2 * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC.
3 * Copyright (c) 2009, 2010, 2011, 2014 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: AFSFileInfo.cpp
39 #include "AFSCommon.h"
42 // Function: AFSQueryFileInfo
46 // This function is the dispatch handler for the IRP_MJ_QUERY_FILE_INFORMATION request
50 // A status is returned for the function
54 AFSQueryFileInfo( IN PDEVICE_OBJECT LibDeviceObject,
58 UNREFERENCED_PARAMETER(LibDeviceObject);
59 NTSTATUS ntStatus = STATUS_SUCCESS;
60 IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
63 BOOLEAN bReleaseMain = FALSE;
65 FILE_INFORMATION_CLASS stFileInformationClass;
73 // Determine the type of request this request is
76 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
78 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
83 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
84 AFS_TRACE_LEVEL_ERROR,
85 "AFSQueryFileInfo Attempted access (%p) when pFcb == NULL\n",
88 try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST);
91 lLength = (LONG)pIrpSp->Parameters.QueryFile.Length;
92 stFileInformationClass = pIrpSp->Parameters.QueryFile.FileInformationClass;
93 pBuffer = Irp->AssociatedIrp.SystemBuffer;
95 if ( BooleanFlagOn( pFcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY))
98 RtlZeroMemory( &stAuthGroup,
101 AFSRetrieveAuthGroupFnc( (ULONGLONG)PsGetCurrentProcessId(),
102 (ULONGLONG)PsGetCurrentThreadId(),
105 ntStatus = AFSVerifyEntry( &stAuthGroup,
109 if ( NT_SUCCESS( ntStatus))
112 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
113 AFS_TRACE_LEVEL_VERBOSE,
114 "AFSQueryFileInfo FID %08lX-%08lX-%08lX-%08lX Clearing Verify Flag\n",
115 pFcb->ObjectInformation->FileId.Cell,
116 pFcb->ObjectInformation->FileId.Volume,
117 pFcb->ObjectInformation->FileId.Vnode,
118 pFcb->ObjectInformation->FileId.Unique));
120 ClearFlag( pFcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY);
125 ntStatus = STATUS_SUCCESS;
130 // Grab the main shared right off the bat
133 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
134 AFS_TRACE_LEVEL_VERBOSE,
135 "AFSQueryFileInfo Acquiring Fcb lock %p SHARED %08lX\n",
136 &pFcb->NPFcb->Resource,
137 PsGetCurrentThread()));
139 AFSAcquireShared( &pFcb->NPFcb->Resource,
145 // Don't allow requests against IOCtl nodes
148 if( pFcb->Header.NodeTypeCode == AFS_SPECIAL_SHARE_FCB)
151 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
152 AFS_TRACE_LEVEL_VERBOSE,
153 "AFSQueryFileInfo Processing request against SpecialShare Fcb\n"));
155 ntStatus = AFSProcessShareQueryInfo( Irp,
159 try_return( ntStatus);
161 else if( pFcb->Header.NodeTypeCode == AFS_IOCTL_FCB)
163 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
164 AFS_TRACE_LEVEL_VERBOSE,
165 "AFSQueryFileInfo request against PIOCtl Fcb\n"));
167 ntStatus = AFSProcessPIOCtlQueryInfo( Irp,
172 try_return( ntStatus);
175 else if( pFcb->Header.NodeTypeCode == AFS_INVALID_FCB)
177 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
178 AFS_TRACE_LEVEL_VERBOSE,
179 "AFSQueryFileInfo request against Invalid Fcb\n"));
181 try_return( ntStatus = STATUS_ACCESS_DENIED);
185 // Process the request
188 switch( stFileInformationClass)
191 case FileAllInformation:
194 PFILE_ALL_INFORMATION pAllInfo;
197 // For the all information class we'll typecast a local
198 // pointer to the output buffer and then call the
199 // individual routines to fill in the buffer.
202 pAllInfo = (PFILE_ALL_INFORMATION)pBuffer;
204 ntStatus = AFSQueryBasicInfo( Irp,
206 &pAllInfo->BasicInformation,
209 if( !NT_SUCCESS( ntStatus))
212 try_return( ntStatus);
215 ntStatus = AFSQueryStandardInfo( Irp,
217 &pAllInfo->StandardInformation,
220 if( !NT_SUCCESS( ntStatus))
223 try_return( ntStatus);
226 ntStatus = AFSQueryInternalInfo( Irp,
228 &pAllInfo->InternalInformation,
231 if( !NT_SUCCESS( ntStatus))
234 try_return( ntStatus);
237 ntStatus = AFSQueryEaInfo( Irp,
239 &pAllInfo->EaInformation,
242 if( !NT_SUCCESS( ntStatus))
245 try_return( ntStatus);
249 // We skip setting AccessInformation since this is set by the IO Mgr prior
250 // to sending this request to the file system
253 if( lLength < sizeof( FILE_ACCESS_INFORMATION))
255 try_return( ntStatus = STATUS_BUFFER_TOO_SMALL);
258 lLength -= sizeof( FILE_ACCESS_INFORMATION);
260 ntStatus = AFSQueryPositionInfo( Irp,
262 &pAllInfo->PositionInformation,
265 if( !NT_SUCCESS( ntStatus))
268 try_return( ntStatus);
272 // We skip setting ModeInformation and AlignmentInformation since this is set by the IO Mgr prior
273 // to sending this request to the file system
276 if( lLength < sizeof( FILE_MODE_INFORMATION))
278 try_return( ntStatus = STATUS_BUFFER_TOO_SMALL);
281 lLength -= sizeof( FILE_MODE_INFORMATION);
283 if( lLength < sizeof( FILE_ALIGNMENT_INFORMATION))
285 try_return( ntStatus = STATUS_BUFFER_TOO_SMALL);
288 lLength -= sizeof( FILE_ALIGNMENT_INFORMATION);
291 // Populate the name information
294 ntStatus = AFSQueryNameInfo( Irp,
296 &pAllInfo->NameInformation,
299 if( !NT_SUCCESS( ntStatus))
302 try_return( ntStatus);
308 case FileBasicInformation:
311 ntStatus = AFSQueryBasicInfo( Irp,
313 (PFILE_BASIC_INFORMATION)pBuffer,
319 case FileStandardInformation:
322 ntStatus = AFSQueryStandardInfo( Irp,
324 (PFILE_STANDARD_INFORMATION)pBuffer,
330 case FileInternalInformation:
333 ntStatus = AFSQueryInternalInfo( Irp,
335 (PFILE_INTERNAL_INFORMATION)pBuffer,
341 case FileEaInformation:
344 ntStatus = AFSQueryEaInfo( Irp,
346 (PFILE_EA_INFORMATION)pBuffer,
352 case FilePositionInformation:
355 ntStatus = AFSQueryPositionInfo( Irp,
357 (PFILE_POSITION_INFORMATION)pBuffer,
363 case FileNormalizedNameInformation:
364 case FileNameInformation:
367 ntStatus = AFSQueryNameInfo( Irp,
369 (PFILE_NAME_INFORMATION)pBuffer,
375 case FileAlternateNameInformation:
378 ntStatus = AFSQueryShortNameInfo( Irp,
380 (PFILE_NAME_INFORMATION)pBuffer,
386 case FileNetworkOpenInformation:
389 ntStatus = AFSQueryNetworkInfo( Irp,
391 (PFILE_NETWORK_OPEN_INFORMATION)pBuffer,
397 case FileStreamInformation:
400 ntStatus = AFSQueryStreamInfo( Irp,
402 (FILE_STREAM_INFORMATION *)pBuffer,
409 case FileAttributeTagInformation:
412 ntStatus = AFSQueryAttribTagInfo( Irp,
414 (FILE_ATTRIBUTE_TAG_INFORMATION *)pBuffer,
420 case FileRemoteProtocolInformation:
423 ntStatus = AFSQueryRemoteProtocolInfo( Irp,
425 (FILE_REMOTE_PROTOCOL_INFORMATION *)pBuffer,
431 case FileNetworkPhysicalNameInformation:
434 ntStatus = AFSQueryPhysicalNameInfo( Irp,
436 (FILE_NETWORK_PHYSICAL_NAME_INFORMATION *)pBuffer,
444 ntStatus = STATUS_INVALID_PARAMETER;
451 Irp->IoStatus.Information = pIrpSp->Parameters.QueryFile.Length - lLength;
456 AFSReleaseResource( &pFcb->NPFcb->Resource);
459 if( !NT_SUCCESS( ntStatus) &&
460 ntStatus != STATUS_INVALID_PARAMETER &&
461 ntStatus != STATUS_BUFFER_OVERFLOW)
465 pCcb->DirectoryCB != NULL)
468 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
469 AFS_TRACE_LEVEL_ERROR,
470 "AFSQueryFileInfo Failed to process request for %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
471 &pCcb->DirectoryCB->NameInformation.FileName,
472 pFcb->ObjectInformation->FileId.Cell,
473 pFcb->ObjectInformation->FileId.Volume,
474 pFcb->ObjectInformation->FileId.Vnode,
475 pFcb->ObjectInformation->FileId.Unique,
480 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
485 "EXCEPTION - AFSQueryFileInfo\n"));
487 AFSDumpTraceFilesFnc();
489 ntStatus = STATUS_UNSUCCESSFUL;
494 AFSReleaseResource( &pFcb->NPFcb->Resource);
498 AFSCompleteRequest( Irp,
505 // Function: AFSSetFileInfo
509 // This function is the dispatch handler for the IRP_MJ_SET_FILE_INFORMATION request
513 // A status is returned for the function
517 AFSSetFileInfo( IN PDEVICE_OBJECT LibDeviceObject,
521 UNREFERENCED_PARAMETER(LibDeviceObject);
522 NTSTATUS ntStatus = STATUS_SUCCESS;
523 IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
526 FILE_INFORMATION_CLASS FileInformationClass;
527 BOOLEAN bCanQueueRequest = FALSE;
528 PFILE_OBJECT pFileObject = NULL;
529 BOOLEAN bReleaseMain = FALSE;
530 BOOLEAN bUpdateFileInfo = FALSE;
531 AFSFileID stParentFileId;
536 pFileObject = pIrpSp->FileObject;
538 pFcb = (AFSFcb *)pFileObject->FsContext;
539 pCcb = (AFSCcb *)pFileObject->FsContext2;
544 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
545 AFS_TRACE_LEVEL_ERROR,
546 "AFSSetFileInfo Attempted access (%p) when pFcb == NULL\n",
549 try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST);
552 bCanQueueRequest = !(IoIsOperationSynchronous( Irp) | (KeGetCurrentIrql() != PASSIVE_LEVEL));
553 FileInformationClass = pIrpSp->Parameters.SetFile.FileInformationClass;
559 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
560 AFS_TRACE_LEVEL_VERBOSE,
561 "AFSSetFileInfo Acquiring Fcb lock %p EXCL %08lX\n",
562 &pFcb->NPFcb->Resource,
563 PsGetCurrentThread()));
565 AFSAcquireExcl( &pFcb->NPFcb->Resource,
571 // Don't allow requests against IOCtl nodes
574 if( pFcb->Header.NodeTypeCode == AFS_IOCTL_FCB)
577 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
578 AFS_TRACE_LEVEL_ERROR,
579 "AFSSetFileInfo Failing request against PIOCtl Fcb\n"));
581 try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST);
583 else if( pFcb->Header.NodeTypeCode == AFS_SPECIAL_SHARE_FCB)
586 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
587 AFS_TRACE_LEVEL_VERBOSE,
588 "AFSSetFileInfo Processing request against SpecialShare Fcb\n"));
590 ntStatus = AFSProcessShareSetInfo( Irp,
594 try_return( ntStatus);
597 if( FileInformationClass != FilePositionInformation &&
598 BooleanFlagOn( pFcb->ObjectInformation->VolumeCB->VolumeInformation.FileSystemAttributes, FILE_READ_ONLY_VOLUME))
601 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
602 AFS_TRACE_LEVEL_ERROR,
603 "AFSSetFileInfo Request failed due to read only volume\n",
606 try_return( ntStatus = STATUS_MEDIA_WRITE_PROTECTED);
609 if( pFcb->Header.NodeTypeCode == AFS_INVALID_FCB &&
610 FileInformationClass != FileDispositionInformation)
612 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
613 AFS_TRACE_LEVEL_VERBOSE,
614 "AFSSetFileInfo request against Invalid Fcb\n"));
616 try_return( ntStatus = STATUS_ACCESS_DENIED);
620 // Ensure rename operations are synchronous
623 if( FileInformationClass == FileRenameInformation)
626 bCanQueueRequest = FALSE;
630 // Store away the parent fid
633 RtlZeroMemory( &stParentFileId,
636 if( BooleanFlagOn( pFcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
639 stParentFileId = pFcb->ObjectInformation->ParentFileId;
643 // Process the request
646 switch( FileInformationClass)
649 case FileBasicInformation:
652 ntStatus = AFSSetBasicInfo( Irp,
659 case FileDispositionInformation:
662 ntStatus = AFSSetDispositionInfo( Irp,
668 case FileRenameInformation:
671 ntStatus = AFSSetRenameInfo( Irp);
676 case FilePositionInformation:
679 ntStatus = AFSSetPositionInfo( Irp,
685 case FileLinkInformation:
688 ntStatus = AFSSetFileLinkInfo( Irp);
693 case FileAllocationInformation:
696 ntStatus = AFSSetAllocationInfo( Irp,
702 case FileEndOfFileInformation:
705 ntStatus = AFSSetEndOfFileInfo( Irp,
713 ntStatus = STATUS_INVALID_PARAMETER;
723 AFSReleaseResource( &pFcb->NPFcb->Resource);
726 if( NT_SUCCESS( ntStatus) &&
730 ntStatus = AFSUpdateFileInformation( &stParentFileId,
731 pFcb->ObjectInformation,
734 if( !NT_SUCCESS( ntStatus))
737 AFSAcquireExcl( &pFcb->NPFcb->Resource,
741 // Unwind the update and fail the request
744 AFSUnwindFileInfo( pFcb,
747 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
748 AFS_TRACE_LEVEL_ERROR,
749 "AFSSetFileInfo Failed to send file info update to service request for %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
750 &pCcb->DirectoryCB->NameInformation.FileName,
751 pFcb->ObjectInformation->FileId.Cell,
752 pFcb->ObjectInformation->FileId.Volume,
753 pFcb->ObjectInformation->FileId.Vnode,
754 pFcb->ObjectInformation->FileId.Unique,
757 AFSReleaseResource( &pFcb->NPFcb->Resource);
761 if( !NT_SUCCESS( ntStatus))
765 pCcb->DirectoryCB != NULL)
768 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
769 AFS_TRACE_LEVEL_ERROR,
770 "AFSSetFileInfo Failed to process request for %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
771 &pCcb->DirectoryCB->NameInformation.FileName,
772 pFcb->ObjectInformation->FileId.Cell,
773 pFcb->ObjectInformation->FileId.Volume,
774 pFcb->ObjectInformation->FileId.Vnode,
775 pFcb->ObjectInformation->FileId.Unique,
780 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
785 "EXCEPTION - AFSSetFileInfo\n"));
787 AFSDumpTraceFilesFnc();
789 ntStatus = STATUS_UNSUCCESSFUL;
794 AFSReleaseResource( &pFcb->NPFcb->Resource);
798 AFSCompleteRequest( Irp,
805 // Function: AFSQueryBasicInfo
809 // This function is the handler for the query basic information request
813 // A status is returned for the function
817 AFSQueryBasicInfo( IN PIRP Irp,
818 IN AFSDirectoryCB *DirectoryCB,
819 IN OUT PFILE_BASIC_INFORMATION Buffer,
822 NTSTATUS ntStatus = STATUS_SUCCESS;
823 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
824 ULONG ulFileAttribs = 0;
827 IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
828 AFSFileInfoCB stFileInfo;
829 AFSDirectoryCB *pParentDirectoryCB = NULL;
830 UNICODE_STRING uniParentPath;
832 if( *Length >= sizeof( FILE_BASIC_INFORMATION))
835 RtlZeroMemory( Buffer,
838 ulFileAttribs = DirectoryCB->ObjectInformation->FileAttributes;
840 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
841 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
843 if( DirectoryCB->ObjectInformation->FileType == AFS_FILE_TYPE_SYMLINK)
846 pParentDirectoryCB = AFSGetParentEntry( pCcb->NameArray);
848 AFSRetrieveParentPath( &pCcb->FullFileName,
851 RtlZeroMemory( &stFileInfo,
852 sizeof( AFSFileInfoCB));
855 // Can't hold the Fcb while evaluating the path, leads to lock inversion
858 AFSReleaseResource( &pFcb->NPFcb->Resource);
861 // Its a reparse point regardless of whether the file attributes
862 // can be retrieved for the target.
865 if ( ulFileAttribs == FILE_ATTRIBUTE_NORMAL)
868 ulFileAttribs = FILE_ATTRIBUTE_REPARSE_POINT;
873 ulFileAttribs |= FILE_ATTRIBUTE_REPARSE_POINT;
876 if( NT_SUCCESS( AFSRetrieveFileAttributes( pParentDirectoryCB,
884 if ( stFileInfo.FileAttributes & FILE_ATTRIBUTE_DIRECTORY)
887 ulFileAttribs |= FILE_ATTRIBUTE_DIRECTORY;
891 AFSAcquireShared( &pFcb->NPFcb->Resource,
896 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
897 AFS_TRACE_LEVEL_VERBOSE_2,
898 "AFSQueryBasicInfo %wZ Type 0x%x Attrib 0x%x -> 0x%x\n",
899 &pCcb->DirectoryCB->NameInformation.FileName,
900 pFcb->ObjectInformation->FileType,
901 pFcb->ObjectInformation->FileAttributes,
904 Buffer->CreationTime = DirectoryCB->ObjectInformation->CreationTime;
905 Buffer->LastAccessTime = DirectoryCB->ObjectInformation->LastAccessTime;
906 Buffer->LastWriteTime = DirectoryCB->ObjectInformation->LastWriteTime;
907 Buffer->ChangeTime = DirectoryCB->ObjectInformation->ChangeTime;
908 Buffer->FileAttributes = ulFileAttribs;
910 if( DirectoryCB->NameInformation.FileName.Buffer[ 0] == L'.' &&
911 BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_HIDE_DOT_NAMES))
914 if ( Buffer->FileAttributes != FILE_ATTRIBUTE_NORMAL)
916 Buffer->FileAttributes |= FILE_ATTRIBUTE_HIDDEN;
920 Buffer->FileAttributes = FILE_ATTRIBUTE_HIDDEN;
924 *Length -= sizeof( FILE_BASIC_INFORMATION);
929 ntStatus = STATUS_BUFFER_TOO_SMALL;
936 AFSQueryStandardInfo( IN PIRP Irp,
937 IN AFSDirectoryCB *DirectoryCB,
938 IN OUT PFILE_STANDARD_INFORMATION Buffer,
942 NTSTATUS ntStatus = STATUS_SUCCESS;
945 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
946 AFSFileInfoCB stFileInfo;
947 AFSDirectoryCB *pParentDirectoryCB = NULL;
948 UNICODE_STRING uniParentPath;
949 ULONG ulFileAttribs = 0;
951 if( *Length >= sizeof( FILE_STANDARD_INFORMATION))
954 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
955 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
957 RtlZeroMemory( Buffer,
960 Buffer->NumberOfLinks = 1;
961 Buffer->DeletePending = BooleanFlagOn( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
963 Buffer->AllocationSize.QuadPart = (ULONGLONG)((DirectoryCB->ObjectInformation->AllocationSize.QuadPart/PAGE_SIZE) + 1) * PAGE_SIZE;
965 Buffer->EndOfFile = DirectoryCB->ObjectInformation->EndOfFile;
967 ulFileAttribs = DirectoryCB->ObjectInformation->FileAttributes;
969 if( DirectoryCB->ObjectInformation->FileType == AFS_FILE_TYPE_SYMLINK)
972 pParentDirectoryCB = AFSGetParentEntry( pCcb->NameArray);
974 AFSRetrieveParentPath( &pCcb->FullFileName,
977 RtlZeroMemory( &stFileInfo,
978 sizeof( AFSFileInfoCB));
981 // Can't hold the Fcb while evaluating the path, leads to lock inversion
984 AFSReleaseResource( &pFcb->NPFcb->Resource);
987 // Its a reparse point regardless of whether or not the
988 // file attributes can be retrieved.
991 if ( ulFileAttribs == FILE_ATTRIBUTE_NORMAL)
994 ulFileAttribs = FILE_ATTRIBUTE_REPARSE_POINT;
999 ulFileAttribs |= FILE_ATTRIBUTE_REPARSE_POINT;
1002 if( NT_SUCCESS( AFSRetrieveFileAttributes( pParentDirectoryCB,
1010 if ( stFileInfo.FileAttributes & FILE_ATTRIBUTE_DIRECTORY)
1013 ulFileAttribs |= FILE_ATTRIBUTE_DIRECTORY;
1017 AFSAcquireShared( &pFcb->NPFcb->Resource,
1021 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1022 AFS_TRACE_LEVEL_VERBOSE_2,
1023 "AFSQueryStandardInfo %wZ Type 0x%x Attrib 0x%x -> 0x%x\n",
1024 &pCcb->DirectoryCB->NameInformation.FileName,
1025 pFcb->ObjectInformation->FileType,
1026 pFcb->ObjectInformation->FileAttributes,
1029 Buffer->Directory = BooleanFlagOn( ulFileAttribs, FILE_ATTRIBUTE_DIRECTORY);
1031 *Length -= sizeof( FILE_STANDARD_INFORMATION);
1036 ntStatus = STATUS_BUFFER_TOO_SMALL;
1043 AFSQueryInternalInfo( IN PIRP Irp,
1045 IN OUT PFILE_INTERNAL_INFORMATION Buffer,
1046 IN OUT PLONG Length)
1049 UNREFERENCED_PARAMETER(Irp);
1050 NTSTATUS ntStatus = STATUS_SUCCESS;
1052 if( *Length >= sizeof( FILE_INTERNAL_INFORMATION))
1055 Buffer->IndexNumber.HighPart = Fcb->ObjectInformation->FileId.Vnode;
1057 Buffer->IndexNumber.LowPart = Fcb->ObjectInformation->FileId.Unique;
1059 *Length -= sizeof( FILE_INTERNAL_INFORMATION);
1064 ntStatus = STATUS_BUFFER_TOO_SMALL;
1071 AFSQueryEaInfo( IN PIRP Irp,
1072 IN AFSDirectoryCB *DirectoryCB,
1073 IN OUT PFILE_EA_INFORMATION Buffer,
1074 IN OUT PLONG Length)
1077 UNREFERENCED_PARAMETER(Irp);
1078 UNREFERENCED_PARAMETER(DirectoryCB);
1079 NTSTATUS ntStatus = STATUS_SUCCESS;
1081 RtlZeroMemory( Buffer,
1084 if( *Length >= sizeof( FILE_EA_INFORMATION))
1089 *Length -= sizeof( FILE_EA_INFORMATION);
1094 ntStatus = STATUS_BUFFER_TOO_SMALL;
1101 AFSQueryPositionInfo( IN PIRP Irp,
1103 IN OUT PFILE_POSITION_INFORMATION Buffer,
1104 IN OUT PLONG Length)
1107 UNREFERENCED_PARAMETER(Fcb);
1108 NTSTATUS ntStatus = STATUS_SUCCESS;
1109 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1111 if( *Length >= sizeof( FILE_POSITION_INFORMATION))
1114 RtlZeroMemory( Buffer,
1117 Buffer->CurrentByteOffset.QuadPart = pIrpSp->FileObject->CurrentByteOffset.QuadPart;
1119 *Length -= sizeof( FILE_POSITION_INFORMATION);
1124 ntStatus = STATUS_BUFFER_TOO_SMALL;
1131 AFSQueryNameInfo( IN PIRP Irp,
1132 IN AFSDirectoryCB *DirectoryCB,
1133 IN OUT PFILE_NAME_INFORMATION Buffer,
1134 IN OUT PLONG Length)
1137 UNREFERENCED_PARAMETER(DirectoryCB);
1138 NTSTATUS ntStatus = STATUS_SUCCESS;
1139 ULONG ulCopyLength = 0;
1140 ULONG cchCopied = 0;
1141 AFSFcb *pFcb = NULL;
1142 AFSCcb *pCcb = NULL;
1143 IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1144 BOOLEAN bAddLeadingSlash = FALSE;
1145 BOOLEAN bAddTrailingSlash = FALSE;
1146 USHORT usFullNameLength = 0;
1148 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
1150 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
1152 if( *Length >= FIELD_OFFSET( FILE_NAME_INFORMATION, FileName))
1155 RtlZeroMemory( Buffer,
1158 if( pCcb->FullFileName.Length == 0 ||
1159 pCcb->FullFileName.Buffer[ 0] != L'\\')
1161 bAddLeadingSlash = TRUE;
1164 if( pFcb->ObjectInformation->FileType == AFS_FILE_TYPE_DIRECTORY &&
1165 pCcb->FullFileName.Length > 0 &&
1166 pCcb->FullFileName.Buffer[ (pCcb->FullFileName.Length/sizeof( WCHAR)) - 1] != L'\\')
1168 bAddTrailingSlash = TRUE;
1171 usFullNameLength = sizeof( WCHAR) +
1172 AFSServerName.Length +
1173 pCcb->FullFileName.Length;
1175 if( bAddLeadingSlash)
1177 usFullNameLength += sizeof( WCHAR);
1180 if( bAddTrailingSlash)
1182 usFullNameLength += sizeof( WCHAR);
1185 if( *Length >= (LONG)(FIELD_OFFSET( FILE_NAME_INFORMATION, FileName) + (LONG)usFullNameLength))
1188 ulCopyLength = (LONG)usFullNameLength;
1193 ulCopyLength = *Length - FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
1195 ntStatus = STATUS_BUFFER_OVERFLOW;
1198 Buffer->FileNameLength = (ULONG)usFullNameLength;
1200 *Length -= FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
1202 if( ulCopyLength > 0)
1205 Buffer->FileName[ 0] = L'\\';
1206 ulCopyLength -= sizeof( WCHAR);
1208 *Length -= sizeof( WCHAR);
1211 if( ulCopyLength >= AFSServerName.Length)
1214 RtlCopyMemory( &Buffer->FileName[ 1],
1215 AFSServerName.Buffer,
1216 AFSServerName.Length);
1218 ulCopyLength -= AFSServerName.Length;
1219 *Length -= AFSServerName.Length;
1220 cchCopied += AFSServerName.Length/sizeof( WCHAR);
1222 if ( ulCopyLength > 0 &&
1226 Buffer->FileName[ cchCopied] = L'\\';
1228 ulCopyLength -= sizeof( WCHAR);
1229 *Length -= sizeof( WCHAR);
1233 if( ulCopyLength >= pCcb->FullFileName.Length)
1236 RtlCopyMemory( &Buffer->FileName[ cchCopied],
1237 pCcb->FullFileName.Buffer,
1238 pCcb->FullFileName.Length);
1240 ulCopyLength -= pCcb->FullFileName.Length;
1241 *Length -= pCcb->FullFileName.Length;
1242 cchCopied += pCcb->FullFileName.Length/sizeof( WCHAR);
1244 if( ulCopyLength > 0 &&
1247 Buffer->FileName[ cchCopied] = L'\\';
1249 *Length -= sizeof( WCHAR);
1255 RtlCopyMemory( &Buffer->FileName[ cchCopied],
1256 pCcb->FullFileName.Buffer,
1259 *Length -= ulCopyLength;
1267 ntStatus = STATUS_BUFFER_TOO_SMALL;
1274 AFSQueryShortNameInfo( IN PIRP Irp,
1275 IN AFSDirectoryCB *DirectoryCB,
1276 IN OUT PFILE_NAME_INFORMATION Buffer,
1277 IN OUT PLONG Length)
1280 UNREFERENCED_PARAMETER(Irp);
1281 NTSTATUS ntStatus = STATUS_BUFFER_TOO_SMALL;
1282 ULONG ulCopyLength = 0;
1284 RtlZeroMemory( Buffer,
1287 if( DirectoryCB->NameInformation.ShortNameLength == 0)
1291 // The short name IS the long name
1294 if( *Length >= (LONG)FIELD_OFFSET( FILE_NAME_INFORMATION, FileName))
1297 if( *Length >= (LONG)(FIELD_OFFSET( FILE_NAME_INFORMATION, FileName) + (LONG)DirectoryCB->NameInformation.FileName.Length))
1300 ulCopyLength = (LONG)DirectoryCB->NameInformation.FileName.Length;
1302 ntStatus = STATUS_SUCCESS;
1307 ulCopyLength = *Length - FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
1309 ntStatus = STATUS_BUFFER_OVERFLOW;
1312 Buffer->FileNameLength = DirectoryCB->NameInformation.FileName.Length;
1314 *Length -= FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
1316 if( ulCopyLength > 0)
1319 RtlCopyMemory( Buffer->FileName,
1320 DirectoryCB->NameInformation.FileName.Buffer,
1323 *Length -= ulCopyLength;
1330 if( *Length >= (LONG)FIELD_OFFSET( FILE_NAME_INFORMATION, FileName))
1333 if( *Length >= (LONG)(FIELD_OFFSET( FILE_NAME_INFORMATION, FileName) + (LONG)DirectoryCB->NameInformation.FileName.Length))
1336 ulCopyLength = (LONG)DirectoryCB->NameInformation.ShortNameLength;
1338 ntStatus = STATUS_SUCCESS;
1343 ulCopyLength = *Length - FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
1345 ntStatus = STATUS_BUFFER_OVERFLOW;
1348 Buffer->FileNameLength = DirectoryCB->NameInformation.ShortNameLength;
1350 *Length -= FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
1352 if( ulCopyLength > 0)
1355 RtlCopyMemory( Buffer->FileName,
1356 DirectoryCB->NameInformation.ShortName,
1357 Buffer->FileNameLength);
1359 *Length -= ulCopyLength;
1368 AFSQueryNetworkInfo( IN PIRP Irp,
1369 IN AFSDirectoryCB *DirectoryCB,
1370 IN OUT PFILE_NETWORK_OPEN_INFORMATION Buffer,
1371 IN OUT PLONG Length)
1374 NTSTATUS ntStatus = STATUS_SUCCESS;
1375 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1376 AFSFcb *pFcb = NULL;
1377 AFSCcb *pCcb = NULL;
1378 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1379 AFSFileInfoCB stFileInfo;
1380 AFSDirectoryCB *pParentDirectoryCB = NULL;
1381 UNICODE_STRING uniParentPath;
1382 ULONG ulFileAttribs = 0;
1384 RtlZeroMemory( Buffer,
1387 if( *Length >= sizeof( FILE_NETWORK_OPEN_INFORMATION))
1390 ulFileAttribs = DirectoryCB->ObjectInformation->FileAttributes;
1392 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
1393 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
1395 if( DirectoryCB->ObjectInformation->FileType == AFS_FILE_TYPE_SYMLINK)
1398 pParentDirectoryCB = AFSGetParentEntry( pCcb->NameArray);
1400 AFSRetrieveParentPath( &pCcb->FullFileName,
1403 RtlZeroMemory( &stFileInfo,
1404 sizeof( AFSFileInfoCB));
1407 // Can't hold the Fcb while evaluating the path, leads to lock inversion
1410 AFSReleaseResource( &pFcb->NPFcb->Resource);
1413 // Its a reparse point regardless of whether the file attributes
1414 // can be retrieved for the target.
1417 if ( ulFileAttribs == FILE_ATTRIBUTE_NORMAL)
1420 ulFileAttribs = FILE_ATTRIBUTE_REPARSE_POINT;
1425 ulFileAttribs |= FILE_ATTRIBUTE_REPARSE_POINT;
1428 if( NT_SUCCESS( AFSRetrieveFileAttributes( pParentDirectoryCB,
1436 if ( stFileInfo.FileAttributes & FILE_ATTRIBUTE_DIRECTORY)
1439 ulFileAttribs |= FILE_ATTRIBUTE_DIRECTORY;
1443 AFSAcquireShared( &pFcb->NPFcb->Resource,
1447 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1448 AFS_TRACE_LEVEL_VERBOSE_2,
1449 "AFSQueryNetworkInfo %wZ Type 0x%x Attrib 0x%x -> 0x%x\n",
1450 &pCcb->DirectoryCB->NameInformation.FileName,
1451 pFcb->ObjectInformation->FileType,
1452 pFcb->ObjectInformation->FileAttributes,
1455 Buffer->CreationTime.QuadPart = DirectoryCB->ObjectInformation->CreationTime.QuadPart;
1456 Buffer->LastAccessTime.QuadPart = DirectoryCB->ObjectInformation->LastAccessTime.QuadPart;
1457 Buffer->LastWriteTime.QuadPart = DirectoryCB->ObjectInformation->LastWriteTime.QuadPart;
1458 Buffer->ChangeTime.QuadPart = DirectoryCB->ObjectInformation->ChangeTime.QuadPart;
1460 Buffer->AllocationSize.QuadPart = DirectoryCB->ObjectInformation->AllocationSize.QuadPart;
1461 Buffer->EndOfFile.QuadPart = DirectoryCB->ObjectInformation->EndOfFile.QuadPart;
1463 Buffer->FileAttributes = ulFileAttribs;
1465 if( DirectoryCB->NameInformation.FileName.Buffer[ 0] == L'.' &&
1466 BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_HIDE_DOT_NAMES))
1469 if ( Buffer->FileAttributes != FILE_ATTRIBUTE_NORMAL)
1472 Buffer->FileAttributes |= FILE_ATTRIBUTE_HIDDEN;
1477 Buffer->FileAttributes = FILE_ATTRIBUTE_HIDDEN;
1481 *Length -= sizeof( FILE_NETWORK_OPEN_INFORMATION);
1486 ntStatus = STATUS_BUFFER_TOO_SMALL;
1493 AFSQueryStreamInfo( IN PIRP Irp,
1494 IN AFSDirectoryCB *DirectoryCB,
1495 IN OUT FILE_STREAM_INFORMATION *Buffer,
1496 IN OUT PLONG Length)
1499 UNREFERENCED_PARAMETER(Irp);
1500 NTSTATUS ntStatus = STATUS_BUFFER_TOO_SMALL;
1501 ULONG ulCopyLength = 0;
1503 if( *Length >= FIELD_OFFSET( FILE_STREAM_INFORMATION, StreamName))
1506 RtlZeroMemory( Buffer,
1509 Buffer->NextEntryOffset = 0;
1512 if( !BooleanFlagOn( DirectoryCB->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_DIRECTORY))
1515 if( *Length >= (LONG)(FIELD_OFFSET( FILE_STREAM_INFORMATION, StreamName) + 14)) // ::$DATA
1520 ntStatus = STATUS_SUCCESS;
1525 ulCopyLength = *Length - FIELD_OFFSET( FILE_STREAM_INFORMATION, StreamName);
1527 ntStatus = STATUS_BUFFER_OVERFLOW;
1530 Buffer->StreamNameLength = 14; // ::$DATA
1532 Buffer->StreamSize.QuadPart = DirectoryCB->ObjectInformation->EndOfFile.QuadPart;
1534 Buffer->StreamAllocationSize.QuadPart = DirectoryCB->ObjectInformation->AllocationSize.QuadPart;
1536 *Length -= FIELD_OFFSET( FILE_STREAM_INFORMATION, StreamName);
1538 if( ulCopyLength > 0)
1541 RtlCopyMemory( Buffer->StreamName,
1545 *Length -= ulCopyLength;
1551 Buffer->StreamNameLength = 0; // No stream for a directory
1553 // The response size is zero
1555 ntStatus = STATUS_SUCCESS;
1563 AFSQueryAttribTagInfo( IN PIRP Irp,
1564 IN AFSDirectoryCB *DirectoryCB,
1565 IN OUT FILE_ATTRIBUTE_TAG_INFORMATION *Buffer,
1566 IN OUT PLONG Length)
1569 NTSTATUS ntStatus = STATUS_BUFFER_TOO_SMALL;
1570 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1571 AFSFcb *pFcb = NULL;
1572 AFSCcb *pCcb = NULL;
1573 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1574 AFSFileInfoCB stFileInfo;
1575 AFSDirectoryCB *pParentDirectoryCB = NULL;
1576 UNICODE_STRING uniParentPath;
1577 ULONG ulFileAttribs = 0;
1579 if( *Length >= sizeof( FILE_ATTRIBUTE_TAG_INFORMATION))
1582 RtlZeroMemory( Buffer,
1585 ulFileAttribs = DirectoryCB->ObjectInformation->FileAttributes;
1587 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
1588 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
1590 if( DirectoryCB->ObjectInformation->FileType == AFS_FILE_TYPE_SYMLINK)
1593 pParentDirectoryCB = AFSGetParentEntry( pCcb->NameArray);
1595 AFSRetrieveParentPath( &pCcb->FullFileName,
1598 RtlZeroMemory( &stFileInfo,
1599 sizeof( AFSFileInfoCB));
1602 // Can't hold the Fcb while evaluating the path, leads to lock inversion
1605 AFSReleaseResource( &pFcb->NPFcb->Resource);
1608 // Its a reparse point regardless of whether the file attributes
1609 // can be retrieved for the target.
1612 if ( ulFileAttribs == FILE_ATTRIBUTE_NORMAL)
1615 ulFileAttribs = FILE_ATTRIBUTE_REPARSE_POINT;
1620 ulFileAttribs |= FILE_ATTRIBUTE_REPARSE_POINT;
1623 if( NT_SUCCESS( AFSRetrieveFileAttributes( pParentDirectoryCB,
1631 if ( stFileInfo.FileAttributes & FILE_ATTRIBUTE_DIRECTORY)
1634 ulFileAttribs |= FILE_ATTRIBUTE_DIRECTORY;
1638 AFSAcquireShared( &pFcb->NPFcb->Resource,
1642 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1643 AFS_TRACE_LEVEL_VERBOSE_2,
1644 "AFSAttribTagInfo %wZ Type 0x%x Attrib 0x%x -> 0x%x\n",
1645 &pCcb->DirectoryCB->NameInformation.FileName,
1646 pFcb->ObjectInformation->FileType,
1647 pFcb->ObjectInformation->FileAttributes,
1650 Buffer->FileAttributes = ulFileAttribs;
1652 if( DirectoryCB->NameInformation.FileName.Buffer[ 0] == L'.' &&
1653 BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_HIDE_DOT_NAMES))
1656 if ( Buffer->FileAttributes != FILE_ATTRIBUTE_NORMAL)
1659 Buffer->FileAttributes |= FILE_ATTRIBUTE_HIDDEN;
1664 Buffer->FileAttributes = FILE_ATTRIBUTE_HIDDEN;
1668 if ( DirectoryCB->ObjectInformation->FileType == AFS_FILE_TYPE_MOUNTPOINT)
1671 Buffer->ReparseTag = IO_REPARSE_TAG_SURROGATE|IO_REPARSE_TAG_OPENAFS_DFS;
1673 else if( BooleanFlagOn( DirectoryCB->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_REPARSE_POINT))
1676 Buffer->ReparseTag = IO_REPARSE_TAG_SYMLINK;
1679 *Length -= sizeof( FILE_ATTRIBUTE_TAG_INFORMATION);
1681 ntStatus = STATUS_SUCCESS;
1688 AFSQueryRemoteProtocolInfo( IN PIRP Irp,
1689 IN AFSDirectoryCB *DirectoryCB,
1690 IN OUT FILE_REMOTE_PROTOCOL_INFORMATION *Buffer,
1691 IN OUT PLONG Length)
1694 UNREFERENCED_PARAMETER(Irp);
1695 UNREFERENCED_PARAMETER(DirectoryCB);
1696 NTSTATUS ntStatus = STATUS_BUFFER_TOO_SMALL;
1698 if( *Length >= sizeof( FILE_REMOTE_PROTOCOL_INFORMATION))
1701 RtlZeroMemory( Buffer,
1704 Buffer->StructureVersion = 1;
1706 Buffer->StructureSize = sizeof(FILE_REMOTE_PROTOCOL_INFORMATION);
1708 Buffer->Protocol = WNNC_NET_OPENAFS;
1710 Buffer->ProtocolMajorVersion = 3;
1712 Buffer->ProtocolMinorVersion = 0;
1714 Buffer->ProtocolRevision = 0;
1716 *Length -= sizeof( FILE_REMOTE_PROTOCOL_INFORMATION);
1718 ntStatus = STATUS_SUCCESS;
1725 AFSQueryPhysicalNameInfo( IN PIRP Irp,
1726 IN AFSDirectoryCB *DirectoryCB,
1727 IN OUT PFILE_NETWORK_PHYSICAL_NAME_INFORMATION Buffer,
1728 IN OUT PLONG Length)
1731 UNREFERENCED_PARAMETER(DirectoryCB);
1732 NTSTATUS ntStatus = STATUS_SUCCESS;
1733 ULONG ulCopyLength = 0;
1734 ULONG cchCopied = 0;
1735 AFSFcb *pFcb = NULL;
1736 AFSCcb *pCcb = NULL;
1737 IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1738 BOOLEAN bAddLeadingSlash = FALSE;
1739 USHORT usFullNameLength = 0;
1741 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
1743 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
1745 if( *Length >= FIELD_OFFSET( FILE_NETWORK_PHYSICAL_NAME_INFORMATION, FileName))
1748 RtlZeroMemory( Buffer,
1751 if( pCcb->FullFileName.Length == 0 ||
1752 pCcb->FullFileName.Buffer[ 0] != L'\\')
1754 bAddLeadingSlash = TRUE;
1757 usFullNameLength = pCcb->FullFileName.Length;
1759 if( bAddLeadingSlash)
1761 usFullNameLength += sizeof( WCHAR);
1764 if( *Length >= (LONG)(FIELD_OFFSET( FILE_NETWORK_PHYSICAL_NAME_INFORMATION, FileName) + (LONG)usFullNameLength))
1766 ulCopyLength = (LONG)usFullNameLength;
1771 ulCopyLength = *Length - FIELD_OFFSET( FILE_NETWORK_PHYSICAL_NAME_INFORMATION, FileName);
1773 ntStatus = STATUS_BUFFER_OVERFLOW;
1776 Buffer->FileNameLength = (ULONG)usFullNameLength;
1778 *Length -= FIELD_OFFSET( FILE_NETWORK_PHYSICAL_NAME_INFORMATION, FileName);
1780 if( ulCopyLength > 0)
1783 if( bAddLeadingSlash)
1786 Buffer->FileName[ cchCopied] = L'\\';
1788 ulCopyLength -= sizeof( WCHAR);
1789 *Length -= sizeof( WCHAR);
1793 if( ulCopyLength >= pCcb->FullFileName.Length)
1796 RtlCopyMemory( &Buffer->FileName[ cchCopied],
1797 pCcb->FullFileName.Buffer,
1798 pCcb->FullFileName.Length);
1800 ulCopyLength -= pCcb->FullFileName.Length;
1801 *Length -= pCcb->FullFileName.Length;
1802 cchCopied += pCcb->FullFileName.Length/sizeof( WCHAR);
1807 RtlCopyMemory( &Buffer->FileName[ cchCopied],
1808 pCcb->FullFileName.Buffer,
1811 *Length -= ulCopyLength;
1818 ntStatus = STATUS_BUFFER_TOO_SMALL;
1825 AFSSetBasicInfo( IN PIRP Irp,
1826 IN AFSDirectoryCB *DirectoryCB,
1827 OUT BOOLEAN *bUpdateFileInfo)
1829 NTSTATUS ntStatus = STATUS_SUCCESS;
1830 PFILE_BASIC_INFORMATION pBuffer;
1831 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1832 ULONG ulNotifyFilter = 0;
1833 AFSCcb *pCcb = NULL;
1838 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
1840 pBuffer = (PFILE_BASIC_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
1842 pCcb->FileUnwindInfo.FileAttributes = (ULONG)-1;
1844 if( pBuffer->FileAttributes != (ULONGLONG)0)
1848 // Make sure that the reparse point attribute is not modified.
1849 // Fail if the RP attribute is requested but it is not
1850 // already a RP. Otherwise, ignore it.
1853 if ( !BooleanFlagOn( DirectoryCB->ObjectInformation->FileAttributes,
1854 FILE_ATTRIBUTE_REPARSE_POINT) &&
1855 BooleanFlagOn( pBuffer->FileAttributes,
1856 FILE_ATTRIBUTE_REPARSE_POINT))
1859 try_return( ntStatus = STATUS_INVALID_PARAMETER);
1863 // Make sure that the directory attribute is not modified.
1864 // Fail if the D attribute is requested but it is not
1865 // already a directory. Otherwise, ignore it.
1868 if ( !BooleanFlagOn( DirectoryCB->ObjectInformation->FileAttributes,
1869 FILE_ATTRIBUTE_DIRECTORY) &&
1870 BooleanFlagOn( pBuffer->FileAttributes,
1871 FILE_ATTRIBUTE_DIRECTORY))
1874 try_return( ntStatus = STATUS_INVALID_PARAMETER);
1878 // Save the original value
1881 pCcb->FileUnwindInfo.FileAttributes = DirectoryCB->ObjectInformation->FileAttributes;
1883 if( BooleanFlagOn( pBuffer->FileAttributes, FILE_ATTRIBUTE_READONLY))
1887 // Set the readonly flag.
1890 if ( !BooleanFlagOn( DirectoryCB->ObjectInformation->FileAttributes,
1891 FILE_ATTRIBUTE_READONLY))
1894 if ( DirectoryCB->ObjectInformation->FileAttributes == FILE_ATTRIBUTE_NORMAL)
1897 DirectoryCB->ObjectInformation->FileAttributes = FILE_ATTRIBUTE_READONLY;
1902 DirectoryCB->ObjectInformation->FileAttributes |= FILE_ATTRIBUTE_READONLY;
1905 ulNotifyFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
1907 SetFlag( DirectoryCB->ObjectInformation->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED);
1913 // Reset the readonly flag.
1916 if ( BooleanFlagOn( DirectoryCB->ObjectInformation->FileAttributes,
1917 FILE_ATTRIBUTE_READONLY))
1920 DirectoryCB->ObjectInformation->FileAttributes &= ~FILE_ATTRIBUTE_READONLY;
1922 if ( DirectoryCB->ObjectInformation->FileAttributes == 0)
1925 DirectoryCB->ObjectInformation->FileAttributes = FILE_ATTRIBUTE_NORMAL;
1928 ulNotifyFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
1930 SetFlag( DirectoryCB->ObjectInformation->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED);
1935 pCcb->FileUnwindInfo.CreationTime.QuadPart = (ULONGLONG)-1;
1937 if( pBuffer->CreationTime.QuadPart != (ULONGLONG)-1 &&
1938 pBuffer->CreationTime.QuadPart != (ULONGLONG)0)
1941 pCcb->FileUnwindInfo.CreationTime.QuadPart = DirectoryCB->ObjectInformation->CreationTime.QuadPart;
1943 DirectoryCB->ObjectInformation->CreationTime.QuadPart = pBuffer->CreationTime.QuadPart;
1945 ulNotifyFilter |= FILE_NOTIFY_CHANGE_CREATION;
1947 SetFlag( DirectoryCB->ObjectInformation->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_CREATE_TIME);
1950 pCcb->FileUnwindInfo.LastAccessTime.QuadPart = (ULONGLONG)-1;
1952 if( pBuffer->LastAccessTime.QuadPart != (ULONGLONG)-1 &&
1953 pBuffer->LastAccessTime.QuadPart != (ULONGLONG)0)
1956 pCcb->FileUnwindInfo.LastAccessTime.QuadPart = DirectoryCB->ObjectInformation->LastAccessTime.QuadPart;
1958 DirectoryCB->ObjectInformation->LastAccessTime.QuadPart = pBuffer->LastAccessTime.QuadPart;
1960 ulNotifyFilter |= FILE_NOTIFY_CHANGE_LAST_ACCESS;
1962 SetFlag( DirectoryCB->ObjectInformation->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_ACCESS_TIME);
1965 pCcb->FileUnwindInfo.LastWriteTime.QuadPart = (ULONGLONG)-1;
1967 if( pBuffer->LastWriteTime.QuadPart != (ULONGLONG)-1 &&
1968 pBuffer->LastWriteTime.QuadPart != (ULONGLONG)0)
1971 pCcb->FileUnwindInfo.LastWriteTime.QuadPart = DirectoryCB->ObjectInformation->LastWriteTime.QuadPart;
1973 DirectoryCB->ObjectInformation->LastWriteTime.QuadPart = pBuffer->LastWriteTime.QuadPart;
1975 ulNotifyFilter |= FILE_NOTIFY_CHANGE_LAST_WRITE;
1977 SetFlag( DirectoryCB->ObjectInformation->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_LAST_WRITE_TIME);
1979 SetFlag( pCcb->Flags, CCB_FLAG_LAST_WRITE_TIME_SET);
1981 } else if ( pBuffer->LastWriteTime.QuadPart == (ULONGLONG)-1) {
1983 SetFlag( pCcb->Flags, CCB_FLAG_LAST_WRITE_TIME_SET);
1986 pCcb->FileUnwindInfo.ChangeTime.QuadPart = (ULONGLONG)-1;
1988 if( pBuffer->ChangeTime.QuadPart != (ULONGLONG)-1 &&
1989 pBuffer->ChangeTime.QuadPart != (ULONGLONG)0)
1992 pCcb->FileUnwindInfo.ChangeTime.QuadPart = DirectoryCB->ObjectInformation->ChangeTime.QuadPart;
1994 DirectoryCB->ObjectInformation->ChangeTime.QuadPart = pBuffer->ChangeTime.QuadPart;
1996 ulNotifyFilter |= FILE_NOTIFY_CHANGE_LAST_ACCESS;
1998 SetFlag( DirectoryCB->ObjectInformation->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_CHANGE_TIME);
2001 if( ulNotifyFilter > 0)
2004 *bUpdateFileInfo = TRUE;
2006 if( BooleanFlagOn( DirectoryCB->ObjectInformation->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
2009 AFSObjectInfoCB * pParentObjectInfo = AFSFindObjectInfo( DirectoryCB->ObjectInformation->VolumeCB,
2010 &DirectoryCB->ObjectInformation->ParentFileId,
2013 if ( pParentObjectInfo != NULL)
2015 AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
2017 (ULONG)ulNotifyFilter,
2018 (ULONG)FILE_ACTION_MODIFIED);
2020 AFSReleaseObjectInfo( &pParentObjectInfo);
2034 AFSSetDispositionInfo( IN PIRP Irp,
2035 IN AFSDirectoryCB *DirectoryCB)
2037 NTSTATUS ntStatus = STATUS_SUCCESS;
2038 PFILE_DISPOSITION_INFORMATION pBuffer;
2039 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2040 AFSFcb *pFcb = NULL;
2041 AFSCcb *pCcb = NULL;
2046 pBuffer = (PFILE_DISPOSITION_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
2048 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
2050 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
2053 // Can't delete the root
2056 if( pFcb->Header.NodeTypeCode == AFS_ROOT_FCB)
2059 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2060 AFS_TRACE_LEVEL_ERROR,
2061 "AFSSetDispositionInfo Attempt to delete root entry\n"));
2063 try_return( ntStatus = STATUS_CANNOT_DELETE);
2067 // If the file is read only then do not allow the delete
2070 if( BooleanFlagOn( DirectoryCB->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_READONLY))
2073 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2074 AFS_TRACE_LEVEL_ERROR,
2075 "AFSSetDispositionInfo Attempt to delete read only entry %wZ\n",
2076 &DirectoryCB->NameInformation.FileName));
2078 try_return( ntStatus = STATUS_CANNOT_DELETE);
2081 if( pBuffer->DeleteFile)
2085 // Check if the caller can delete the file
2088 ntStatus = AFSNotifyDelete( DirectoryCB,
2092 if( !NT_SUCCESS( ntStatus))
2095 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2096 AFS_TRACE_LEVEL_ERROR,
2097 "AFSSetDispositionInfo Cannot delete entry %wZ Status %08lX\n",
2098 &DirectoryCB->NameInformation.FileName,
2101 try_return( ntStatus);
2104 if( pFcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB)
2108 // Reduce the Link count in the object information block
2109 // to correspond with the deletion of the directory entry.
2112 pFcb->ObjectInformation->Links--;
2115 // Check if this is a directory that there are not currently other opens
2118 if( pFcb->ObjectInformation->Specific.Directory.ChildOpenHandleCount > 0)
2121 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2122 AFS_TRACE_LEVEL_ERROR,
2123 "AFSSetDispositionInfo Attempt to delete directory %wZ with open %u handles\n",
2124 &DirectoryCB->NameInformation.FileName,
2125 pFcb->ObjectInformation->Specific.Directory.ChildOpenHandleCount));
2127 try_return( ntStatus = STATUS_DIRECTORY_NOT_EMPTY);
2131 // Make sure the directory is enumerated before checking to see if it is empty.
2134 if( !BooleanFlagOn( pFcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
2137 AFSAcquireExcl( pFcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
2140 if( !BooleanFlagOn( pFcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
2143 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2144 AFS_TRACE_LEVEL_VERBOSE,
2145 "AFSSetDispositionInfo Enumerating parent FID %08lX-%08lX-%08lX-%08lX\n",
2146 pFcb->ObjectInformation->FileId.Cell,
2147 pFcb->ObjectInformation->FileId.Volume,
2148 pFcb->ObjectInformation->FileId.Vnode,
2149 pFcb->ObjectInformation->FileId.Unique));
2151 ntStatus = AFSEnumerateDirectory( &pCcb->AuthGroup,
2152 pFcb->ObjectInformation,
2155 if( !NT_SUCCESS( ntStatus))
2158 AFSReleaseResource( pFcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
2160 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2161 AFS_TRACE_LEVEL_ERROR,
2162 "AFSSetDispositionInfo Failed to enumerate parent FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
2163 pFcb->ObjectInformation->FileId.Cell,
2164 pFcb->ObjectInformation->FileId.Volume,
2165 pFcb->ObjectInformation->FileId.Vnode,
2166 pFcb->ObjectInformation->FileId.Unique,
2169 try_return( ntStatus);
2173 AFSReleaseResource( pFcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
2176 if( !AFSIsDirectoryEmptyForDelete( pFcb))
2179 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2180 AFS_TRACE_LEVEL_ERROR,
2181 "AFSSetDispositionInfo Attempt to delete non-empty directory %wZ\n",
2182 &DirectoryCB->NameInformation.FileName));
2184 try_return( ntStatus = STATUS_DIRECTORY_NOT_EMPTY);
2187 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2188 AFS_TRACE_LEVEL_VERBOSE,
2189 "AFSSetDispositionInfo Setting PENDING_DELETE on DirEntry %p Name %wZ\n",
2191 &DirectoryCB->NameInformation.FileName));
2193 SetFlag( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
2195 else if( pFcb->Header.NodeTypeCode == AFS_FILE_FCB)
2199 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
2200 AFS_TRACE_LEVEL_VERBOSE,
2201 "AFSSetDispositionInfo Acquiring Fcb lock %p EXCL %08lX\n",
2202 &pFcb->NPFcb->Resource,
2203 PsGetCurrentThread()));
2205 AFSAcquireExcl( &pFcb->NPFcb->Resource,
2208 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
2209 AFS_TRACE_LEVEL_VERBOSE,
2210 "AFSSetDispositionInfo Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
2211 &pFcb->NPFcb->SectionObjectResource,
2212 PsGetCurrentThread()));
2214 AFSAcquireExcl( &pFcb->NPFcb->SectionObjectResource,
2221 // Attempt to flush any outstanding data
2224 bMmFlushed = MmFlushImageSection( &pFcb->NPFcb->SectionObjectPointers,
2231 // Set PENDING_DELETE before CcPurgeCacheSection to avoid a
2232 // deadlock with Trend Micro's Enterprise anti-virus product
2233 // which attempts to open the file which is being deleted.
2236 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2237 AFS_TRACE_LEVEL_VERBOSE,
2238 "AFSSetDispositionInfo Setting PENDING_DELETE on DirEntry %p Name %wZ\n",
2240 &DirectoryCB->NameInformation.FileName));
2242 SetFlag( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
2245 // Purge the cache as well
2248 if( pFcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
2251 if ( !CcPurgeCacheSection( &pFcb->NPFcb->SectionObjectPointers,
2257 SetFlag( pFcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
2262 __except( EXCEPTION_EXECUTE_HANDLER)
2267 ntStatus = GetExceptionCode();
2271 "EXCEPTION - AFSSetDispositionInfo MmFlushImageSection failed FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
2272 pFcb->ObjectInformation->FileId.Cell,
2273 pFcb->ObjectInformation->FileId.Volume,
2274 pFcb->ObjectInformation->FileId.Vnode,
2275 pFcb->ObjectInformation->FileId.Unique,
2279 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
2280 AFS_TRACE_LEVEL_VERBOSE,
2281 "AFSSetDispositionInfo Releasing Fcb SectionObject lock %p EXCL %08lX\n",
2282 &pFcb->NPFcb->SectionObjectResource,
2283 PsGetCurrentThread()));
2285 AFSReleaseResource( &pFcb->NPFcb->SectionObjectResource);
2287 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
2288 AFS_TRACE_LEVEL_VERBOSE,
2289 "AFSSetDispositionInfo Releasing Fcb lock %p EXCL %08lX\n",
2290 &pFcb->NPFcb->Resource,
2291 PsGetCurrentThread()));
2293 AFSReleaseResource( &pFcb->NPFcb->Resource);
2298 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2299 AFS_TRACE_LEVEL_ERROR,
2300 "AFSSetDispositionInfo Failed to flush image section for delete Entry %wZ\n",
2301 &DirectoryCB->NameInformation.FileName));
2303 try_return( ntStatus = STATUS_CANNOT_DELETE);
2306 else if( pFcb->Header.NodeTypeCode == AFS_SYMBOLIC_LINK_FCB ||
2307 pFcb->Header.NodeTypeCode == AFS_MOUNT_POINT_FCB ||
2308 pFcb->Header.NodeTypeCode == AFS_DFS_LINK_FCB ||
2309 pFcb->Header.NodeTypeCode == AFS_INVALID_FCB)
2312 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2313 AFS_TRACE_LEVEL_VERBOSE,
2314 "AFSSetDispositionInfo Setting PENDING_DELETE on DirEntry %p Name %wZ\n",
2316 &DirectoryCB->NameInformation.FileName));
2318 SetFlag( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
2324 ClearFlag( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
2328 // OK, should be good to go, set the flag in the file object
2331 pIrpSp->FileObject->DeletePending = pBuffer->DeleteFile;
2342 AFSSetFileLinkInfo( IN PIRP Irp)
2345 NTSTATUS ntStatus = STATUS_SUCCESS;
2346 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
2347 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2348 PFILE_LINK_INFORMATION pFileLinkInfo = NULL;
2349 PFILE_OBJECT pSrcFileObj = NULL;
2350 PFILE_OBJECT pTargetFileObj = pIrpSp->Parameters.SetFile.FileObject;
2351 AFSFcb *pSrcFcb = NULL, *pTargetDcb = NULL;
2352 AFSCcb *pSrcCcb = NULL, *pTargetDirCcb = NULL;
2353 AFSObjectInfoCB *pSrcObject = NULL;
2354 AFSObjectInfoCB *pSrcParentObject = NULL, *pTargetParentObject = NULL;
2355 UNICODE_STRING uniSourceName, uniTargetName;
2356 UNICODE_STRING uniFullTargetName, uniTargetParentName;
2357 BOOLEAN bCommonParent = FALSE;
2358 AFSDirectoryCB *pTargetDirEntry = NULL;
2359 AFSDirectoryCB *pNewTargetDirEntry = NULL;
2361 BOOLEAN bTargetEntryExists = FALSE;
2363 BOOLEAN bReleaseTargetDirLock = FALSE;
2364 ULONG ulNotificationAction = 0, ulNotifyFilter = 0;
2369 pSrcFileObj = pIrpSp->FileObject;
2371 pSrcFcb = (AFSFcb *)pSrcFileObj->FsContext;
2372 pSrcCcb = (AFSCcb *)pSrcFileObj->FsContext2;
2374 pSrcObject = pSrcFcb->ObjectInformation;
2376 if ( BooleanFlagOn( pSrcObject->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
2379 pSrcParentObject = AFSFindObjectInfo( pSrcObject->VolumeCB,
2380 &pSrcObject->ParentFileId,
2384 if( pSrcParentObject == NULL)
2387 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2388 AFS_TRACE_LEVEL_ERROR,
2389 "AFSSetFileLinkInfo Unable to resolve SrcParentObject (INVALID_PARAMETER)\n"));
2393 try_return( ntStatus = STATUS_INVALID_PARAMETER);
2396 pFileLinkInfo = (PFILE_LINK_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
2399 // Perform some basic checks to ensure FS integrity
2402 if( pSrcFcb->Header.NodeTypeCode != AFS_FILE_FCB)
2405 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2406 AFS_TRACE_LEVEL_ERROR,
2407 "AFSSetFileLinkInfo Attempt to non-file (INVALID_PARAMETER)\n"));
2409 try_return( ntStatus = STATUS_INVALID_PARAMETER);
2412 if( pTargetFileObj == NULL)
2415 if ( pFileLinkInfo->RootDirectory)
2419 // The target directory is provided by HANDLE
2420 // RootDirectory is only set when the target directory is not the same
2421 // as the source directory.
2423 // AFS only supports hard links within a single directory.
2425 // The IOManager should translate any Handle to a FileObject for us.
2426 // However, the failure to receive a FileObject is treated as a fatal
2430 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2431 AFS_TRACE_LEVEL_ERROR,
2432 "AFSSetFileLinkInfo Attempt to link %wZ to alternate directory by handle INVALID_PARAMETER\n",
2433 &pSrcCcb->DirectoryCB->NameInformation.FileName));
2435 try_return( ntStatus = STATUS_INVALID_PARAMETER);
2440 uniFullTargetName.Length = (USHORT)pFileLinkInfo->FileNameLength;
2442 uniFullTargetName.Buffer = (PWSTR)&pFileLinkInfo->FileName;
2444 AFSRetrieveFinalComponent( &uniFullTargetName,
2447 AFSRetrieveParentPath( &uniFullTargetName,
2448 &uniTargetParentName);
2450 if ( uniTargetParentName.Length == 0)
2454 // This is a simple rename. Here the target directory is the same as the source parent directory
2455 // and the name is retrieved from the system buffer information
2458 pTargetParentObject = pSrcParentObject;
2463 // uniTargetParentName contains the directory the renamed object
2464 // will be moved to. Must obtain the TargetParentObject.
2467 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2468 AFS_TRACE_LEVEL_ERROR,
2469 "AFSSetFileLinkInfo Attempt to link %wZ to alternate directory %wZ (NOT_SAME_DEVICE)\n",
2470 &pSrcCcb->DirectoryCB->NameInformation.FileName,
2471 &uniFullTargetName));
2473 try_return( ntStatus = STATUS_NOT_SAME_DEVICE);
2477 pTargetDcb = pTargetParentObject->Fcb;
2483 // So here we have the target directory taken from the targetfile object
2486 pTargetDcb = (AFSFcb *)pTargetFileObj->FsContext;
2488 pTargetDirCcb = (AFSCcb *)pTargetFileObj->FsContext2;
2490 pTargetParentObject = (AFSObjectInfoCB *)pTargetDcb->ObjectInformation;
2493 // Grab the target name which we setup in the IRP_MJ_CREATE handler. By how we set this up
2494 // it is only the target component of the rename operation
2497 uniTargetName = *((PUNICODE_STRING)&pTargetFileObj->FileName);
2501 // The quick check to see if they are self linking.
2502 // Do the names match? Only do this where the parent directories are
2506 if( pTargetParentObject == pSrcParentObject)
2509 if( FsRtlAreNamesEqual( &uniTargetName,
2514 try_return( ntStatus = STATUS_SUCCESS);
2517 bCommonParent = TRUE;
2523 // We do not allow cross-volume hard links
2526 if( pTargetParentObject->VolumeCB != pSrcObject->VolumeCB)
2529 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2530 AFS_TRACE_LEVEL_ERROR,
2531 "AFSSetFileLinkInfo Attempt to link to different volume %wZ\n",
2532 &pSrcCcb->DirectoryCB->NameInformation.FileName));
2534 try_return( ntStatus = STATUS_NOT_SAME_DEVICE);
2538 ulTargetCRC = AFSGenerateCRC( &uniTargetName,
2541 AFSAcquireExcl( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock,
2544 bReleaseTargetDirLock = TRUE;
2546 AFSLocateCaseSensitiveDirEntry( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
2550 if( pTargetDirEntry == NULL)
2554 // Missed so perform a case insensitive lookup
2557 ulTargetCRC = AFSGenerateCRC( &uniTargetName,
2560 AFSLocateCaseInsensitiveDirEntry( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
2565 if ( !BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
2566 pTargetDirEntry == NULL && RtlIsNameLegalDOS8Dot3( &uniTargetName,
2571 // Try the short name
2573 AFSLocateShortNameDirEntry( pTargetParentObject->Specific.Directory.ShortNameTree,
2579 // Increment our ref count on the dir entry
2582 if( pTargetDirEntry != NULL)
2585 ASSERT( BooleanFlagOn( pTargetDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_PARENT_FID) &&
2586 AFSIsEqualFID( &pTargetParentObject->FileId, &pTargetDirEntry->ObjectInformation->ParentFileId));
2588 lCount = InterlockedIncrement( &pTargetDirEntry->DirOpenReferenceCount);
2590 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2591 AFS_TRACE_LEVEL_VERBOSE,
2592 "AFSSetFileLinkInfo Increment count on %wZ DE %p Ccb %p Cnt %d\n",
2593 &pTargetDirEntry->NameInformation.FileName,
2598 ASSERT( lCount >= 0);
2600 if( !pFileLinkInfo->ReplaceIfExists)
2603 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2604 AFS_TRACE_LEVEL_ERROR,
2605 "AFSSetFileLinkInfo Attempt to link with target collision %wZ Target %wZ\n",
2606 &pSrcCcb->DirectoryCB->NameInformation.FileName,
2607 &pTargetDirEntry->NameInformation.FileName));
2609 try_return( ntStatus = STATUS_OBJECT_NAME_COLLISION);
2612 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING | AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2613 AFS_TRACE_LEVEL_ERROR,
2614 "AFSSetFileLinkInfo Target %wZ exists DE %p Count %d, performing delete of target\n",
2615 &pTargetDirEntry->NameInformation.FileName,
2620 // Pull the directory entry from the parent
2623 AFSRemoveDirNodeFromParent( pTargetParentObject,
2627 bTargetEntryExists = TRUE;
2631 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2632 AFS_TRACE_LEVEL_VERBOSE,
2633 "AFSSetFileLinkInfo Target does NOT exist, normal linking\n"));
2637 // OK, this is a simple rename. Issue the rename
2638 // request to the service.
2641 ntStatus = AFSNotifyHardLink( pSrcObject,
2642 &pSrcCcb->AuthGroup,
2644 pTargetDcb->ObjectInformation,
2645 pSrcCcb->DirectoryCB,
2647 pFileLinkInfo->ReplaceIfExists,
2648 &pNewTargetDirEntry);
2650 if( ntStatus != STATUS_REPARSE &&
2651 !NT_SUCCESS( ntStatus))
2654 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2655 AFS_TRACE_LEVEL_ERROR,
2656 "AFSSetFileLinkInfo Failed link of %wZ to target %wZ Status %08lX\n",
2657 &pSrcCcb->DirectoryCB->NameInformation.FileName,
2661 try_return( ntStatus);
2664 if ( ntStatus != STATUS_REPARSE)
2667 AFSInsertDirectoryNode( pTargetDcb->ObjectInformation,
2673 // Send notification for the target link file
2676 if( bTargetEntryExists || pNewTargetDirEntry)
2679 ulNotificationAction = FILE_ACTION_MODIFIED;
2684 ulNotificationAction = FILE_ACTION_ADDED;
2687 AFSFsRtlNotifyFullReportChange( pTargetParentObject,
2689 (ULONG)ulNotifyFilter,
2690 (ULONG)ulNotificationAction);
2694 if( !NT_SUCCESS( ntStatus))
2697 if( bTargetEntryExists)
2700 AFSInsertDirectoryNode( pTargetParentObject,
2706 if( pTargetDirEntry != NULL)
2710 // Release DirOpenReferenceCount obtained above
2713 lCount = InterlockedDecrement( &pTargetDirEntry->DirOpenReferenceCount);
2715 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2716 AFS_TRACE_LEVEL_VERBOSE,
2717 "AFSSetFileLinkInfo Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
2718 &pTargetDirEntry->NameInformation.FileName,
2723 ASSERT( lCount >= 0);
2726 if( pNewTargetDirEntry != NULL)
2730 // Release DirOpenReferenceCount obtained from AFSNotifyHardLink
2733 lCount = InterlockedDecrement( &pNewTargetDirEntry->DirOpenReferenceCount);
2735 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2736 AFS_TRACE_LEVEL_VERBOSE,
2737 "AFSSetFileLinkInfo Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
2738 &pNewTargetDirEntry->NameInformation.FileName,
2743 ASSERT( lCount >= 0);
2746 if( bReleaseTargetDirLock)
2749 AFSReleaseResource( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
2752 if ( pSrcParentObject != NULL)
2755 AFSReleaseObjectInfo( &pSrcParentObject);
2759 // No need to release pTargetParentObject as it is either a copy of pSrcParentObject
2760 // or (AFSFcb *)pTargetFileObj->FsContext->ObjectInformation
2763 pTargetParentObject = NULL;
2770 AFSSetRenameInfo( IN PIRP Irp)
2773 NTSTATUS ntStatus = STATUS_SUCCESS;
2774 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
2775 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2776 AFSFcb *pSrcFcb = NULL, *pTargetDcb = NULL, *pTargetFcb = NULL;
2777 AFSCcb *pSrcCcb = NULL, *pTargetDirCcb = NULL;
2778 PFILE_OBJECT pSrcFileObj = pIrpSp->FileObject;
2779 PFILE_OBJECT pTargetFileObj = pIrpSp->Parameters.SetFile.FileObject;
2780 PFILE_OBJECT pTargetParentFileObj = NULL;
2781 PFILE_RENAME_INFORMATION pRenameInfo = NULL;
2782 UNICODE_STRING uniTargetName, uniSourceName, uniTargetParentName;
2783 BOOLEAN bReplaceIfExists = FALSE;
2784 UNICODE_STRING uniShortName;
2785 AFSDirectoryCB *pTargetDirEntry = NULL;
2786 ULONG ulTargetCRC = 0;
2787 BOOLEAN bTargetEntryExists = FALSE;
2788 AFSObjectInfoCB *pSrcObject = NULL;
2789 AFSObjectInfoCB *pSrcParentObject = NULL, *pTargetParentObject = NULL;
2791 ULONG ulNotificationAction = 0, ulNotifyFilter = 0;
2792 UNICODE_STRING uniFullTargetName;
2793 BOOLEAN bCommonParent = FALSE;
2794 BOOLEAN bReleaseTargetDirLock = FALSE;
2795 BOOLEAN bReleaseSourceDirLock = FALSE;
2796 BOOLEAN bDereferenceTargetParentObject = FALSE;
2797 PERESOURCE pSourceDirLock = NULL;
2803 bReplaceIfExists = pIrpSp->Parameters.SetFile.ReplaceIfExists;
2805 pRenameInfo = (PFILE_RENAME_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
2807 pSrcFcb = (AFSFcb *)pSrcFileObj->FsContext;
2808 pSrcCcb = (AFSCcb *)pSrcFileObj->FsContext2;
2810 pSrcObject = pSrcFcb->ObjectInformation;
2812 if ( BooleanFlagOn( pSrcObject->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
2815 pSrcParentObject = AFSFindObjectInfo( pSrcObject->VolumeCB,
2816 &pSrcObject->ParentFileId,
2820 if( pSrcParentObject == NULL)
2823 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2824 AFS_TRACE_LEVEL_ERROR,
2825 "AFSSetRenameInfo Unable to resolve SrcParentObject (INVALID_PARAMETER)\n"));
2829 try_return( ntStatus = STATUS_INVALID_PARAMETER);
2833 // Perform some basic checks to ensure FS integrity
2836 if( pSrcFcb->Header.NodeTypeCode == AFS_ROOT_FCB)
2840 // Can't rename the root directory
2843 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2844 AFS_TRACE_LEVEL_ERROR,
2845 "AFSSetRenameInfo Attempt to rename root entry\n"));
2847 try_return( ntStatus = STATUS_INVALID_PARAMETER);
2850 if( pSrcFcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB)
2854 // If there are any open children then fail the rename
2857 if( pSrcObject->Specific.Directory.ChildOpenHandleCount > 0)
2860 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2861 AFS_TRACE_LEVEL_ERROR,
2862 "AFSSetRenameInfo Attempt to rename directory with open children %wZ\n",
2863 &pSrcCcb->DirectoryCB->NameInformation.FileName));
2865 try_return( ntStatus = STATUS_ACCESS_DENIED);
2871 // Extract off the final component name from the Fcb
2874 uniSourceName.Length = (USHORT)pSrcCcb->DirectoryCB->NameInformation.FileName.Length;
2875 uniSourceName.MaximumLength = uniSourceName.Length;
2877 uniSourceName.Buffer = pSrcCcb->DirectoryCB->NameInformation.FileName.Buffer;
2880 // Resolve the target fileobject
2883 if( pTargetFileObj == NULL)
2886 if ( pRenameInfo->RootDirectory)
2889 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2890 AFS_TRACE_LEVEL_ERROR,
2891 "AFSSetRenameInfo Handle provided but no FileObject ntStatus INVALID_PARAMETER\n"));
2893 try_return( ntStatus = STATUS_INVALID_PARAMETER);
2898 uniFullTargetName.Length = (USHORT)pRenameInfo->FileNameLength;
2900 uniFullTargetName.Buffer = (PWSTR)&pRenameInfo->FileName;
2902 AFSRetrieveFinalComponent( &uniFullTargetName,
2905 AFSRetrieveParentPath( &uniFullTargetName,
2906 &uniTargetParentName);
2908 if ( uniTargetParentName.Length == 0)
2912 // This is a simple rename. Here the target directory is the same as the source parent directory
2913 // and the name is retrieved from the system buffer information
2916 pTargetParentObject = pSrcParentObject;
2921 // uniTargetParentName contains the directory the renamed object
2922 // will be moved to. Must obtain the TargetParentObject.
2925 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2926 AFS_TRACE_LEVEL_ERROR,
2927 "AFSSetRenameInfo Attempt to move %wZ to %wZ -- not yet supported (NOT_SAME_DEVICE)\n",
2928 &pSrcCcb->DirectoryCB->NameInformation.FileName,
2929 &uniFullTargetName));
2931 try_return( ntStatus = STATUS_NOT_SAME_DEVICE);
2935 pTargetDcb = pTargetParentObject->Fcb;
2941 // So here we have the target directory taken from the targetfile object
2944 pTargetDcb = (AFSFcb *)pTargetFileObj->FsContext;
2946 pTargetDirCcb = (AFSCcb *)pTargetFileObj->FsContext2;
2948 pTargetParentObject = (AFSObjectInfoCB *)pTargetDcb->ObjectInformation;
2951 // Grab the target name which we setup in the IRP_MJ_CREATE handler. By how we set this up
2952 // it is only the target component of the rename operation
2955 uniTargetName = *((PUNICODE_STRING)&pTargetFileObj->FileName);
2959 // The quick check to see if they are not really performing a rename
2960 // Do the names match? Only do this where the parent directories are
2964 if( pTargetParentObject == pSrcParentObject)
2967 if( FsRtlAreNamesEqual( &uniTargetName,
2972 try_return( ntStatus = STATUS_SUCCESS);
2975 bCommonParent = TRUE;
2980 bCommonParent = FALSE;
2984 // We do not allow cross-volume renames to occur
2987 if( pTargetParentObject->VolumeCB != pSrcObject->VolumeCB)
2990 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2991 AFS_TRACE_LEVEL_ERROR,
2992 "AFSSetRenameInfo Attempt to rename directory to different volume %wZ\n",
2993 &pSrcCcb->DirectoryCB->NameInformation.FileName));
2995 try_return( ntStatus = STATUS_NOT_SAME_DEVICE);
2998 ulTargetCRC = AFSGenerateCRC( &uniTargetName,
3001 AFSAcquireExcl( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock,
3004 bReleaseTargetDirLock = TRUE;
3006 if( pTargetParentObject != pSrcParentObject)
3008 AFSAcquireExcl( pSrcParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock,
3011 bReleaseSourceDirLock = TRUE;
3013 pSourceDirLock = pSrcParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock;
3016 AFSLocateCaseSensitiveDirEntry( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
3020 if( pTargetDirEntry == NULL)
3024 // Missed so perform a case insensitive lookup
3027 ulTargetCRC = AFSGenerateCRC( &uniTargetName,
3030 AFSLocateCaseInsensitiveDirEntry( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
3035 if ( !BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
3036 pTargetDirEntry == NULL && RtlIsNameLegalDOS8Dot3( &uniTargetName,
3041 // Try the short name
3043 AFSLocateShortNameDirEntry( pTargetParentObject->Specific.Directory.ShortNameTree,
3049 // Increment our ref count on the dir entry
3052 if( pTargetDirEntry != NULL)
3055 ASSERT( BooleanFlagOn( pTargetDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_PARENT_FID) &&
3056 AFSIsEqualFID( &pTargetParentObject->FileId, &pTargetDirEntry->ObjectInformation->ParentFileId));
3058 lCount = InterlockedIncrement( &pTargetDirEntry->DirOpenReferenceCount);
3060 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3061 AFS_TRACE_LEVEL_VERBOSE,
3062 "AFSSetRenameInfo Increment count on %wZ DE %p Ccb %p Cnt %d\n",
3063 &pTargetDirEntry->NameInformation.FileName,
3068 ASSERT( lCount >= 0);
3070 if( !bReplaceIfExists)
3073 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3074 AFS_TRACE_LEVEL_ERROR,
3075 "AFSSetRenameInfo Attempt to rename directory with target collision %wZ Target %wZ\n",
3076 &pSrcCcb->DirectoryCB->NameInformation.FileName,
3077 &pTargetDirEntry->NameInformation.FileName));
3079 try_return( ntStatus = STATUS_OBJECT_NAME_COLLISION);
3082 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING | AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3083 AFS_TRACE_LEVEL_ERROR,
3084 "AFSSetRenameInfo Target %wZ exists DE %p Count %d, performing delete of target\n",
3085 &pTargetDirEntry->NameInformation.FileName,
3090 // Pull the directory entry from the parent
3093 AFSRemoveDirNodeFromParent( pTargetParentObject,
3097 bTargetEntryExists = TRUE;
3101 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3102 AFS_TRACE_LEVEL_VERBOSE,
3103 "AFSSetRenameInfo Target does NOT exist, normal rename\n"));
3107 // We need to remove the DirEntry from the parent node, update the index
3108 // and reinsert it into the parent tree. Note that for entries with the
3109 // same parent we do not pull the node from the enumeration list
3112 AFSRemoveDirNodeFromParent( pSrcParentObject,
3113 pSrcCcb->DirectoryCB,
3117 // OK, this is a simple rename. Issue the rename
3118 // request to the service.
3121 ntStatus = AFSNotifyRename( pSrcObject,
3122 &pSrcCcb->AuthGroup,
3124 pTargetDcb->ObjectInformation,
3125 pSrcCcb->DirectoryCB,
3129 if( !NT_SUCCESS( ntStatus))
3133 // Attempt to re-insert the directory entry
3136 AFSInsertDirectoryNode( pSrcParentObject,
3137 pSrcCcb->DirectoryCB,
3140 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3141 AFS_TRACE_LEVEL_ERROR,
3142 "AFSSetRenameInfo Failed rename of %wZ to target %wZ Status %08lX\n",
3143 &pSrcCcb->DirectoryCB->NameInformation.FileName,
3147 try_return( ntStatus);
3151 // Set the notification up for the source file
3154 if( pSrcParentObject == pTargetParentObject &&
3155 !bTargetEntryExists)
3158 ulNotificationAction = FILE_ACTION_RENAMED_OLD_NAME;
3163 ulNotificationAction = FILE_ACTION_REMOVED;
3166 if( pSrcObject->FileType == AFS_FILE_TYPE_DIRECTORY)
3169 ulNotifyFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
3174 ulNotifyFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
3177 AFSFsRtlNotifyFullReportChange( pSrcParentObject,
3179 (ULONG)ulNotifyFilter,
3180 (ULONG)ulNotificationAction);
3183 // Update the name in the dir entry.
3186 ntStatus = AFSUpdateDirEntryName( pSrcCcb->DirectoryCB,
3189 if( !NT_SUCCESS( ntStatus))
3193 // Attempt to re-insert the directory entry
3196 AFSInsertDirectoryNode( pSrcParentObject,
3197 pSrcCcb->DirectoryCB,
3200 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3201 AFS_TRACE_LEVEL_ERROR,
3202 "AFSSetRenameInfo Failed update of dir entry %wZ to target %wZ Status %08lX\n",
3203 &pSrcCcb->DirectoryCB->NameInformation.FileName,
3207 try_return( ntStatus);
3211 // Update the object information block, if needed
3214 if( !AFSIsEqualFID( &pSrcObject->FileId,
3218 AFSAcquireExcl( pSrcObject->VolumeCB->ObjectInfoTree.TreeLock,
3222 // Remove the old information entry
3225 AFSRemoveHashEntry( &pSrcObject->VolumeCB->ObjectInfoTree.TreeHead,
3226 &pSrcObject->TreeEntry);
3228 RtlCopyMemory( &pSrcObject->FileId,
3230 sizeof( AFSFileID));
3233 // Insert the entry into the new object table.
3236 pSrcObject->TreeEntry.HashIndex = AFSCreateLowIndex( &pSrcObject->FileId);
3238 if( pSrcObject->VolumeCB->ObjectInfoTree.TreeHead == NULL)
3241 pSrcObject->VolumeCB->ObjectInfoTree.TreeHead = &pSrcObject->TreeEntry;
3246 if ( !NT_SUCCESS( AFSInsertHashEntry( pSrcObject->VolumeCB->ObjectInfoTree.TreeHead,
3247 &pSrcObject->TreeEntry)))
3251 // Lost a race, an ObjectInfo object already exists for this FID.
3252 // Let this copy be garbage collected.
3255 ClearFlag( pSrcObject->Flags, AFS_OBJECT_INSERTED_HASH_TREE);
3259 AFSReleaseResource( pSrcObject->VolumeCB->ObjectInfoTree.TreeLock);
3263 // Update the hash values for the name trees.
3266 pSrcCcb->DirectoryCB->CaseSensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pSrcCcb->DirectoryCB->NameInformation.FileName,
3269 pSrcCcb->DirectoryCB->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pSrcCcb->DirectoryCB->NameInformation.FileName,
3272 if( !BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
3273 pSrcCcb->DirectoryCB->NameInformation.ShortNameLength > 0 &&
3274 !RtlIsNameLegalDOS8Dot3( &pSrcCcb->DirectoryCB->NameInformation.FileName,
3279 uniShortName.Length = pSrcCcb->DirectoryCB->NameInformation.ShortNameLength;
3280 uniShortName.MaximumLength = uniShortName.Length;
3281 uniShortName.Buffer = pSrcCcb->DirectoryCB->NameInformation.ShortName;
3283 pSrcCcb->DirectoryCB->Type.Data.ShortNameTreeEntry.HashIndex = AFSGenerateCRC( &uniShortName,
3286 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3287 AFS_TRACE_LEVEL_VERBOSE,
3288 "AFSSetRenameInfo Initialized short name hash for %wZ longname %wZ\n",
3290 &pSrcCcb->DirectoryCB->NameInformation.FileName));
3295 pSrcCcb->DirectoryCB->Type.Data.ShortNameTreeEntry.HashIndex = 0;
3302 // Update the file index for the object in the new parent
3305 pSrcCcb->DirectoryCB->FileIndex = (ULONG)InterlockedIncrement( &pTargetParentObject->Specific.Directory.DirectoryNodeHdr.ContentIndex);
3309 // Re-insert the directory entry
3312 AFSInsertDirectoryNode( pTargetParentObject,
3313 pSrcCcb->DirectoryCB,
3317 // Update the parent pointer in the source object if they are different
3320 if( pSrcParentObject != pTargetParentObject)
3323 lCount = InterlockedDecrement( &pSrcParentObject->Specific.Directory.ChildOpenHandleCount);
3325 lCount = InterlockedDecrement( &pSrcParentObject->Specific.Directory.ChildOpenReferenceCount);
3327 lCount = InterlockedIncrement( &pTargetParentObject->Specific.Directory.ChildOpenHandleCount);
3329 lCount = InterlockedIncrement( &pTargetParentObject->Specific.Directory.ChildOpenReferenceCount);
3333 // Guaranteed to be in the same volume
3336 AFSAcquireExcl( pSrcParentObject->VolumeCB->ObjectInfoTree.TreeLock,
3339 lCount = AFSObjectInfoIncrement( pTargetParentObject,
3340 AFS_OBJECT_REFERENCE_CHILD);
3342 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
3343 AFS_TRACE_LEVEL_VERBOSE,
3344 "AFSSetRenameInfo Increment count on parent object %p Cnt %d\n",
3345 pTargetParentObject,
3348 lCount = AFSObjectInfoDecrement( pSrcParentObject,
3349 AFS_OBJECT_REFERENCE_CHILD);
3351 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
3352 AFS_TRACE_LEVEL_VERBOSE,
3353 "AFSSetRenameInfo Decrement count on parent object %p Cnt %d\n",
3357 pSrcObject->ParentFileId = pTargetParentObject->FileId;
3359 SetFlag( pSrcObject->Flags, AFS_OBJECT_FLAGS_PARENT_FID);
3361 AFSReleaseResource( pSrcParentObject->VolumeCB->ObjectInfoTree.TreeLock);
3363 ulNotificationAction = FILE_ACTION_ADDED;
3368 ulNotificationAction = FILE_ACTION_RENAMED_NEW_NAME;
3372 // Now update the notification for the target file
3375 AFSFsRtlNotifyFullReportChange( pTargetParentObject,
3377 (ULONG)ulNotifyFilter,
3378 (ULONG)ulNotificationAction);
3381 // If we performed the rename of the target because it existed, we now need to
3382 // delete the tmp target we created above
3385 if( bTargetEntryExists)
3388 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3389 AFS_TRACE_LEVEL_VERBOSE,
3390 "AFSSetRenameInfo Setting DELETE flag in dir entry %p name %wZ\n",
3392 &pTargetDirEntry->NameInformation.FileName));
3394 SetFlag( pTargetDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
3397 // Try and purge the cache map if this is a file
3400 if( pTargetDirEntry->ObjectInformation->FileType == AFS_FILE_TYPE_FILE &&
3401 pTargetDirEntry->ObjectInformation->Fcb != NULL &&
3402 pTargetDirEntry->DirOpenReferenceCount > 1)
3405 pTargetFcb = pTargetDirEntry->ObjectInformation->Fcb;
3408 ASSERT( pTargetDirEntry->DirOpenReferenceCount > 0);
3410 lCount = InterlockedDecrement( &pTargetDirEntry->DirOpenReferenceCount); // The count we added above
3412 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3413 AFS_TRACE_LEVEL_VERBOSE,
3414 "AFSSetRenameInfo Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
3415 &pTargetDirEntry->NameInformation.FileName,
3420 ASSERT( lCount >= 0);
3423 pTargetDirEntry->NameArrayReferenceCount <= 0)
3426 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3427 AFS_TRACE_LEVEL_VERBOSE,
3428 "AFSSetRenameInfo Deleting dir entry %p name %wZ\n",
3430 &pTargetDirEntry->NameInformation.FileName));
3432 AFSDeleteDirEntry( pTargetParentObject,
3436 pTargetDirEntry = NULL;
3438 if ( pTargetFcb != NULL)
3442 // Do not hold TreeLocks across the MmForceSectionClosed() call as
3443 // it can deadlock with Trend Micro's TmPreFlt!TmpQueryFullName
3446 if( bReleaseTargetDirLock)
3448 AFSReleaseResource( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
3450 bReleaseTargetDirLock = FALSE;
3453 if( bReleaseSourceDirLock)
3456 AFSReleaseResource( pSourceDirLock);
3458 bReleaseSourceDirLock = FALSE;
3462 // MmForceSectionClosed() can eventually call back into AFSCleanup
3463 // which will need to acquire Fcb->Resource exclusively. Failure
3464 // to obtain it here before holding the SectionObjectResource will
3465 // permit the locks to be obtained out of order risking a deadlock.
3468 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
3469 AFS_TRACE_LEVEL_VERBOSE,
3470 "AFSSetRenameInfo Acquiring Fcb lock %p EXCL %08lX\n",
3471 &pTargetFcb->NPFcb->Resource,
3472 PsGetCurrentThread()));
3474 AFSAcquireExcl( &pTargetFcb->NPFcb->Resource,
3477 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
3478 AFS_TRACE_LEVEL_VERBOSE,
3479 "AFSSetRenameInfo Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
3480 &pTargetFcb->NPFcb->SectionObjectResource,
3481 PsGetCurrentThread()));
3483 AFSAcquireExcl( &pTargetFcb->NPFcb->SectionObjectResource,
3490 // Close the section in the event it was mapped
3493 if( !MmForceSectionClosed( &pTargetFcb->NPFcb->SectionObjectPointers,
3497 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3498 AFS_TRACE_LEVEL_ERROR,
3499 "AFSSetRenameInfo Failed to delete section for target file %wZ\n",
3503 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
3506 ntStatus = GetExceptionCode();
3510 "EXCEPTION - AFSSetRenameInfo MmForceSectionClosed failed FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
3511 pTargetFcb->ObjectInformation->FileId.Cell,
3512 pTargetFcb->ObjectInformation->FileId.Volume,
3513 pTargetFcb->ObjectInformation->FileId.Vnode,
3514 pTargetFcb->ObjectInformation->FileId.Unique,
3518 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
3519 AFS_TRACE_LEVEL_VERBOSE,
3520 "AFSSetRenameInfo Releasing Fcb SectionObject lock %p EXCL %08lX\n",
3521 &pTargetFcb->NPFcb->SectionObjectResource,
3522 PsGetCurrentThread()));
3524 AFSReleaseResource( &pTargetFcb->NPFcb->SectionObjectResource);
3526 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3527 AFS_TRACE_LEVEL_VERBOSE,
3528 "AFSSetRenameInfo Releasing Fcb lock %p EXCL %08lX\n",
3529 &pTargetFcb->NPFcb->Resource,
3530 PsGetCurrentThread()));
3532 AFSReleaseResource( &pTargetFcb->NPFcb->Resource);
3538 if( !NT_SUCCESS( ntStatus))
3541 if( bTargetEntryExists)
3544 ASSERT( pTargetParentObject != NULL);
3546 AFSInsertDirectoryNode( pTargetParentObject,
3552 if( pTargetDirEntry != NULL)
3555 lCount = InterlockedDecrement( &pTargetDirEntry->DirOpenReferenceCount);
3557 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3558 AFS_TRACE_LEVEL_VERBOSE,
3559 "AFSSetRenameInfo Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
3560 &pTargetDirEntry->NameInformation.FileName,
3565 ASSERT( lCount >= 0);
3568 if( bReleaseTargetDirLock)
3571 AFSReleaseResource( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
3574 if( bReleaseSourceDirLock)
3577 AFSReleaseResource( pSourceDirLock);
3580 if ( bDereferenceTargetParentObject)
3583 ObDereferenceObject( pTargetParentFileObj);
3586 if ( pSrcParentObject != NULL)
3589 AFSReleaseObjectInfo( &pSrcParentObject);
3593 // No need to release pTargetParentObject as it is either a copy of pSrcParentObject
3594 // or (AFSFcb *)pTargetFileObj->FsContext->ObjectInformation
3597 pTargetParentObject = NULL;
3604 AFSSetPositionInfo( IN PIRP Irp,
3605 IN AFSDirectoryCB *DirectoryCB)
3607 UNREFERENCED_PARAMETER(DirectoryCB);
3608 NTSTATUS ntStatus = STATUS_SUCCESS;
3609 PFILE_POSITION_INFORMATION pBuffer;
3610 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
3612 pBuffer = (PFILE_POSITION_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
3614 pIrpSp->FileObject->CurrentByteOffset.QuadPart = pBuffer->CurrentByteOffset.QuadPart;
3620 AFSSetAllocationInfo( IN PIRP Irp,
3621 IN AFSDirectoryCB *DirectoryCB)
3623 UNREFERENCED_PARAMETER(DirectoryCB);
3624 NTSTATUS ntStatus = STATUS_SUCCESS;
3625 PFILE_ALLOCATION_INFORMATION pBuffer;
3626 BOOLEAN bReleasePaging = FALSE;
3627 BOOLEAN bTellCc = FALSE;
3628 BOOLEAN bTellService = FALSE;
3629 BOOLEAN bUserMapped = FALSE;
3630 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
3631 PFILE_OBJECT pFileObject = pIrpSp->FileObject;
3632 AFSFcb *pFcb = NULL;
3633 AFSCcb *pCcb = NULL;
3634 LARGE_INTEGER liSaveAlloc;
3635 LARGE_INTEGER liSaveFileSize;
3636 LARGE_INTEGER liSaveVDL;
3638 pBuffer = (PFILE_ALLOCATION_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
3640 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
3642 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
3645 // save values to put back
3647 liSaveAlloc = pFcb->Header.AllocationSize;
3648 liSaveFileSize = pFcb->Header.FileSize;
3649 liSaveVDL = pFcb->Header.ValidDataLength;
3651 if( pFcb->Header.AllocationSize.QuadPart == pBuffer->AllocationSize.QuadPart ||
3652 pIrpSp->Parameters.SetFile.AdvanceOnly)
3654 return STATUS_SUCCESS ;
3657 if( pFcb->Header.AllocationSize.QuadPart > pBuffer->AllocationSize.QuadPart)
3660 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
3661 AFS_TRACE_LEVEL_VERBOSE,
3662 "AFSSetAllocationInfo Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
3663 &pFcb->NPFcb->SectionObjectResource,
3664 PsGetCurrentThread()));
3666 AFSAcquireExcl( &pFcb->NPFcb->SectionObjectResource,
3672 bUserMapped = !MmCanFileBeTruncated( pFileObject->SectionObjectPointer,
3673 &pBuffer->AllocationSize);
3675 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
3678 bUserMapped = FALSE;
3680 ntStatus = GetExceptionCode();
3684 "EXCEPTION - AFSSetAllocationInfo MmCanFileBeTruncated failed FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
3685 pFcb->ObjectInformation->FileId.Cell,
3686 pFcb->ObjectInformation->FileId.Volume,
3687 pFcb->ObjectInformation->FileId.Vnode,
3688 pFcb->ObjectInformation->FileId.Unique,
3692 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
3693 AFS_TRACE_LEVEL_VERBOSE,
3694 "AFSSetAllocationInfo Releasing Fcb SectionObject lock %p EXCL %08lX\n",
3695 &pFcb->NPFcb->SectionObjectResource,
3696 PsGetCurrentThread()));
3698 AFSReleaseResource( &pFcb->NPFcb->SectionObjectResource);
3701 // Truncating the file
3706 ntStatus = STATUS_USER_MAPPED_FILE ;
3712 // If this is a truncation we need to grab the paging IO resource.
3715 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3716 AFS_TRACE_LEVEL_VERBOSE,
3717 "AFSSetAllocationInfo Acquiring Fcb PagingIo lock %p EXCL %08lX\n",
3718 &pFcb->NPFcb->PagingResource,
3719 PsGetCurrentThread()));
3721 AFSAcquireExcl( &pFcb->NPFcb->PagingResource,
3724 bReleasePaging = TRUE;
3727 // Must drop the Fcb Resource. When changing the file size
3728 // a deadlock can occur with Trend Micro's filter if the file
3729 // size is set to zero.
3732 AFSReleaseResource( &pFcb->NPFcb->Resource);
3734 pFcb->Header.AllocationSize = pBuffer->AllocationSize;
3736 pFcb->ObjectInformation->AllocationSize = pBuffer->AllocationSize;
3739 // Tell Cc that Allocation is moved.
3743 if( pFcb->Header.FileSize.QuadPart > pBuffer->AllocationSize.QuadPart)
3746 // We are pulling the EOF back as well so we need to tell
3749 bTellService = TRUE;
3751 pFcb->Header.FileSize = pBuffer->AllocationSize;
3753 pFcb->ObjectInformation->EndOfFile = pBuffer->AllocationSize;
3761 // Tell Cc if allocation is increased.
3764 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3765 AFS_TRACE_LEVEL_VERBOSE,
3766 "AFSSetAllocationInfo Acquiring Fcb PagingIo lock %p EXCL %08lX\n",
3767 &pFcb->NPFcb->PagingResource,
3768 PsGetCurrentThread()));
3770 AFSAcquireExcl( &pFcb->NPFcb->PagingResource,
3773 bReleasePaging = TRUE;
3776 // Must drop the Fcb Resource. When changing the file size
3777 // a deadlock can occur with Trend Micro's filter if the file
3778 // size is set to zero.
3781 AFSReleaseResource( &pFcb->NPFcb->Resource);
3783 bTellCc = pBuffer->AllocationSize.QuadPart > pFcb->Header.AllocationSize.QuadPart;
3785 pFcb->Header.AllocationSize = pBuffer->AllocationSize;
3787 pFcb->ObjectInformation->AllocationSize = pBuffer->AllocationSize;
3791 // Now Tell the server if we have to
3796 ASSERT( BooleanFlagOn( pFcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_PARENT_FID));
3798 ntStatus = AFSUpdateFileInformation( &pFcb->ObjectInformation->ParentFileId,
3799 pFcb->ObjectInformation,
3803 if (NT_SUCCESS(ntStatus))
3806 // Trim extents if we told the service - the update has done an implicit
3807 // trim at the service.
3811 AFSTrimExtents( pFcb,
3812 &pFcb->Header.FileSize);
3815 KeQuerySystemTime( &pFcb->ObjectInformation->ChangeTime);
3817 SetFlag( pFcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_CHANGE_TIME);
3820 CcIsFileCached( pFileObject))
3822 CcSetFileSizes( pFileObject,
3823 (PCC_FILE_SIZES)&pFcb->Header.AllocationSize);
3827 // Mark the file as modified so as to reflect the change into the last write on close.
3829 SetFlag( pFileObject->Flags, FO_FILE_MODIFIED);
3834 // Put the saved values back
3836 pFcb->Header.ValidDataLength = liSaveVDL;
3837 pFcb->Header.FileSize = liSaveFileSize;
3838 pFcb->Header.AllocationSize = liSaveAlloc;
3839 pFcb->ObjectInformation->EndOfFile = liSaveFileSize;
3840 pFcb->ObjectInformation->AllocationSize = liSaveAlloc;
3846 AFSReleaseResource( &pFcb->NPFcb->PagingResource);
3848 AFSAcquireExcl( &pFcb->NPFcb->Resource,
3856 AFSSetEndOfFileInfo( IN PIRP Irp,
3857 IN AFSDirectoryCB *DirectoryCB)
3859 UNREFERENCED_PARAMETER(DirectoryCB);
3860 NTSTATUS ntStatus = STATUS_SUCCESS;
3861 PFILE_END_OF_FILE_INFORMATION pBuffer;
3862 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
3863 PFILE_OBJECT pFileObject = pIrpSp->FileObject;
3864 LARGE_INTEGER liSaveSize;
3865 LARGE_INTEGER liSaveVDL;
3866 LARGE_INTEGER liSaveAlloc;
3867 BOOLEAN bModified = FALSE;
3868 BOOLEAN bReleasePaging = FALSE;
3869 BOOLEAN bTruncated = FALSE;
3870 BOOLEAN bUserMapped = FALSE;
3871 AFSFcb *pFcb = NULL;
3872 AFSCcb *pCcb = NULL;
3874 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
3876 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
3878 pBuffer = (PFILE_END_OF_FILE_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
3880 liSaveSize = pFcb->Header.FileSize;
3881 liSaveAlloc = pFcb->Header.AllocationSize;
3882 liSaveVDL = pFcb->Header.ValidDataLength;
3884 if( pFcb->Header.FileSize.QuadPart != pBuffer->EndOfFile.QuadPart &&
3885 !pIrpSp->Parameters.SetFile.AdvanceOnly)
3888 if( pBuffer->EndOfFile.QuadPart < pFcb->Header.FileSize.QuadPart)
3891 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
3892 AFS_TRACE_LEVEL_VERBOSE,
3893 "AFSSetEndOfFileInfo Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
3894 &pFcb->NPFcb->SectionObjectResource,
3895 PsGetCurrentThread()));
3897 AFSAcquireExcl( &pFcb->NPFcb->SectionObjectResource,
3903 bUserMapped = !MmCanFileBeTruncated( pFileObject->SectionObjectPointer,
3904 &pBuffer->EndOfFile);
3906 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
3909 bUserMapped = FALSE;
3911 ntStatus = GetExceptionCode();
3915 "EXCEPTION - AFSSetEndOfFileInfo MmCanFileBeTruncated failed FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
3916 pFcb->ObjectInformation->FileId.Cell,
3917 pFcb->ObjectInformation->FileId.Volume,
3918 pFcb->ObjectInformation->FileId.Vnode,
3919 pFcb->ObjectInformation->FileId.Unique,
3923 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
3924 AFS_TRACE_LEVEL_VERBOSE,
3925 "AFSSetEndOfFileInfo Releasing Fcb SectionObject lock %p EXCL %08lX\n",
3926 &pFcb->NPFcb->SectionObjectResource,
3927 PsGetCurrentThread()));
3929 AFSReleaseResource( &pFcb->NPFcb->SectionObjectResource);
3931 // Truncating the file
3935 ntStatus = STATUS_USER_MAPPED_FILE;
3941 // If this is a truncation we need to grab the paging
3944 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3945 AFS_TRACE_LEVEL_VERBOSE,
3946 "AFSSetEndOfFileInfo Acquiring Fcb PagingIo lock %p EXCL %08lX\n",
3947 &pFcb->NPFcb->PagingResource,
3948 PsGetCurrentThread()));
3950 AFSAcquireExcl( &pFcb->NPFcb->PagingResource,
3953 bReleasePaging = TRUE;
3956 // Must drop the Fcb Resource. When changing the file size
3957 // a deadlock can occur with Trend Micro's filter if the file
3958 // size is set to zero.
3961 AFSReleaseResource( &pFcb->NPFcb->Resource);
3963 pFcb->Header.AllocationSize = pBuffer->EndOfFile;
3965 pFcb->Header.FileSize = pBuffer->EndOfFile;
3967 pFcb->ObjectInformation->EndOfFile = pBuffer->EndOfFile;
3969 pFcb->ObjectInformation->AllocationSize = pBuffer->EndOfFile;
3971 if( pFcb->Header.ValidDataLength.QuadPart > pFcb->Header.FileSize.QuadPart)
3974 pFcb->Header.ValidDataLength = pFcb->Header.FileSize;
3986 // extending the file, move EOF
3990 // If this is a truncation we need to grab the paging
3993 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3994 AFS_TRACE_LEVEL_VERBOSE,
3995 "AFSSetEndOfFileInfo Acquiring Fcb PagingIo lock %p EXCL %08lX\n",
3996 &pFcb->NPFcb->PagingResource,
3997 PsGetCurrentThread()));
3999 AFSAcquireExcl( &pFcb->NPFcb->PagingResource,
4002 bReleasePaging = TRUE;
4005 // Must drop the Fcb Resource. When changing the file size
4006 // a deadlock can occur with Trend Micro's filter if the file
4007 // size is set to zero.
4010 AFSReleaseResource( &pFcb->NPFcb->Resource);
4012 pFcb->Header.FileSize = pBuffer->EndOfFile;
4014 pFcb->ObjectInformation->EndOfFile = pBuffer->EndOfFile;
4016 if (pFcb->Header.FileSize.QuadPart > pFcb->Header.AllocationSize.QuadPart)
4019 // And Allocation as needed.
4021 pFcb->Header.AllocationSize = pBuffer->EndOfFile;
4023 pFcb->ObjectInformation->AllocationSize = pBuffer->EndOfFile;
4033 KeQuerySystemTime( &pFcb->ObjectInformation->ChangeTime);
4035 SetFlag( pFcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_CHANGE_TIME);
4041 ASSERT( BooleanFlagOn( pFcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_PARENT_FID));
4043 ntStatus = AFSUpdateFileInformation( &pFcb->ObjectInformation->ParentFileId,
4044 pFcb->ObjectInformation,
4047 if( NT_SUCCESS(ntStatus))
4050 // We are now good to go so tell CC.
4052 CcSetFileSizes( pFileObject,
4053 (PCC_FILE_SIZES)&pFcb->Header.AllocationSize);
4056 // And give up those extents
4061 AFSTrimExtents( pFcb,
4062 &pFcb->Header.FileSize);
4066 // Mark the file as modified so as to reflect the change into the last write on close.
4068 SetFlag( pFileObject->Flags, FO_FILE_MODIFIED);
4072 pFcb->Header.ValidDataLength = liSaveVDL;
4073 pFcb->Header.FileSize = liSaveSize;
4074 pFcb->Header.AllocationSize = liSaveAlloc;
4075 pFcb->ObjectInformation->EndOfFile = liSaveSize;
4076 pFcb->ObjectInformation->AllocationSize = liSaveAlloc;
4083 AFSReleaseResource( &pFcb->NPFcb->PagingResource);
4085 AFSAcquireExcl( &pFcb->NPFcb->Resource,
4093 AFSProcessShareSetInfo( IN IRP *Irp,
4098 UNREFERENCED_PARAMETER(Fcb);
4099 NTSTATUS ntStatus = STATUS_SUCCESS;
4100 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
4101 FILE_INFORMATION_CLASS ulFileInformationClass;
4102 void *pPipeInfo = NULL;
4106 ulFileInformationClass = pIrpSp->Parameters.SetFile.FileInformationClass;
4108 AFSDbgTrace(( AFS_SUBSYSTEM_PIPE_PROCESSING,
4109 AFS_TRACE_LEVEL_VERBOSE,
4110 "AFSProcessShareSetInfo On pipe %wZ Class %08lX\n",
4111 &Ccb->DirectoryCB->NameInformation.FileName,
4112 ulFileInformationClass));
4114 pPipeInfo = AFSLockSystemBuffer( Irp,
4115 pIrpSp->Parameters.SetFile.Length);
4117 if( pPipeInfo == NULL)
4120 AFSDbgTrace(( AFS_SUBSYSTEM_PIPE_PROCESSING,
4121 AFS_TRACE_LEVEL_ERROR,
4122 "AFSProcessShareSetInfo Failed to lock buffer on pipe %wZ\n",
4123 &Ccb->DirectoryCB->NameInformation.FileName));
4125 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4129 // Send the request to the service
4132 ntStatus = AFSNotifySetPipeInfo( Ccb,
4133 (ULONG)ulFileInformationClass,
4134 pIrpSp->Parameters.SetFile.Length,
4137 if( !NT_SUCCESS( ntStatus))
4140 AFSDbgTrace(( AFS_SUBSYSTEM_PIPE_PROCESSING,
4141 AFS_TRACE_LEVEL_ERROR,
4142 "AFSProcessShareSetInfo Failed to send request to service on pipe %wZ Status %08lX\n",
4143 &Ccb->DirectoryCB->NameInformation.FileName,
4146 try_return( ntStatus);
4149 AFSDbgTrace(( AFS_SUBSYSTEM_PIPE_PROCESSING,
4150 AFS_TRACE_LEVEL_VERBOSE,
4151 "AFSProcessShareSetInfo Completed request on pipe %wZ Class %08lX\n",
4152 &Ccb->DirectoryCB->NameInformation.FileName,
4153 ulFileInformationClass));
4164 AFSProcessShareQueryInfo( IN IRP *Irp,
4169 UNREFERENCED_PARAMETER(Fcb);
4170 NTSTATUS ntStatus = STATUS_SUCCESS;
4171 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
4172 FILE_INFORMATION_CLASS ulFileInformationClass;
4173 void *pPipeInfo = NULL;
4178 ulFileInformationClass = pIrpSp->Parameters.QueryFile.FileInformationClass;
4180 AFSDbgTrace(( AFS_SUBSYSTEM_PIPE_PROCESSING,
4181 AFS_TRACE_LEVEL_VERBOSE,
4182 "AFSProcessShareQueryInfo On pipe %wZ Class %08lX\n",
4183 &Ccb->DirectoryCB->NameInformation.FileName,
4184 ulFileInformationClass));
4186 pPipeInfo = AFSLockSystemBuffer( Irp,
4187 pIrpSp->Parameters.QueryFile.Length);
4189 if( pPipeInfo == NULL)
4192 AFSDbgTrace(( AFS_SUBSYSTEM_PIPE_PROCESSING,
4193 AFS_TRACE_LEVEL_ERROR,
4194 "AFSProcessShareQueryInfo Failed to lock buffer on pipe %wZ\n",
4195 &Ccb->DirectoryCB->NameInformation.FileName));
4197 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4201 // Send the request to the service
4204 ntStatus = AFSNotifyQueryPipeInfo( Ccb,
4205 (ULONG)ulFileInformationClass,
4206 pIrpSp->Parameters.QueryFile.Length,
4208 (ULONG *)&Irp->IoStatus.Information);
4210 if( !NT_SUCCESS( ntStatus))
4213 AFSDbgTrace(( AFS_SUBSYSTEM_PIPE_PROCESSING,
4214 AFS_TRACE_LEVEL_ERROR,
4215 "AFSProcessShareQueryInfo Failed to send request to service on pipe %wZ Status %08lX\n",
4216 &Ccb->DirectoryCB->NameInformation.FileName,
4219 try_return( ntStatus);
4222 AFSDbgTrace(( AFS_SUBSYSTEM_PIPE_PROCESSING,
4223 AFS_TRACE_LEVEL_VERBOSE,
4224 "AFSProcessShareQueryInfo Completed request on pipe %wZ Class %08lX\n",
4225 &Ccb->DirectoryCB->NameInformation.FileName,
4226 ulFileInformationClass));
4237 AFSProcessPIOCtlQueryInfo( IN IRP *Irp,
4240 IN OUT LONG *Length)
4243 UNREFERENCED_PARAMETER(Fcb);
4244 UNREFERENCED_PARAMETER(Ccb);
4245 NTSTATUS ntStatus = STATUS_SUCCESS;
4246 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
4247 FILE_INFORMATION_CLASS ulFileInformationClass;
4252 ulFileInformationClass = pIrpSp->Parameters.QueryFile.FileInformationClass;
4254 switch( ulFileInformationClass)
4257 case FileBasicInformation:
4260 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4261 AFS_TRACE_LEVEL_VERBOSE,
4262 "AFSProcessPIOCtlQueryInfo (FileBasicInformation)\n"));
4264 if ( *Length >= sizeof( FILE_BASIC_INFORMATION))
4266 PFILE_BASIC_INFORMATION pBasic = (PFILE_BASIC_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
4268 pBasic->CreationTime.QuadPart = 0;
4269 pBasic->LastAccessTime.QuadPart = 0;
4270 pBasic->ChangeTime.QuadPart = 0;
4271 pBasic->LastWriteTime.QuadPart = 0;
4272 pBasic->FileAttributes = FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM;
4274 *Length -= sizeof( FILE_BASIC_INFORMATION);
4278 ntStatus = STATUS_BUFFER_TOO_SMALL;
4284 case FileStandardInformation:
4287 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4288 AFS_TRACE_LEVEL_VERBOSE,
4289 "AFSProcessPIOCtlQueryInfo (FileStandardInformation)\n"));
4291 if ( *Length >= sizeof( FILE_STANDARD_INFORMATION))
4293 PFILE_STANDARD_INFORMATION pStandard = (PFILE_STANDARD_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
4295 pStandard->NumberOfLinks = 1;
4296 pStandard->DeletePending = 0;
4297 pStandard->AllocationSize.QuadPart = 0;
4298 pStandard->EndOfFile.QuadPart = 0;
4299 pStandard->Directory = 0;
4301 *Length -= sizeof( FILE_STANDARD_INFORMATION);
4305 ntStatus = STATUS_BUFFER_TOO_SMALL;
4311 case FileNormalizedNameInformation:
4312 case FileNameInformation:
4315 ULONG ulCopyLength = 0;
4316 AFSFcb *pFcb = NULL;
4317 AFSCcb *pCcb = NULL;
4318 USHORT usFullNameLength = 0;
4319 PFILE_NAME_INFORMATION pNameInfo = (PFILE_NAME_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
4320 UNICODE_STRING uniName;
4322 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4323 AFS_TRACE_LEVEL_VERBOSE,
4324 "AFSProcessPIOCtlQueryInfo (FileNameInformation)\n"));
4326 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
4327 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
4329 if( *Length < FIELD_OFFSET( FILE_NAME_INFORMATION, FileName))
4331 ntStatus = STATUS_BUFFER_TOO_SMALL;
4335 RtlZeroMemory( pNameInfo,
4338 usFullNameLength = sizeof( WCHAR) +
4339 AFSServerName.Length +
4340 pCcb->FullFileName.Length;
4342 if( *Length >= (LONG)(FIELD_OFFSET( FILE_NAME_INFORMATION, FileName) + (LONG)usFullNameLength))
4344 ulCopyLength = (LONG)usFullNameLength;
4348 ulCopyLength = *Length - FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
4349 ntStatus = STATUS_BUFFER_OVERFLOW;
4352 pNameInfo->FileNameLength = (ULONG)usFullNameLength;
4354 *Length -= FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
4356 if( ulCopyLength > 0)
4359 pNameInfo->FileName[ 0] = L'\\';
4360 ulCopyLength -= sizeof( WCHAR);
4362 *Length -= sizeof( WCHAR);
4364 if( ulCopyLength >= AFSServerName.Length)
4367 RtlCopyMemory( &pNameInfo->FileName[ 1],
4368 AFSServerName.Buffer,
4369 AFSServerName.Length);
4371 ulCopyLength -= AFSServerName.Length;
4372 *Length -= AFSServerName.Length;
4374 if( ulCopyLength >= pCcb->FullFileName.Length)
4377 RtlCopyMemory( &pNameInfo->FileName[ 1 + (AFSServerName.Length/sizeof( WCHAR))],
4378 pCcb->FullFileName.Buffer,
4379 pCcb->FullFileName.Length);
4381 ulCopyLength -= pCcb->FullFileName.Length;
4382 *Length -= pCcb->FullFileName.Length;
4384 uniName.Length = (USHORT)pNameInfo->FileNameLength;
4385 uniName.MaximumLength = uniName.Length;
4386 uniName.Buffer = pNameInfo->FileName;
4391 RtlCopyMemory( &pNameInfo->FileName[ 1 + (AFSServerName.Length/sizeof( WCHAR))],
4392 pCcb->FullFileName.Buffer,
4395 *Length -= ulCopyLength;
4397 uniName.Length = (USHORT)(sizeof( WCHAR) + AFSServerName.Length + ulCopyLength);
4398 uniName.MaximumLength = uniName.Length;
4399 uniName.Buffer = pNameInfo->FileName;
4402 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4403 AFS_TRACE_LEVEL_VERBOSE,
4404 "AFSProcessPIOCtlQueryInfo (FileNameInformation) Returning %wZ\n",
4412 case FileInternalInformation:
4415 PFILE_INTERNAL_INFORMATION pInternalInfo = (PFILE_INTERNAL_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
4417 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4418 AFS_TRACE_LEVEL_VERBOSE,
4419 "AFSProcessPIOCtlQueryInfo (FileInternalInformation)\n"));
4421 if( *Length >= sizeof( FILE_INTERNAL_INFORMATION))
4424 pInternalInfo->IndexNumber.HighPart = 0;
4426 pInternalInfo->IndexNumber.LowPart = 0;
4428 *Length -= sizeof( FILE_INTERNAL_INFORMATION);
4433 ntStatus = STATUS_BUFFER_TOO_SMALL;
4439 case FileAllInformation:
4441 ntStatus = STATUS_INVALID_PARAMETER;
4443 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4444 AFS_TRACE_LEVEL_WARNING,
4445 "AFSProcessPIOCtlQueryInfo (FileAllInformation) Not Implemented\n"));
4450 case FileEaInformation:
4452 ntStatus = STATUS_INVALID_PARAMETER;
4454 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4455 AFS_TRACE_LEVEL_WARNING,
4456 "AFSProcessPIOCtlQueryInfo (FileEaInformation) Not Implemented\n"));
4461 case FilePositionInformation:
4463 ntStatus = STATUS_INVALID_PARAMETER;
4465 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4466 AFS_TRACE_LEVEL_WARNING,
4467 "AFSProcessPIOCtlQueryInfo (FilePositionInformation) Not Implemented\n"));
4472 case FileAlternateNameInformation:
4474 ntStatus = STATUS_INVALID_PARAMETER;
4476 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4477 AFS_TRACE_LEVEL_WARNING,
4478 "AFSProcessPIOCtlQueryInfo (FileAlternateNameInformation) Not Implemented\n"));
4483 case FileNetworkOpenInformation:
4485 ntStatus = STATUS_INVALID_PARAMETER;
4487 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4488 AFS_TRACE_LEVEL_WARNING,
4489 "AFSProcessPIOCtlQueryInfo (FileNetworkOpenInformation) Not Implemented\n"));
4494 case FileStreamInformation:
4496 ntStatus = STATUS_INVALID_PARAMETER;
4498 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4499 AFS_TRACE_LEVEL_WARNING,
4500 "AFSProcessPIOCtlQueryInfo (FileStreamInformation) Not Implemented\n"));
4505 case FileAttributeTagInformation:
4507 ntStatus = STATUS_INVALID_PARAMETER;
4509 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4510 AFS_TRACE_LEVEL_WARNING,
4511 "AFSProcessPIOCtlQueryInfo (FileAttributeTagInformation) Not Implemented\n"));
4516 case FileRemoteProtocolInformation:
4518 ntStatus = STATUS_INVALID_PARAMETER;
4520 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4521 AFS_TRACE_LEVEL_WARNING,
4522 "AFSProcessPIOCtlQueryInfo (FileRemoteProtocolInformation) Not Implemented\n"));
4527 case FileNetworkPhysicalNameInformation:
4529 ntStatus = STATUS_INVALID_PARAMETER;
4531 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4532 AFS_TRACE_LEVEL_WARNING,
4533 "AFSProcessPIOCtlQueryInfo (FileNetworkPhysicalNameInformation) Not Implemented\n"));
4540 ntStatus = STATUS_INVALID_PARAMETER;
4542 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4543 AFS_TRACE_LEVEL_WARNING,
4544 "AFSProcessPIOCtlQueryInfo Not handling request %08lX\n",
4545 ulFileInformationClass));
4552 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4553 AFS_TRACE_LEVEL_VERBOSE,
4554 "AFSProcessPIOCtlQueryInfo ntStatus %08lX\n",