2 * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC.
3 * Copyright (c) 2009, 2010, 2011 Your File System, Inc.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * - Redistributions of source code must retain the above copyright notice,
11 * this list of conditions and the following disclaimer.
12 * - Redistributions in binary form must reproduce the above copyright
14 * this list of conditions and the following disclaimer in the
16 * and/or other materials provided with the distribution.
17 * - Neither the names of Kernel Drivers, LLC and Your File System, Inc.
18 * nor the names of their contributors may be used to endorse or promote
19 * products derived from this software without specific prior written
20 * permission from Kernel Drivers, LLC and Your File System, Inc.
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
24 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
25 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
26 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 // File: 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 ClearFlag( pFcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY);
117 ntStatus = STATUS_SUCCESS;
122 // Grab the main shared right off the bat
125 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
126 AFS_TRACE_LEVEL_VERBOSE,
127 "AFSQueryFileInfo Acquiring Fcb lock %p SHARED %08lX\n",
128 &pFcb->NPFcb->Resource,
129 PsGetCurrentThread()));
131 AFSAcquireShared( &pFcb->NPFcb->Resource,
137 // Don't allow requests against IOCtl nodes
140 if( pFcb->Header.NodeTypeCode == AFS_SPECIAL_SHARE_FCB)
143 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
144 AFS_TRACE_LEVEL_VERBOSE,
145 "AFSQueryFileInfo Processing request against SpecialShare Fcb\n"));
147 ntStatus = AFSProcessShareQueryInfo( Irp,
151 try_return( ntStatus);
153 else if( pFcb->Header.NodeTypeCode == AFS_IOCTL_FCB)
155 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
156 AFS_TRACE_LEVEL_VERBOSE,
157 "AFSQueryFileInfo request against PIOCtl Fcb\n"));
159 ntStatus = AFSProcessPIOCtlQueryInfo( Irp,
164 try_return( ntStatus);
167 else if( pFcb->Header.NodeTypeCode == AFS_INVALID_FCB)
169 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
170 AFS_TRACE_LEVEL_VERBOSE,
171 "AFSQueryFileInfo request against Invalid Fcb\n"));
173 try_return( ntStatus = STATUS_ACCESS_DENIED);
177 // Process the request
180 switch( stFileInformationClass)
183 case FileAllInformation:
186 PFILE_ALL_INFORMATION pAllInfo;
189 // For the all information class we'll typecast a local
190 // pointer to the output buffer and then call the
191 // individual routines to fill in the buffer.
194 pAllInfo = (PFILE_ALL_INFORMATION)pBuffer;
196 ntStatus = AFSQueryBasicInfo( Irp,
198 &pAllInfo->BasicInformation,
201 if( !NT_SUCCESS( ntStatus))
204 try_return( ntStatus);
207 ntStatus = AFSQueryStandardInfo( Irp,
209 &pAllInfo->StandardInformation,
212 if( !NT_SUCCESS( ntStatus))
215 try_return( ntStatus);
218 ntStatus = AFSQueryInternalInfo( Irp,
220 &pAllInfo->InternalInformation,
223 if( !NT_SUCCESS( ntStatus))
226 try_return( ntStatus);
229 ntStatus = AFSQueryEaInfo( Irp,
231 &pAllInfo->EaInformation,
234 if( !NT_SUCCESS( ntStatus))
237 try_return( ntStatus);
240 ntStatus = AFSQueryAccess( Irp,
242 &pAllInfo->AccessInformation,
245 if( !NT_SUCCESS( ntStatus))
248 try_return( ntStatus);
251 ntStatus = AFSQueryPositionInfo( Irp,
253 &pAllInfo->PositionInformation,
256 if( !NT_SUCCESS( ntStatus))
259 try_return( ntStatus);
262 ntStatus = AFSQueryMode( Irp,
264 &pAllInfo->ModeInformation,
267 if( !NT_SUCCESS( ntStatus))
270 try_return( ntStatus);
273 ntStatus = AFSQueryAlignment( Irp,
275 &pAllInfo->AlignmentInformation,
278 if( !NT_SUCCESS( ntStatus))
281 try_return( ntStatus);
284 ntStatus = AFSQueryNameInfo( Irp,
286 &pAllInfo->NameInformation,
289 if( !NT_SUCCESS( ntStatus))
292 try_return( ntStatus);
298 case FileBasicInformation:
301 ntStatus = AFSQueryBasicInfo( Irp,
303 (PFILE_BASIC_INFORMATION)pBuffer,
309 case FileStandardInformation:
312 ntStatus = AFSQueryStandardInfo( Irp,
314 (PFILE_STANDARD_INFORMATION)pBuffer,
320 case FileInternalInformation:
323 ntStatus = AFSQueryInternalInfo( Irp,
325 (PFILE_INTERNAL_INFORMATION)pBuffer,
331 case FileEaInformation:
334 ntStatus = AFSQueryEaInfo( Irp,
336 (PFILE_EA_INFORMATION)pBuffer,
342 case FilePositionInformation:
345 ntStatus = AFSQueryPositionInfo( Irp,
347 (PFILE_POSITION_INFORMATION)pBuffer,
353 case FileNormalizedNameInformation:
354 case FileNameInformation:
357 ntStatus = AFSQueryNameInfo( Irp,
359 (PFILE_NAME_INFORMATION)pBuffer,
365 case FileAlternateNameInformation:
368 ntStatus = AFSQueryShortNameInfo( Irp,
370 (PFILE_NAME_INFORMATION)pBuffer,
376 case FileNetworkOpenInformation:
379 ntStatus = AFSQueryNetworkInfo( Irp,
381 (PFILE_NETWORK_OPEN_INFORMATION)pBuffer,
387 case FileStreamInformation:
390 ntStatus = AFSQueryStreamInfo( Irp,
392 (FILE_STREAM_INFORMATION *)pBuffer,
399 case FileAttributeTagInformation:
402 ntStatus = AFSQueryAttribTagInfo( Irp,
404 (FILE_ATTRIBUTE_TAG_INFORMATION *)pBuffer,
410 case FileRemoteProtocolInformation:
413 ntStatus = AFSQueryRemoteProtocolInfo( Irp,
415 (FILE_REMOTE_PROTOCOL_INFORMATION *)pBuffer,
421 case FileNetworkPhysicalNameInformation:
424 ntStatus = AFSQueryPhysicalNameInfo( Irp,
426 (FILE_NETWORK_PHYSICAL_NAME_INFORMATION *)pBuffer,
434 ntStatus = STATUS_INVALID_PARAMETER;
441 Irp->IoStatus.Information = pIrpSp->Parameters.QueryFile.Length - lLength;
446 AFSReleaseResource( &pFcb->NPFcb->Resource);
449 if( !NT_SUCCESS( ntStatus) &&
450 ntStatus != STATUS_INVALID_PARAMETER &&
451 ntStatus != STATUS_BUFFER_OVERFLOW)
455 pCcb->DirectoryCB != NULL)
458 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
459 AFS_TRACE_LEVEL_ERROR,
460 "AFSQueryFileInfo Failed to process request for %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
461 &pCcb->DirectoryCB->NameInformation.FileName,
462 pFcb->ObjectInformation->FileId.Cell,
463 pFcb->ObjectInformation->FileId.Volume,
464 pFcb->ObjectInformation->FileId.Vnode,
465 pFcb->ObjectInformation->FileId.Unique,
470 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
475 "EXCEPTION - AFSQueryFileInfo\n"));
477 AFSDumpTraceFilesFnc();
479 ntStatus = STATUS_UNSUCCESSFUL;
484 AFSReleaseResource( &pFcb->NPFcb->Resource);
488 AFSCompleteRequest( Irp,
495 // Function: AFSSetFileInfo
499 // This function is the dispatch handler for the IRP_MJ_SET_FILE_INFORMATION request
503 // A status is returned for the function
507 AFSSetFileInfo( IN PDEVICE_OBJECT LibDeviceObject,
511 UNREFERENCED_PARAMETER(LibDeviceObject);
512 NTSTATUS ntStatus = STATUS_SUCCESS;
513 IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
516 FILE_INFORMATION_CLASS FileInformationClass;
517 BOOLEAN bCanQueueRequest = FALSE;
518 PFILE_OBJECT pFileObject = NULL;
519 BOOLEAN bReleaseMain = FALSE;
520 BOOLEAN bUpdateFileInfo = FALSE;
521 AFSFileID stParentFileId;
526 pFileObject = pIrpSp->FileObject;
528 pFcb = (AFSFcb *)pFileObject->FsContext;
529 pCcb = (AFSCcb *)pFileObject->FsContext2;
534 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
535 AFS_TRACE_LEVEL_ERROR,
536 "AFSSetFileInfo Attempted access (%p) when pFcb == NULL\n",
539 try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST);
542 bCanQueueRequest = !(IoIsOperationSynchronous( Irp) | (KeGetCurrentIrql() != PASSIVE_LEVEL));
543 FileInformationClass = pIrpSp->Parameters.SetFile.FileInformationClass;
549 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
550 AFS_TRACE_LEVEL_VERBOSE,
551 "AFSSetFileInfo Acquiring Fcb lock %p EXCL %08lX\n",
552 &pFcb->NPFcb->Resource,
553 PsGetCurrentThread()));
555 AFSAcquireExcl( &pFcb->NPFcb->Resource,
561 // Don't allow requests against IOCtl nodes
564 if( pFcb->Header.NodeTypeCode == AFS_IOCTL_FCB)
567 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
568 AFS_TRACE_LEVEL_ERROR,
569 "AFSSetFileInfo Failing request against PIOCtl Fcb\n"));
571 try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST);
573 else if( pFcb->Header.NodeTypeCode == AFS_SPECIAL_SHARE_FCB)
576 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
577 AFS_TRACE_LEVEL_VERBOSE,
578 "AFSSetFileInfo Processing request against SpecialShare Fcb\n"));
580 ntStatus = AFSProcessShareSetInfo( Irp,
584 try_return( ntStatus);
587 if( BooleanFlagOn( pFcb->ObjectInformation->VolumeCB->VolumeInformation.FileSystemAttributes, FILE_READ_ONLY_VOLUME))
590 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
591 AFS_TRACE_LEVEL_ERROR,
592 "AFSSetFileInfo Request failed due to read only volume\n",
595 try_return( ntStatus = STATUS_MEDIA_WRITE_PROTECTED);
598 if( pFcb->Header.NodeTypeCode == AFS_INVALID_FCB &&
599 FileInformationClass != FileDispositionInformation)
601 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
602 AFS_TRACE_LEVEL_VERBOSE,
603 "AFSSetFileInfo request against Invalid Fcb\n"));
605 try_return( ntStatus = STATUS_ACCESS_DENIED);
609 // Ensure rename operations are synchronous
612 if( FileInformationClass == FileRenameInformation)
615 bCanQueueRequest = FALSE;
619 // Store away the parent fid
622 RtlZeroMemory( &stParentFileId,
625 if( BooleanFlagOn( pFcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
628 stParentFileId = pFcb->ObjectInformation->ParentFileId;
632 // Process the request
635 switch( FileInformationClass)
638 case FileBasicInformation:
641 bUpdateFileInfo = TRUE;
643 ntStatus = AFSSetBasicInfo( Irp,
649 case FileDispositionInformation:
652 ntStatus = AFSSetDispositionInfo( Irp,
658 case FileRenameInformation:
661 ntStatus = AFSSetRenameInfo( Irp);
666 case FilePositionInformation:
669 ntStatus = AFSSetPositionInfo( Irp,
675 case FileLinkInformation:
678 ntStatus = AFSSetFileLinkInfo( Irp);
683 case FileAllocationInformation:
686 ntStatus = AFSSetAllocationInfo( Irp,
692 case FileEndOfFileInformation:
695 ntStatus = AFSSetEndOfFileInfo( Irp,
703 ntStatus = STATUS_INVALID_PARAMETER;
713 AFSReleaseResource( &pFcb->NPFcb->Resource);
716 if( NT_SUCCESS( ntStatus) &&
720 ntStatus = AFSUpdateFileInformation( &stParentFileId,
721 pFcb->ObjectInformation,
724 if( !NT_SUCCESS( ntStatus))
727 AFSAcquireExcl( &pFcb->NPFcb->Resource,
731 // Unwind the update and fail the request
734 AFSUnwindFileInfo( pFcb,
737 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
738 AFS_TRACE_LEVEL_ERROR,
739 "AFSSetFileInfo Failed to send file info update to service request for %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
740 &pCcb->DirectoryCB->NameInformation.FileName,
741 pFcb->ObjectInformation->FileId.Cell,
742 pFcb->ObjectInformation->FileId.Volume,
743 pFcb->ObjectInformation->FileId.Vnode,
744 pFcb->ObjectInformation->FileId.Unique,
747 AFSReleaseResource( &pFcb->NPFcb->Resource);
751 if( !NT_SUCCESS( ntStatus))
755 pCcb->DirectoryCB != NULL)
758 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
759 AFS_TRACE_LEVEL_ERROR,
760 "AFSSetFileInfo Failed to process request for %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
761 &pCcb->DirectoryCB->NameInformation.FileName,
762 pFcb->ObjectInformation->FileId.Cell,
763 pFcb->ObjectInformation->FileId.Volume,
764 pFcb->ObjectInformation->FileId.Vnode,
765 pFcb->ObjectInformation->FileId.Unique,
770 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
775 "EXCEPTION - AFSSetFileInfo\n"));
777 AFSDumpTraceFilesFnc();
779 ntStatus = STATUS_UNSUCCESSFUL;
784 AFSReleaseResource( &pFcb->NPFcb->Resource);
788 AFSCompleteRequest( Irp,
795 // Function: AFSQueryBasicInfo
799 // This function is the handler for the query basic information request
803 // A status is returned for the function
807 AFSQueryBasicInfo( IN PIRP Irp,
808 IN AFSDirectoryCB *DirectoryCB,
809 IN OUT PFILE_BASIC_INFORMATION Buffer,
812 NTSTATUS ntStatus = STATUS_SUCCESS;
813 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
814 ULONG ulFileAttribs = 0;
817 IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
818 AFSFileInfoCB stFileInfo;
819 AFSDirectoryCB *pParentDirectoryCB = NULL;
820 UNICODE_STRING uniParentPath;
822 if( *Length >= sizeof( FILE_BASIC_INFORMATION))
825 RtlZeroMemory( Buffer,
828 ulFileAttribs = DirectoryCB->ObjectInformation->FileAttributes;
830 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
831 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
833 if( DirectoryCB->ObjectInformation->FileType == AFS_FILE_TYPE_SYMLINK)
836 pParentDirectoryCB = AFSGetParentEntry( pCcb->NameArray);
838 AFSRetrieveParentPath( &pCcb->FullFileName,
841 RtlZeroMemory( &stFileInfo,
842 sizeof( AFSFileInfoCB));
845 // Can't hold the Fcb while evaluating the path, leads to lock inversion
848 AFSReleaseResource( &pFcb->NPFcb->Resource);
851 // Its a reparse point regardless of whether the file attributes
852 // can be retrieved for the target.
855 if ( ulFileAttribs == FILE_ATTRIBUTE_NORMAL)
858 ulFileAttribs = FILE_ATTRIBUTE_REPARSE_POINT;
863 ulFileAttribs |= FILE_ATTRIBUTE_REPARSE_POINT;
866 if( NT_SUCCESS( AFSRetrieveFileAttributes( pParentDirectoryCB,
874 if ( stFileInfo.FileAttributes & FILE_ATTRIBUTE_DIRECTORY)
877 ulFileAttribs |= FILE_ATTRIBUTE_DIRECTORY;
881 AFSAcquireShared( &pFcb->NPFcb->Resource,
886 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
887 AFS_TRACE_LEVEL_VERBOSE_2,
888 "AFSQueryBasicInfo %wZ Type 0x%x Attrib 0x%x -> 0x%x\n",
889 &pCcb->DirectoryCB->NameInformation.FileName,
890 pFcb->ObjectInformation->FileType,
891 pFcb->ObjectInformation->FileAttributes,
894 Buffer->CreationTime = DirectoryCB->ObjectInformation->CreationTime;
895 Buffer->LastAccessTime = DirectoryCB->ObjectInformation->LastAccessTime;
896 Buffer->LastWriteTime = DirectoryCB->ObjectInformation->LastWriteTime;
897 Buffer->ChangeTime = DirectoryCB->ObjectInformation->ChangeTime;
898 Buffer->FileAttributes = ulFileAttribs;
900 if( DirectoryCB->NameInformation.FileName.Buffer[ 0] == L'.' &&
901 BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_HIDE_DOT_NAMES))
904 if ( Buffer->FileAttributes != FILE_ATTRIBUTE_NORMAL)
906 Buffer->FileAttributes |= FILE_ATTRIBUTE_HIDDEN;
910 Buffer->FileAttributes = FILE_ATTRIBUTE_HIDDEN;
914 *Length -= sizeof( FILE_BASIC_INFORMATION);
919 ntStatus = STATUS_BUFFER_TOO_SMALL;
926 AFSQueryStandardInfo( IN PIRP Irp,
927 IN AFSDirectoryCB *DirectoryCB,
928 IN OUT PFILE_STANDARD_INFORMATION Buffer,
932 NTSTATUS ntStatus = STATUS_SUCCESS;
935 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
936 AFSFileInfoCB stFileInfo;
937 AFSDirectoryCB *pParentDirectoryCB = NULL;
938 UNICODE_STRING uniParentPath;
939 ULONG ulFileAttribs = 0;
941 if( *Length >= sizeof( FILE_STANDARD_INFORMATION))
944 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
945 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
947 RtlZeroMemory( Buffer,
950 Buffer->NumberOfLinks = 1;
951 Buffer->DeletePending = BooleanFlagOn( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
953 Buffer->AllocationSize.QuadPart = (ULONGLONG)((DirectoryCB->ObjectInformation->AllocationSize.QuadPart/PAGE_SIZE) + 1) * PAGE_SIZE;
955 Buffer->EndOfFile = DirectoryCB->ObjectInformation->EndOfFile;
957 ulFileAttribs = DirectoryCB->ObjectInformation->FileAttributes;
959 if( DirectoryCB->ObjectInformation->FileType == AFS_FILE_TYPE_SYMLINK)
962 pParentDirectoryCB = AFSGetParentEntry( pCcb->NameArray);
964 AFSRetrieveParentPath( &pCcb->FullFileName,
967 RtlZeroMemory( &stFileInfo,
968 sizeof( AFSFileInfoCB));
971 // Can't hold the Fcb while evaluating the path, leads to lock inversion
974 AFSReleaseResource( &pFcb->NPFcb->Resource);
977 // Its a reparse point regardless of whether or not the
978 // file attributes can be retrieved.
981 if ( ulFileAttribs == FILE_ATTRIBUTE_NORMAL)
984 ulFileAttribs = FILE_ATTRIBUTE_REPARSE_POINT;
989 ulFileAttribs |= FILE_ATTRIBUTE_REPARSE_POINT;
992 if( NT_SUCCESS( AFSRetrieveFileAttributes( pParentDirectoryCB,
1000 if ( stFileInfo.FileAttributes & FILE_ATTRIBUTE_DIRECTORY)
1003 ulFileAttribs |= FILE_ATTRIBUTE_DIRECTORY;
1007 AFSAcquireShared( &pFcb->NPFcb->Resource,
1011 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1012 AFS_TRACE_LEVEL_VERBOSE_2,
1013 "AFSQueryStandardInfo %wZ Type 0x%x Attrib 0x%x -> 0x%x\n",
1014 &pCcb->DirectoryCB->NameInformation.FileName,
1015 pFcb->ObjectInformation->FileType,
1016 pFcb->ObjectInformation->FileAttributes,
1019 Buffer->Directory = BooleanFlagOn( ulFileAttribs, FILE_ATTRIBUTE_DIRECTORY);
1021 *Length -= sizeof( FILE_STANDARD_INFORMATION);
1026 ntStatus = STATUS_BUFFER_TOO_SMALL;
1033 AFSQueryInternalInfo( IN PIRP Irp,
1035 IN OUT PFILE_INTERNAL_INFORMATION Buffer,
1036 IN OUT PLONG Length)
1039 UNREFERENCED_PARAMETER(Irp);
1040 NTSTATUS ntStatus = STATUS_SUCCESS;
1042 if( *Length >= sizeof( FILE_INTERNAL_INFORMATION))
1045 Buffer->IndexNumber.HighPart = Fcb->ObjectInformation->FileId.Vnode;
1047 Buffer->IndexNumber.LowPart = Fcb->ObjectInformation->FileId.Unique;
1049 *Length -= sizeof( FILE_INTERNAL_INFORMATION);
1054 ntStatus = STATUS_BUFFER_TOO_SMALL;
1061 AFSQueryEaInfo( IN PIRP Irp,
1062 IN AFSDirectoryCB *DirectoryCB,
1063 IN OUT PFILE_EA_INFORMATION Buffer,
1064 IN OUT PLONG Length)
1067 UNREFERENCED_PARAMETER(Irp);
1068 UNREFERENCED_PARAMETER(DirectoryCB);
1069 NTSTATUS ntStatus = STATUS_SUCCESS;
1071 RtlZeroMemory( Buffer,
1074 if( *Length >= sizeof( FILE_EA_INFORMATION))
1079 *Length -= sizeof( FILE_EA_INFORMATION);
1084 ntStatus = STATUS_BUFFER_TOO_SMALL;
1091 AFSQueryPositionInfo( IN PIRP Irp,
1093 IN OUT PFILE_POSITION_INFORMATION Buffer,
1094 IN OUT PLONG Length)
1097 UNREFERENCED_PARAMETER(Fcb);
1098 NTSTATUS ntStatus = STATUS_SUCCESS;
1099 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1101 if( *Length >= sizeof( FILE_POSITION_INFORMATION))
1104 RtlZeroMemory( Buffer,
1107 Buffer->CurrentByteOffset.QuadPart = pIrpSp->FileObject->CurrentByteOffset.QuadPart;
1109 *Length -= sizeof( FILE_POSITION_INFORMATION);
1114 ntStatus = STATUS_BUFFER_TOO_SMALL;
1121 AFSQueryAccess( IN PIRP Irp,
1123 IN OUT PFILE_ACCESS_INFORMATION Buffer,
1124 IN OUT PLONG Length)
1127 UNREFERENCED_PARAMETER(Irp);
1128 UNREFERENCED_PARAMETER(Fcb);
1129 NTSTATUS ntStatus = STATUS_SUCCESS;
1131 if( *Length >= sizeof( FILE_ACCESS_INFORMATION))
1134 RtlZeroMemory( Buffer,
1137 Buffer->AccessFlags = 0;
1139 *Length -= sizeof( FILE_ACCESS_INFORMATION);
1144 ntStatus = STATUS_BUFFER_TOO_SMALL;
1151 AFSQueryMode( IN PIRP Irp,
1153 IN OUT PFILE_MODE_INFORMATION Buffer,
1154 IN OUT PLONG Length)
1157 UNREFERENCED_PARAMETER(Irp);
1158 UNREFERENCED_PARAMETER(Fcb);
1159 NTSTATUS ntStatus = STATUS_SUCCESS;
1161 if( *Length >= sizeof( FILE_MODE_INFORMATION))
1164 RtlZeroMemory( Buffer,
1169 *Length -= sizeof( FILE_MODE_INFORMATION);
1174 ntStatus = STATUS_BUFFER_TOO_SMALL;
1181 AFSQueryAlignment( IN PIRP Irp,
1183 IN OUT PFILE_ALIGNMENT_INFORMATION Buffer,
1184 IN OUT PLONG Length)
1187 UNREFERENCED_PARAMETER(Irp);
1188 UNREFERENCED_PARAMETER(Fcb);
1189 NTSTATUS ntStatus = STATUS_SUCCESS;
1191 if( *Length >= sizeof( FILE_ALIGNMENT_INFORMATION))
1194 RtlZeroMemory( Buffer,
1197 Buffer->AlignmentRequirement = 1;
1199 *Length -= sizeof( FILE_ALIGNMENT_INFORMATION);
1204 ntStatus = STATUS_BUFFER_TOO_SMALL;
1211 AFSQueryNameInfo( IN PIRP Irp,
1212 IN AFSDirectoryCB *DirectoryCB,
1213 IN OUT PFILE_NAME_INFORMATION Buffer,
1214 IN OUT PLONG Length)
1217 UNREFERENCED_PARAMETER(DirectoryCB);
1218 NTSTATUS ntStatus = STATUS_SUCCESS;
1219 ULONG ulCopyLength = 0;
1220 ULONG cchCopied = 0;
1221 AFSFcb *pFcb = NULL;
1222 AFSCcb *pCcb = NULL;
1223 IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1224 BOOLEAN bAddLeadingSlash = FALSE;
1225 BOOLEAN bAddTrailingSlash = FALSE;
1226 USHORT usFullNameLength = 0;
1228 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
1230 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
1232 if( *Length >= FIELD_OFFSET( FILE_NAME_INFORMATION, FileName))
1235 RtlZeroMemory( Buffer,
1238 if( pCcb->FullFileName.Length == 0 ||
1239 pCcb->FullFileName.Buffer[ 0] != L'\\')
1241 bAddLeadingSlash = TRUE;
1244 if( pFcb->ObjectInformation->FileType == AFS_FILE_TYPE_DIRECTORY &&
1245 pCcb->FullFileName.Length > 0 &&
1246 pCcb->FullFileName.Buffer[ (pCcb->FullFileName.Length/sizeof( WCHAR)) - 1] != L'\\')
1248 bAddTrailingSlash = TRUE;
1251 usFullNameLength = sizeof( WCHAR) +
1252 AFSServerName.Length +
1253 pCcb->FullFileName.Length;
1255 if( bAddLeadingSlash)
1257 usFullNameLength += sizeof( WCHAR);
1260 if( bAddTrailingSlash)
1262 usFullNameLength += sizeof( WCHAR);
1265 if( *Length >= (LONG)(FIELD_OFFSET( FILE_NAME_INFORMATION, FileName) + (LONG)usFullNameLength))
1268 ulCopyLength = (LONG)usFullNameLength;
1273 ulCopyLength = *Length - FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
1275 ntStatus = STATUS_BUFFER_OVERFLOW;
1278 Buffer->FileNameLength = (ULONG)usFullNameLength;
1280 *Length -= FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
1282 if( ulCopyLength > 0)
1285 Buffer->FileName[ 0] = L'\\';
1286 ulCopyLength -= sizeof( WCHAR);
1288 *Length -= sizeof( WCHAR);
1291 if( ulCopyLength >= AFSServerName.Length)
1294 RtlCopyMemory( &Buffer->FileName[ 1],
1295 AFSServerName.Buffer,
1296 AFSServerName.Length);
1298 ulCopyLength -= AFSServerName.Length;
1299 *Length -= AFSServerName.Length;
1300 cchCopied += AFSServerName.Length/sizeof( WCHAR);
1302 if ( ulCopyLength > 0 &&
1306 Buffer->FileName[ cchCopied] = L'\\';
1308 ulCopyLength -= sizeof( WCHAR);
1309 *Length -= sizeof( WCHAR);
1313 if( ulCopyLength >= pCcb->FullFileName.Length)
1316 RtlCopyMemory( &Buffer->FileName[ cchCopied],
1317 pCcb->FullFileName.Buffer,
1318 pCcb->FullFileName.Length);
1320 ulCopyLength -= pCcb->FullFileName.Length;
1321 *Length -= pCcb->FullFileName.Length;
1322 cchCopied += pCcb->FullFileName.Length/sizeof( WCHAR);
1324 if( ulCopyLength > 0 &&
1327 Buffer->FileName[ cchCopied] = L'\\';
1329 *Length -= sizeof( WCHAR);
1335 RtlCopyMemory( &Buffer->FileName[ cchCopied],
1336 pCcb->FullFileName.Buffer,
1339 *Length -= ulCopyLength;
1347 ntStatus = STATUS_BUFFER_TOO_SMALL;
1354 AFSQueryShortNameInfo( IN PIRP Irp,
1355 IN AFSDirectoryCB *DirectoryCB,
1356 IN OUT PFILE_NAME_INFORMATION Buffer,
1357 IN OUT PLONG Length)
1360 UNREFERENCED_PARAMETER(Irp);
1361 NTSTATUS ntStatus = STATUS_BUFFER_TOO_SMALL;
1362 ULONG ulCopyLength = 0;
1364 RtlZeroMemory( Buffer,
1367 if( DirectoryCB->NameInformation.ShortNameLength == 0)
1371 // The short name IS the long name
1374 if( *Length >= (LONG)FIELD_OFFSET( FILE_NAME_INFORMATION, FileName))
1377 if( *Length >= (LONG)(FIELD_OFFSET( FILE_NAME_INFORMATION, FileName) + (LONG)DirectoryCB->NameInformation.FileName.Length))
1380 ulCopyLength = (LONG)DirectoryCB->NameInformation.FileName.Length;
1382 ntStatus = STATUS_SUCCESS;
1387 ulCopyLength = *Length - FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
1389 ntStatus = STATUS_BUFFER_OVERFLOW;
1392 Buffer->FileNameLength = DirectoryCB->NameInformation.FileName.Length;
1394 *Length -= FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
1396 if( ulCopyLength > 0)
1399 RtlCopyMemory( Buffer->FileName,
1400 DirectoryCB->NameInformation.FileName.Buffer,
1403 *Length -= ulCopyLength;
1410 if( *Length >= (LONG)FIELD_OFFSET( FILE_NAME_INFORMATION, FileName))
1413 if( *Length >= (LONG)(FIELD_OFFSET( FILE_NAME_INFORMATION, FileName) + (LONG)DirectoryCB->NameInformation.FileName.Length))
1416 ulCopyLength = (LONG)DirectoryCB->NameInformation.ShortNameLength;
1418 ntStatus = STATUS_SUCCESS;
1423 ulCopyLength = *Length - FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
1425 ntStatus = STATUS_BUFFER_OVERFLOW;
1428 Buffer->FileNameLength = DirectoryCB->NameInformation.ShortNameLength;
1430 *Length -= FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
1432 if( ulCopyLength > 0)
1435 RtlCopyMemory( Buffer->FileName,
1436 DirectoryCB->NameInformation.ShortName,
1437 Buffer->FileNameLength);
1439 *Length -= ulCopyLength;
1448 AFSQueryNetworkInfo( IN PIRP Irp,
1449 IN AFSDirectoryCB *DirectoryCB,
1450 IN OUT PFILE_NETWORK_OPEN_INFORMATION Buffer,
1451 IN OUT PLONG Length)
1454 NTSTATUS ntStatus = STATUS_SUCCESS;
1455 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1456 AFSFcb *pFcb = NULL;
1457 AFSCcb *pCcb = NULL;
1458 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1459 AFSFileInfoCB stFileInfo;
1460 AFSDirectoryCB *pParentDirectoryCB = NULL;
1461 UNICODE_STRING uniParentPath;
1462 ULONG ulFileAttribs = 0;
1464 RtlZeroMemory( Buffer,
1467 if( *Length >= sizeof( FILE_NETWORK_OPEN_INFORMATION))
1470 ulFileAttribs = DirectoryCB->ObjectInformation->FileAttributes;
1472 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
1473 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
1475 if( DirectoryCB->ObjectInformation->FileType == AFS_FILE_TYPE_SYMLINK)
1478 pParentDirectoryCB = AFSGetParentEntry( pCcb->NameArray);
1480 AFSRetrieveParentPath( &pCcb->FullFileName,
1483 RtlZeroMemory( &stFileInfo,
1484 sizeof( AFSFileInfoCB));
1487 // Can't hold the Fcb while evaluating the path, leads to lock inversion
1490 AFSReleaseResource( &pFcb->NPFcb->Resource);
1493 // Its a reparse point regardless of whether the file attributes
1494 // can be retrieved for the target.
1497 if ( ulFileAttribs == FILE_ATTRIBUTE_NORMAL)
1500 ulFileAttribs = FILE_ATTRIBUTE_REPARSE_POINT;
1505 ulFileAttribs |= FILE_ATTRIBUTE_REPARSE_POINT;
1508 if( NT_SUCCESS( AFSRetrieveFileAttributes( pParentDirectoryCB,
1516 if ( stFileInfo.FileAttributes & FILE_ATTRIBUTE_DIRECTORY)
1519 ulFileAttribs |= FILE_ATTRIBUTE_DIRECTORY;
1523 AFSAcquireShared( &pFcb->NPFcb->Resource,
1527 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1528 AFS_TRACE_LEVEL_VERBOSE_2,
1529 "AFSQueryNetworkInfo %wZ Type 0x%x Attrib 0x%x -> 0x%x\n",
1530 &pCcb->DirectoryCB->NameInformation.FileName,
1531 pFcb->ObjectInformation->FileType,
1532 pFcb->ObjectInformation->FileAttributes,
1535 Buffer->CreationTime.QuadPart = DirectoryCB->ObjectInformation->CreationTime.QuadPart;
1536 Buffer->LastAccessTime.QuadPart = DirectoryCB->ObjectInformation->LastAccessTime.QuadPart;
1537 Buffer->LastWriteTime.QuadPart = DirectoryCB->ObjectInformation->LastWriteTime.QuadPart;
1538 Buffer->ChangeTime.QuadPart = DirectoryCB->ObjectInformation->ChangeTime.QuadPart;
1540 Buffer->AllocationSize.QuadPart = DirectoryCB->ObjectInformation->AllocationSize.QuadPart;
1541 Buffer->EndOfFile.QuadPart = DirectoryCB->ObjectInformation->EndOfFile.QuadPart;
1543 Buffer->FileAttributes = ulFileAttribs;
1545 if( DirectoryCB->NameInformation.FileName.Buffer[ 0] == L'.' &&
1546 BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_HIDE_DOT_NAMES))
1549 if ( Buffer->FileAttributes != FILE_ATTRIBUTE_NORMAL)
1552 Buffer->FileAttributes |= FILE_ATTRIBUTE_HIDDEN;
1557 Buffer->FileAttributes = FILE_ATTRIBUTE_HIDDEN;
1561 *Length -= sizeof( FILE_NETWORK_OPEN_INFORMATION);
1566 ntStatus = STATUS_BUFFER_TOO_SMALL;
1573 AFSQueryStreamInfo( IN PIRP Irp,
1574 IN AFSDirectoryCB *DirectoryCB,
1575 IN OUT FILE_STREAM_INFORMATION *Buffer,
1576 IN OUT PLONG Length)
1579 UNREFERENCED_PARAMETER(Irp);
1580 NTSTATUS ntStatus = STATUS_BUFFER_TOO_SMALL;
1581 ULONG ulCopyLength = 0;
1583 if( *Length >= FIELD_OFFSET( FILE_STREAM_INFORMATION, StreamName))
1586 RtlZeroMemory( Buffer,
1589 Buffer->NextEntryOffset = 0;
1592 if( !BooleanFlagOn( DirectoryCB->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_DIRECTORY))
1595 if( *Length >= (LONG)(FIELD_OFFSET( FILE_STREAM_INFORMATION, StreamName) + 14)) // ::$DATA
1600 ntStatus = STATUS_SUCCESS;
1605 ulCopyLength = *Length - FIELD_OFFSET( FILE_STREAM_INFORMATION, StreamName);
1607 ntStatus = STATUS_BUFFER_OVERFLOW;
1610 Buffer->StreamNameLength = 14; // ::$DATA
1612 Buffer->StreamSize.QuadPart = DirectoryCB->ObjectInformation->EndOfFile.QuadPart;
1614 Buffer->StreamAllocationSize.QuadPart = DirectoryCB->ObjectInformation->AllocationSize.QuadPart;
1616 *Length -= FIELD_OFFSET( FILE_STREAM_INFORMATION, StreamName);
1618 if( ulCopyLength > 0)
1621 RtlCopyMemory( Buffer->StreamName,
1625 *Length -= ulCopyLength;
1631 Buffer->StreamNameLength = 0; // No stream for a directory
1633 // The response size is zero
1635 ntStatus = STATUS_SUCCESS;
1643 AFSQueryAttribTagInfo( IN PIRP Irp,
1644 IN AFSDirectoryCB *DirectoryCB,
1645 IN OUT FILE_ATTRIBUTE_TAG_INFORMATION *Buffer,
1646 IN OUT PLONG Length)
1649 NTSTATUS ntStatus = STATUS_BUFFER_TOO_SMALL;
1650 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1651 AFSFcb *pFcb = NULL;
1652 AFSCcb *pCcb = NULL;
1653 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1654 AFSFileInfoCB stFileInfo;
1655 AFSDirectoryCB *pParentDirectoryCB = NULL;
1656 UNICODE_STRING uniParentPath;
1657 ULONG ulFileAttribs = 0;
1659 if( *Length >= sizeof( FILE_ATTRIBUTE_TAG_INFORMATION))
1662 RtlZeroMemory( Buffer,
1665 ulFileAttribs = DirectoryCB->ObjectInformation->FileAttributes;
1667 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
1668 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
1670 if( DirectoryCB->ObjectInformation->FileType == AFS_FILE_TYPE_SYMLINK)
1673 pParentDirectoryCB = AFSGetParentEntry( pCcb->NameArray);
1675 AFSRetrieveParentPath( &pCcb->FullFileName,
1678 RtlZeroMemory( &stFileInfo,
1679 sizeof( AFSFileInfoCB));
1682 // Can't hold the Fcb while evaluating the path, leads to lock inversion
1685 AFSReleaseResource( &pFcb->NPFcb->Resource);
1688 // Its a reparse point regardless of whether the file attributes
1689 // can be retrieved for the target.
1692 if ( ulFileAttribs == FILE_ATTRIBUTE_NORMAL)
1695 ulFileAttribs = FILE_ATTRIBUTE_REPARSE_POINT;
1700 ulFileAttribs |= FILE_ATTRIBUTE_REPARSE_POINT;
1703 if( NT_SUCCESS( AFSRetrieveFileAttributes( pParentDirectoryCB,
1711 if ( stFileInfo.FileAttributes & FILE_ATTRIBUTE_DIRECTORY)
1714 ulFileAttribs |= FILE_ATTRIBUTE_DIRECTORY;
1718 AFSAcquireShared( &pFcb->NPFcb->Resource,
1722 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1723 AFS_TRACE_LEVEL_VERBOSE_2,
1724 "AFSAttribTagInfo %wZ Type 0x%x Attrib 0x%x -> 0x%x\n",
1725 &pCcb->DirectoryCB->NameInformation.FileName,
1726 pFcb->ObjectInformation->FileType,
1727 pFcb->ObjectInformation->FileAttributes,
1730 Buffer->FileAttributes = ulFileAttribs;
1732 if( DirectoryCB->NameInformation.FileName.Buffer[ 0] == L'.' &&
1733 BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_HIDE_DOT_NAMES))
1736 if ( Buffer->FileAttributes != FILE_ATTRIBUTE_NORMAL)
1739 Buffer->FileAttributes |= FILE_ATTRIBUTE_HIDDEN;
1744 Buffer->FileAttributes = FILE_ATTRIBUTE_HIDDEN;
1748 if ( DirectoryCB->ObjectInformation->FileType == AFS_FILE_TYPE_MOUNTPOINT)
1751 Buffer->ReparseTag = IO_REPARSE_TAG_SURROGATE|IO_REPARSE_TAG_OPENAFS_DFS;
1753 else if( BooleanFlagOn( DirectoryCB->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_REPARSE_POINT))
1756 Buffer->ReparseTag = IO_REPARSE_TAG_SYMLINK;
1759 *Length -= sizeof( FILE_ATTRIBUTE_TAG_INFORMATION);
1761 ntStatus = STATUS_SUCCESS;
1768 AFSQueryRemoteProtocolInfo( IN PIRP Irp,
1769 IN AFSDirectoryCB *DirectoryCB,
1770 IN OUT FILE_REMOTE_PROTOCOL_INFORMATION *Buffer,
1771 IN OUT PLONG Length)
1774 UNREFERENCED_PARAMETER(Irp);
1775 UNREFERENCED_PARAMETER(DirectoryCB);
1776 NTSTATUS ntStatus = STATUS_BUFFER_TOO_SMALL;
1778 if( *Length >= sizeof( FILE_REMOTE_PROTOCOL_INFORMATION))
1781 RtlZeroMemory( Buffer,
1784 Buffer->StructureVersion = 1;
1786 Buffer->StructureSize = sizeof(FILE_REMOTE_PROTOCOL_INFORMATION);
1788 Buffer->Protocol = WNNC_NET_OPENAFS;
1790 Buffer->ProtocolMajorVersion = 3;
1792 Buffer->ProtocolMinorVersion = 0;
1794 Buffer->ProtocolRevision = 0;
1796 *Length -= sizeof( FILE_REMOTE_PROTOCOL_INFORMATION);
1798 ntStatus = STATUS_SUCCESS;
1805 AFSQueryPhysicalNameInfo( IN PIRP Irp,
1806 IN AFSDirectoryCB *DirectoryCB,
1807 IN OUT PFILE_NETWORK_PHYSICAL_NAME_INFORMATION Buffer,
1808 IN OUT PLONG Length)
1811 UNREFERENCED_PARAMETER(DirectoryCB);
1812 NTSTATUS ntStatus = STATUS_SUCCESS;
1813 ULONG ulCopyLength = 0;
1814 ULONG cchCopied = 0;
1815 AFSFcb *pFcb = NULL;
1816 AFSCcb *pCcb = NULL;
1817 IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1818 BOOLEAN bAddLeadingSlash = FALSE;
1819 USHORT usFullNameLength = 0;
1821 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
1823 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
1825 if( *Length >= FIELD_OFFSET( FILE_NETWORK_PHYSICAL_NAME_INFORMATION, FileName))
1828 RtlZeroMemory( Buffer,
1831 if( pCcb->FullFileName.Length == 0 ||
1832 pCcb->FullFileName.Buffer[ 0] != L'\\')
1834 bAddLeadingSlash = TRUE;
1837 usFullNameLength = pCcb->FullFileName.Length;
1839 if( bAddLeadingSlash)
1841 usFullNameLength += sizeof( WCHAR);
1844 if( *Length >= (LONG)(FIELD_OFFSET( FILE_NETWORK_PHYSICAL_NAME_INFORMATION, FileName) + (LONG)usFullNameLength))
1846 ulCopyLength = (LONG)usFullNameLength;
1851 ulCopyLength = *Length - FIELD_OFFSET( FILE_NETWORK_PHYSICAL_NAME_INFORMATION, FileName);
1853 ntStatus = STATUS_BUFFER_OVERFLOW;
1856 Buffer->FileNameLength = (ULONG)usFullNameLength;
1858 *Length -= FIELD_OFFSET( FILE_NETWORK_PHYSICAL_NAME_INFORMATION, FileName);
1860 if( ulCopyLength > 0)
1863 if( bAddLeadingSlash)
1866 Buffer->FileName[ cchCopied] = L'\\';
1868 ulCopyLength -= sizeof( WCHAR);
1869 *Length -= sizeof( WCHAR);
1873 if( ulCopyLength >= pCcb->FullFileName.Length)
1876 RtlCopyMemory( &Buffer->FileName[ cchCopied],
1877 pCcb->FullFileName.Buffer,
1878 pCcb->FullFileName.Length);
1880 ulCopyLength -= pCcb->FullFileName.Length;
1881 *Length -= pCcb->FullFileName.Length;
1882 cchCopied += pCcb->FullFileName.Length/sizeof( WCHAR);
1887 RtlCopyMemory( &Buffer->FileName[ cchCopied],
1888 pCcb->FullFileName.Buffer,
1891 *Length -= ulCopyLength;
1898 ntStatus = STATUS_BUFFER_TOO_SMALL;
1905 AFSSetBasicInfo( IN PIRP Irp,
1906 IN AFSDirectoryCB *DirectoryCB)
1908 NTSTATUS ntStatus = STATUS_SUCCESS;
1909 PFILE_BASIC_INFORMATION pBuffer;
1910 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1911 ULONG ulNotifyFilter = 0;
1912 AFSCcb *pCcb = NULL;
1917 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
1919 pBuffer = (PFILE_BASIC_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
1921 pCcb->FileUnwindInfo.FileAttributes = (ULONG)-1;
1923 if( pBuffer->FileAttributes != (ULONGLONG)0)
1926 if( DirectoryCB->ObjectInformation->Fcb->Header.NodeTypeCode == AFS_FILE_FCB &&
1927 BooleanFlagOn( pBuffer->FileAttributes, FILE_ATTRIBUTE_DIRECTORY))
1930 try_return( ntStatus = STATUS_INVALID_PARAMETER);
1933 if( DirectoryCB->ObjectInformation->Fcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB)
1936 pBuffer->FileAttributes |= FILE_ATTRIBUTE_DIRECTORY;
1939 pCcb->FileUnwindInfo.FileAttributes = DirectoryCB->ObjectInformation->FileAttributes;
1941 DirectoryCB->ObjectInformation->FileAttributes = pBuffer->FileAttributes;
1943 ulNotifyFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
1945 SetFlag( DirectoryCB->ObjectInformation->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED);
1948 pCcb->FileUnwindInfo.CreationTime.QuadPart = (ULONGLONG)-1;
1950 if( pBuffer->CreationTime.QuadPart != (ULONGLONG)-1 &&
1951 pBuffer->CreationTime.QuadPart != (ULONGLONG)0)
1954 pCcb->FileUnwindInfo.CreationTime.QuadPart = DirectoryCB->ObjectInformation->CreationTime.QuadPart;
1956 DirectoryCB->ObjectInformation->CreationTime.QuadPart = pBuffer->CreationTime.QuadPart;
1958 ulNotifyFilter |= FILE_NOTIFY_CHANGE_CREATION;
1960 SetFlag( DirectoryCB->ObjectInformation->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_CREATE_TIME);
1963 pCcb->FileUnwindInfo.LastAccessTime.QuadPart = (ULONGLONG)-1;
1965 if( pBuffer->LastAccessTime.QuadPart != (ULONGLONG)-1 &&
1966 pBuffer->LastAccessTime.QuadPart != (ULONGLONG)0)
1969 pCcb->FileUnwindInfo.LastAccessTime.QuadPart = DirectoryCB->ObjectInformation->LastAccessTime.QuadPart;
1971 DirectoryCB->ObjectInformation->LastAccessTime.QuadPart = pBuffer->LastAccessTime.QuadPart;
1973 ulNotifyFilter |= FILE_NOTIFY_CHANGE_LAST_ACCESS;
1975 SetFlag( DirectoryCB->ObjectInformation->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_ACCESS_TIME);
1978 pCcb->FileUnwindInfo.LastWriteTime.QuadPart = (ULONGLONG)-1;
1980 if( pBuffer->LastWriteTime.QuadPart != (ULONGLONG)-1 &&
1981 pBuffer->LastWriteTime.QuadPart != (ULONGLONG)0)
1984 pCcb->FileUnwindInfo.LastWriteTime.QuadPart = DirectoryCB->ObjectInformation->LastWriteTime.QuadPart;
1986 DirectoryCB->ObjectInformation->LastWriteTime.QuadPart = pBuffer->LastWriteTime.QuadPart;
1988 ulNotifyFilter |= FILE_NOTIFY_CHANGE_LAST_WRITE;
1990 SetFlag( DirectoryCB->ObjectInformation->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_LAST_WRITE_TIME);
1993 pCcb->FileUnwindInfo.ChangeTime.QuadPart = (ULONGLONG)-1;
1995 if( pBuffer->ChangeTime.QuadPart != (ULONGLONG)-1 &&
1996 pBuffer->ChangeTime.QuadPart != (ULONGLONG)0)
1999 pCcb->FileUnwindInfo.ChangeTime.QuadPart = DirectoryCB->ObjectInformation->ChangeTime.QuadPart;
2001 DirectoryCB->ObjectInformation->ChangeTime.QuadPart = pBuffer->ChangeTime.QuadPart;
2003 ulNotifyFilter |= FILE_NOTIFY_CHANGE_LAST_ACCESS;
2005 SetFlag( DirectoryCB->ObjectInformation->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_CHANGE_TIME);
2008 if( ulNotifyFilter > 0)
2011 if( BooleanFlagOn( DirectoryCB->ObjectInformation->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
2014 AFSObjectInfoCB * pParentObjectInfo = AFSFindObjectInfo( DirectoryCB->ObjectInformation->VolumeCB,
2015 &DirectoryCB->ObjectInformation->ParentFileId,
2018 if ( pParentObjectInfo != NULL)
2020 AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
2022 (ULONG)ulNotifyFilter,
2023 (ULONG)FILE_ACTION_MODIFIED);
2025 AFSReleaseObjectInfo( &pParentObjectInfo);
2039 AFSSetDispositionInfo( IN PIRP Irp,
2040 IN AFSDirectoryCB *DirectoryCB)
2042 NTSTATUS ntStatus = STATUS_SUCCESS;
2043 PFILE_DISPOSITION_INFORMATION pBuffer;
2044 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2045 AFSFcb *pFcb = NULL;
2046 AFSCcb *pCcb = NULL;
2051 pBuffer = (PFILE_DISPOSITION_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
2053 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
2055 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
2058 // Can't delete the root
2061 if( pFcb->Header.NodeTypeCode == AFS_ROOT_FCB)
2064 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2065 AFS_TRACE_LEVEL_ERROR,
2066 "AFSSetDispositionInfo Attempt to delete root entry\n"));
2068 try_return( ntStatus = STATUS_CANNOT_DELETE);
2072 // If the file is read only then do not allow the delete
2075 if( BooleanFlagOn( DirectoryCB->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_READONLY))
2078 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2079 AFS_TRACE_LEVEL_ERROR,
2080 "AFSSetDispositionInfo Attempt to delete read only entry %wZ\n",
2081 &DirectoryCB->NameInformation.FileName));
2083 try_return( ntStatus = STATUS_CANNOT_DELETE);
2086 if( pBuffer->DeleteFile)
2090 // Check if the caller can delete the file
2093 ntStatus = AFSNotifyDelete( DirectoryCB,
2097 if( !NT_SUCCESS( ntStatus))
2100 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2101 AFS_TRACE_LEVEL_ERROR,
2102 "AFSSetDispositionInfo Cannot delete entry %wZ Status %08lX\n",
2103 &DirectoryCB->NameInformation.FileName,
2106 try_return( ntStatus);
2109 if( pFcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB)
2113 // Reduce the Link count in the object information block
2114 // to correspond with the deletion of the directory entry.
2117 pFcb->ObjectInformation->Links--;
2120 // Check if this is a directory that there are not currently other opens
2123 if( pFcb->ObjectInformation->Specific.Directory.ChildOpenHandleCount > 0)
2126 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2127 AFS_TRACE_LEVEL_ERROR,
2128 "AFSSetDispositionInfo Attempt to delete directory %wZ with open %u handles\n",
2129 &DirectoryCB->NameInformation.FileName,
2130 pFcb->ObjectInformation->Specific.Directory.ChildOpenHandleCount));
2132 try_return( ntStatus = STATUS_DIRECTORY_NOT_EMPTY);
2136 // Make sure the directory is enumerated before checking to see if it is empty.
2139 if( !BooleanFlagOn( pFcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
2142 AFSAcquireExcl( pFcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
2145 if( !BooleanFlagOn( pFcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
2148 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2149 AFS_TRACE_LEVEL_VERBOSE,
2150 "AFSSetDispositionInfo Enumerating parent FID %08lX-%08lX-%08lX-%08lX\n",
2151 pFcb->ObjectInformation->FileId.Cell,
2152 pFcb->ObjectInformation->FileId.Volume,
2153 pFcb->ObjectInformation->FileId.Vnode,
2154 pFcb->ObjectInformation->FileId.Unique));
2156 ntStatus = AFSEnumerateDirectory( &pCcb->AuthGroup,
2157 pFcb->ObjectInformation,
2160 if( !NT_SUCCESS( ntStatus))
2163 AFSReleaseResource( pFcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
2165 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2166 AFS_TRACE_LEVEL_ERROR,
2167 "AFSSetDispositionInfo Failed to enumerate parent FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
2168 pFcb->ObjectInformation->FileId.Cell,
2169 pFcb->ObjectInformation->FileId.Volume,
2170 pFcb->ObjectInformation->FileId.Vnode,
2171 pFcb->ObjectInformation->FileId.Unique,
2174 try_return( ntStatus);
2178 AFSReleaseResource( pFcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
2181 if( !AFSIsDirectoryEmptyForDelete( pFcb))
2184 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2185 AFS_TRACE_LEVEL_ERROR,
2186 "AFSSetDispositionInfo Attempt to delete non-empty directory %wZ\n",
2187 &DirectoryCB->NameInformation.FileName));
2189 try_return( ntStatus = STATUS_DIRECTORY_NOT_EMPTY);
2192 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2193 AFS_TRACE_LEVEL_VERBOSE,
2194 "AFSSetDispositionInfo Setting PENDING_DELETE on DirEntry %p Name %wZ\n",
2196 &DirectoryCB->NameInformation.FileName));
2198 SetFlag( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
2200 else if( pFcb->Header.NodeTypeCode == AFS_FILE_FCB)
2204 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
2205 AFS_TRACE_LEVEL_VERBOSE,
2206 "AFSSetDispositionInfo Acquiring Fcb lock %p EXCL %08lX\n",
2207 &pFcb->NPFcb->Resource,
2208 PsGetCurrentThread()));
2210 AFSAcquireExcl( &pFcb->NPFcb->Resource,
2213 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
2214 AFS_TRACE_LEVEL_VERBOSE,
2215 "AFSSetDispositionInfo Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
2216 &pFcb->NPFcb->SectionObjectResource,
2217 PsGetCurrentThread()));
2219 AFSAcquireExcl( &pFcb->NPFcb->SectionObjectResource,
2226 // Attempt to flush any outstanding data
2229 bMmFlushed = MmFlushImageSection( &pFcb->NPFcb->SectionObjectPointers,
2236 // Set PENDING_DELETE before CcPurgeCacheSection to avoid a
2237 // deadlock with Trend Micro's Enterprise anti-virus product
2238 // which attempts to open the file which is being deleted.
2241 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2242 AFS_TRACE_LEVEL_VERBOSE,
2243 "AFSSetDispositionInfo Setting PENDING_DELETE on DirEntry %p Name %wZ\n",
2245 &DirectoryCB->NameInformation.FileName));
2247 SetFlag( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
2250 // Purge the cache as well
2253 if( pFcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
2256 if ( !CcPurgeCacheSection( &pFcb->NPFcb->SectionObjectPointers,
2262 SetFlag( pFcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
2267 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
2272 ntStatus = GetExceptionCode();
2276 "EXCEPTION - AFSSetDispositionInfo MmFlushImageSection failed FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
2277 pFcb->ObjectInformation->FileId.Cell,
2278 pFcb->ObjectInformation->FileId.Volume,
2279 pFcb->ObjectInformation->FileId.Vnode,
2280 pFcb->ObjectInformation->FileId.Unique,
2284 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
2285 AFS_TRACE_LEVEL_VERBOSE,
2286 "AFSSetDispositionInfo Releasing Fcb SectionObject lock %p EXCL %08lX\n",
2287 &pFcb->NPFcb->SectionObjectResource,
2288 PsGetCurrentThread()));
2290 AFSReleaseResource( &pFcb->NPFcb->SectionObjectResource);
2292 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
2293 AFS_TRACE_LEVEL_VERBOSE,
2294 "AFSSetDispositionInfo Releasing Fcb lock %p EXCL %08lX\n",
2295 &pFcb->NPFcb->Resource,
2296 PsGetCurrentThread()));
2298 AFSReleaseResource( &pFcb->NPFcb->Resource);
2303 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2304 AFS_TRACE_LEVEL_ERROR,
2305 "AFSSetDispositionInfo Failed to flush image section for delete Entry %wZ\n",
2306 &DirectoryCB->NameInformation.FileName));
2308 try_return( ntStatus = STATUS_CANNOT_DELETE);
2311 else if( pFcb->Header.NodeTypeCode == AFS_SYMBOLIC_LINK_FCB ||
2312 pFcb->Header.NodeTypeCode == AFS_MOUNT_POINT_FCB ||
2313 pFcb->Header.NodeTypeCode == AFS_DFS_LINK_FCB ||
2314 pFcb->Header.NodeTypeCode == AFS_INVALID_FCB)
2317 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2318 AFS_TRACE_LEVEL_VERBOSE,
2319 "AFSSetDispositionInfo Setting PENDING_DELETE on DirEntry %p Name %wZ\n",
2321 &DirectoryCB->NameInformation.FileName));
2323 SetFlag( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
2329 ClearFlag( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
2333 // OK, should be good to go, set the flag in the file object
2336 pIrpSp->FileObject->DeletePending = pBuffer->DeleteFile;
2347 AFSSetFileLinkInfo( IN PIRP Irp)
2350 NTSTATUS ntStatus = STATUS_SUCCESS;
2351 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
2352 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2353 PFILE_LINK_INFORMATION pFileLinkInfo = NULL;
2354 PFILE_OBJECT pSrcFileObj = NULL;
2355 PFILE_OBJECT pTargetFileObj = pIrpSp->Parameters.SetFile.FileObject;
2356 AFSFcb *pSrcFcb = NULL, *pTargetDcb = NULL;
2357 AFSCcb *pSrcCcb = NULL, *pTargetDirCcb = NULL;
2358 AFSObjectInfoCB *pSrcObject = NULL;
2359 AFSObjectInfoCB *pSrcParentObject = NULL, *pTargetParentObject = NULL;
2360 UNICODE_STRING uniSourceName, uniTargetName;
2361 UNICODE_STRING uniFullTargetName, uniTargetParentName;
2362 BOOLEAN bCommonParent = FALSE;
2363 AFSDirectoryCB *pTargetDirEntry = NULL;
2364 AFSDirectoryCB *pNewTargetDirEntry = NULL;
2366 BOOLEAN bTargetEntryExists = FALSE;
2368 BOOLEAN bReleaseTargetDirLock = FALSE;
2369 ULONG ulNotificationAction = 0, ulNotifyFilter = 0;
2374 pSrcFileObj = pIrpSp->FileObject;
2376 pSrcFcb = (AFSFcb *)pSrcFileObj->FsContext;
2377 pSrcCcb = (AFSCcb *)pSrcFileObj->FsContext2;
2379 pSrcObject = pSrcFcb->ObjectInformation;
2381 if ( BooleanFlagOn( pSrcObject->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
2384 pSrcParentObject = AFSFindObjectInfo( pSrcObject->VolumeCB,
2385 &pSrcObject->ParentFileId,
2389 if( pSrcParentObject == NULL)
2392 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2393 AFS_TRACE_LEVEL_ERROR,
2394 "AFSSetFileLinkInfo Unable to resolve SrcParentObject (INVALID_PARAMETER)\n"));
2398 try_return( ntStatus = STATUS_INVALID_PARAMETER);
2401 pFileLinkInfo = (PFILE_LINK_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
2404 // Perform some basic checks to ensure FS integrity
2407 if( pSrcFcb->Header.NodeTypeCode != AFS_FILE_FCB)
2410 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2411 AFS_TRACE_LEVEL_ERROR,
2412 "AFSSetFileLinkInfo Attempt to non-file (INVALID_PARAMETER)\n"));
2414 try_return( ntStatus = STATUS_INVALID_PARAMETER);
2417 if( pTargetFileObj == NULL)
2420 if ( pFileLinkInfo->RootDirectory)
2424 // The target directory is provided by HANDLE
2425 // RootDirectory is only set when the target directory is not the same
2426 // as the source directory.
2428 // AFS only supports hard links within a single directory.
2430 // The IOManager should translate any Handle to a FileObject for us.
2431 // However, the failure to receive a FileObject is treated as a fatal
2435 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2436 AFS_TRACE_LEVEL_ERROR,
2437 "AFSSetFileLinkInfo Attempt to link %wZ to alternate directory by handle INVALID_PARAMETER\n",
2438 &pSrcCcb->DirectoryCB->NameInformation.FileName));
2440 try_return( ntStatus = STATUS_INVALID_PARAMETER);
2445 uniFullTargetName.Length = (USHORT)pFileLinkInfo->FileNameLength;
2447 uniFullTargetName.Buffer = (PWSTR)&pFileLinkInfo->FileName;
2449 AFSRetrieveFinalComponent( &uniFullTargetName,
2452 AFSRetrieveParentPath( &uniFullTargetName,
2453 &uniTargetParentName);
2455 if ( uniTargetParentName.Length == 0)
2459 // This is a simple rename. Here the target directory is the same as the source parent directory
2460 // and the name is retrieved from the system buffer information
2463 pTargetParentObject = pSrcParentObject;
2468 // uniTargetParentName contains the directory the renamed object
2469 // will be moved to. Must obtain the TargetParentObject.
2472 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2473 AFS_TRACE_LEVEL_ERROR,
2474 "AFSSetFileLinkInfo Attempt to link %wZ to alternate directory %wZ (NOT_SAME_DEVICE)\n",
2475 &pSrcCcb->DirectoryCB->NameInformation.FileName,
2476 &uniFullTargetName));
2478 try_return( ntStatus = STATUS_NOT_SAME_DEVICE);
2482 pTargetDcb = pTargetParentObject->Fcb;
2488 // So here we have the target directory taken from the targetfile object
2491 pTargetDcb = (AFSFcb *)pTargetFileObj->FsContext;
2493 pTargetDirCcb = (AFSCcb *)pTargetFileObj->FsContext2;
2495 pTargetParentObject = (AFSObjectInfoCB *)pTargetDcb->ObjectInformation;
2498 // Grab the target name which we setup in the IRP_MJ_CREATE handler. By how we set this up
2499 // it is only the target component of the rename operation
2502 uniTargetName = *((PUNICODE_STRING)&pTargetFileObj->FileName);
2506 // The quick check to see if they are self linking.
2507 // Do the names match? Only do this where the parent directories are
2511 if( pTargetParentObject == pSrcParentObject)
2514 if( FsRtlAreNamesEqual( &uniTargetName,
2519 try_return( ntStatus = STATUS_SUCCESS);
2522 bCommonParent = TRUE;
2528 // We do not allow cross-volume hard links
2531 if( pTargetParentObject->VolumeCB != pSrcObject->VolumeCB)
2534 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2535 AFS_TRACE_LEVEL_ERROR,
2536 "AFSSetFileLinkInfo Attempt to link to different volume %wZ\n",
2537 &pSrcCcb->DirectoryCB->NameInformation.FileName));
2539 try_return( ntStatus = STATUS_NOT_SAME_DEVICE);
2543 ulTargetCRC = AFSGenerateCRC( &uniTargetName,
2546 AFSAcquireExcl( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock,
2549 bReleaseTargetDirLock = TRUE;
2551 AFSLocateCaseSensitiveDirEntry( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
2555 if( pTargetDirEntry == NULL)
2559 // Missed so perform a case insensitive lookup
2562 ulTargetCRC = AFSGenerateCRC( &uniTargetName,
2565 AFSLocateCaseInsensitiveDirEntry( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
2570 if ( !BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
2571 pTargetDirEntry == NULL && RtlIsNameLegalDOS8Dot3( &uniTargetName,
2576 // Try the short name
2578 AFSLocateShortNameDirEntry( pTargetParentObject->Specific.Directory.ShortNameTree,
2584 // Increment our ref count on the dir entry
2587 if( pTargetDirEntry != NULL)
2590 ASSERT( BooleanFlagOn( pTargetDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_PARENT_FID) &&
2591 AFSIsEqualFID( &pTargetParentObject->FileId, &pTargetDirEntry->ObjectInformation->ParentFileId));
2593 lCount = InterlockedIncrement( &pTargetDirEntry->DirOpenReferenceCount);
2595 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2596 AFS_TRACE_LEVEL_VERBOSE,
2597 "AFSSetFileLinkInfo Increment count on %wZ DE %p Ccb %p Cnt %d\n",
2598 &pTargetDirEntry->NameInformation.FileName,
2603 ASSERT( lCount >= 0);
2605 if( !pFileLinkInfo->ReplaceIfExists)
2608 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2609 AFS_TRACE_LEVEL_ERROR,
2610 "AFSSetFileLinkInfo Attempt to link with target collision %wZ Target %wZ\n",
2611 &pSrcCcb->DirectoryCB->NameInformation.FileName,
2612 &pTargetDirEntry->NameInformation.FileName));
2614 try_return( ntStatus = STATUS_OBJECT_NAME_COLLISION);
2617 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING | AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2618 AFS_TRACE_LEVEL_ERROR,
2619 "AFSSetFileLinkInfo Target %wZ exists DE %p Count %d, performing delete of target\n",
2620 &pTargetDirEntry->NameInformation.FileName,
2625 // Pull the directory entry from the parent
2628 AFSRemoveDirNodeFromParent( pTargetParentObject,
2632 bTargetEntryExists = TRUE;
2636 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2637 AFS_TRACE_LEVEL_VERBOSE,
2638 "AFSSetFileLinkInfo Target does NOT exist, normal linking\n"));
2642 // OK, this is a simple rename. Issue the rename
2643 // request to the service.
2646 ntStatus = AFSNotifyHardLink( pSrcObject,
2647 &pSrcCcb->AuthGroup,
2649 pTargetDcb->ObjectInformation,
2650 pSrcCcb->DirectoryCB,
2652 pFileLinkInfo->ReplaceIfExists,
2653 &pNewTargetDirEntry);
2655 if( ntStatus != STATUS_REPARSE &&
2656 !NT_SUCCESS( ntStatus))
2659 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2660 AFS_TRACE_LEVEL_ERROR,
2661 "AFSSetFileLinkInfo Failed link of %wZ to target %wZ Status %08lX\n",
2662 &pSrcCcb->DirectoryCB->NameInformation.FileName,
2666 try_return( ntStatus);
2669 if ( ntStatus != STATUS_REPARSE)
2672 AFSInsertDirectoryNode( pTargetDcb->ObjectInformation,
2678 // Send notification for the target link file
2681 if( bTargetEntryExists || pNewTargetDirEntry)
2684 ulNotificationAction = FILE_ACTION_MODIFIED;
2689 ulNotificationAction = FILE_ACTION_ADDED;
2692 AFSFsRtlNotifyFullReportChange( pTargetParentObject,
2694 (ULONG)ulNotifyFilter,
2695 (ULONG)ulNotificationAction);
2699 if( !NT_SUCCESS( ntStatus))
2702 if( bTargetEntryExists)
2705 AFSInsertDirectoryNode( pTargetParentObject,
2711 if( pTargetDirEntry != NULL)
2715 // Release DirOpenReferenceCount obtained above
2718 lCount = InterlockedDecrement( &pTargetDirEntry->DirOpenReferenceCount);
2720 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2721 AFS_TRACE_LEVEL_VERBOSE,
2722 "AFSSetFileLinkInfo Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
2723 &pTargetDirEntry->NameInformation.FileName,
2728 ASSERT( lCount >= 0);
2731 if( pNewTargetDirEntry != NULL)
2735 // Release DirOpenReferenceCount obtained from AFSNotifyHardLink
2738 lCount = InterlockedDecrement( &pNewTargetDirEntry->DirOpenReferenceCount);
2740 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2741 AFS_TRACE_LEVEL_VERBOSE,
2742 "AFSSetFileLinkInfo Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
2743 &pNewTargetDirEntry->NameInformation.FileName,
2748 ASSERT( lCount >= 0);
2751 if( bReleaseTargetDirLock)
2754 AFSReleaseResource( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
2757 if ( pSrcParentObject != NULL)
2760 AFSReleaseObjectInfo( &pSrcParentObject);
2764 // No need to release pTargetParentObject as it is either a copy of pSrcParentObject
2765 // or (AFSFcb *)pTargetFileObj->FsContext->ObjectInformation
2768 pTargetParentObject = NULL;
2775 AFSSetRenameInfo( IN PIRP Irp)
2778 NTSTATUS ntStatus = STATUS_SUCCESS;
2779 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
2780 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2781 AFSFcb *pSrcFcb = NULL, *pTargetDcb = NULL, *pTargetFcb = NULL;
2782 AFSCcb *pSrcCcb = NULL, *pTargetDirCcb = NULL;
2783 PFILE_OBJECT pSrcFileObj = pIrpSp->FileObject;
2784 PFILE_OBJECT pTargetFileObj = pIrpSp->Parameters.SetFile.FileObject;
2785 PFILE_OBJECT pTargetParentFileObj = NULL;
2786 PFILE_RENAME_INFORMATION pRenameInfo = NULL;
2787 UNICODE_STRING uniTargetName, uniSourceName, uniTargetParentName;
2788 BOOLEAN bReplaceIfExists = FALSE;
2789 UNICODE_STRING uniShortName;
2790 AFSDirectoryCB *pTargetDirEntry = NULL;
2791 ULONG ulTargetCRC = 0;
2792 BOOLEAN bTargetEntryExists = FALSE;
2793 AFSObjectInfoCB *pSrcObject = NULL;
2794 AFSObjectInfoCB *pSrcParentObject = NULL, *pTargetParentObject = NULL;
2796 ULONG ulNotificationAction = 0, ulNotifyFilter = 0;
2797 UNICODE_STRING uniFullTargetName;
2798 BOOLEAN bCommonParent = FALSE;
2799 BOOLEAN bReleaseTargetDirLock = FALSE;
2800 BOOLEAN bReleaseSourceDirLock = FALSE;
2801 BOOLEAN bDereferenceTargetParentObject = FALSE;
2802 PERESOURCE pSourceDirLock = NULL;
2808 bReplaceIfExists = pIrpSp->Parameters.SetFile.ReplaceIfExists;
2810 pRenameInfo = (PFILE_RENAME_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
2812 pSrcFcb = (AFSFcb *)pSrcFileObj->FsContext;
2813 pSrcCcb = (AFSCcb *)pSrcFileObj->FsContext2;
2815 pSrcObject = pSrcFcb->ObjectInformation;
2817 if ( BooleanFlagOn( pSrcObject->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
2820 pSrcParentObject = AFSFindObjectInfo( pSrcObject->VolumeCB,
2821 &pSrcObject->ParentFileId,
2825 if( pSrcParentObject == NULL)
2828 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2829 AFS_TRACE_LEVEL_ERROR,
2830 "AFSSetRenameInfo Unable to resolve SrcParentObject (INVALID_PARAMETER)\n"));
2834 try_return( ntStatus = STATUS_INVALID_PARAMETER);
2838 // Perform some basic checks to ensure FS integrity
2841 if( pSrcFcb->Header.NodeTypeCode == AFS_ROOT_FCB)
2845 // Can't rename the root directory
2848 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2849 AFS_TRACE_LEVEL_ERROR,
2850 "AFSSetRenameInfo Attempt to rename root entry\n"));
2852 try_return( ntStatus = STATUS_INVALID_PARAMETER);
2855 if( pSrcFcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB)
2859 // If there are any open children then fail the rename
2862 if( pSrcObject->Specific.Directory.ChildOpenHandleCount > 0)
2865 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2866 AFS_TRACE_LEVEL_ERROR,
2867 "AFSSetRenameInfo Attempt to rename directory with open children %wZ\n",
2868 &pSrcCcb->DirectoryCB->NameInformation.FileName));
2870 try_return( ntStatus = STATUS_ACCESS_DENIED);
2876 // Extract off the final component name from the Fcb
2879 uniSourceName.Length = (USHORT)pSrcCcb->DirectoryCB->NameInformation.FileName.Length;
2880 uniSourceName.MaximumLength = uniSourceName.Length;
2882 uniSourceName.Buffer = pSrcCcb->DirectoryCB->NameInformation.FileName.Buffer;
2885 // Resolve the target fileobject
2888 if( pTargetFileObj == NULL)
2891 if ( pRenameInfo->RootDirectory)
2894 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2895 AFS_TRACE_LEVEL_ERROR,
2896 "AFSSetRenameInfo Handle provided but no FileObject ntStatus INVALID_PARAMETER\n"));
2898 try_return( ntStatus = STATUS_INVALID_PARAMETER);
2903 uniFullTargetName.Length = (USHORT)pRenameInfo->FileNameLength;
2905 uniFullTargetName.Buffer = (PWSTR)&pRenameInfo->FileName;
2907 AFSRetrieveFinalComponent( &uniFullTargetName,
2910 AFSRetrieveParentPath( &uniFullTargetName,
2911 &uniTargetParentName);
2913 if ( uniTargetParentName.Length == 0)
2917 // This is a simple rename. Here the target directory is the same as the source parent directory
2918 // and the name is retrieved from the system buffer information
2921 pTargetParentObject = pSrcParentObject;
2926 // uniTargetParentName contains the directory the renamed object
2927 // will be moved to. Must obtain the TargetParentObject.
2930 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2931 AFS_TRACE_LEVEL_ERROR,
2932 "AFSSetRenameInfo Attempt to move %wZ to %wZ -- not yet supported (NOT_SAME_DEVICE)\n",
2933 &pSrcCcb->DirectoryCB->NameInformation.FileName,
2934 &uniFullTargetName));
2936 try_return( ntStatus = STATUS_NOT_SAME_DEVICE);
2940 pTargetDcb = pTargetParentObject->Fcb;
2946 // So here we have the target directory taken from the targetfile object
2949 pTargetDcb = (AFSFcb *)pTargetFileObj->FsContext;
2951 pTargetDirCcb = (AFSCcb *)pTargetFileObj->FsContext2;
2953 pTargetParentObject = (AFSObjectInfoCB *)pTargetDcb->ObjectInformation;
2956 // Grab the target name which we setup in the IRP_MJ_CREATE handler. By how we set this up
2957 // it is only the target component of the rename operation
2960 uniTargetName = *((PUNICODE_STRING)&pTargetFileObj->FileName);
2964 // The quick check to see if they are not really performing a rename
2965 // Do the names match? Only do this where the parent directories are
2969 if( pTargetParentObject == pSrcParentObject)
2972 if( FsRtlAreNamesEqual( &uniTargetName,
2977 try_return( ntStatus = STATUS_SUCCESS);
2980 bCommonParent = TRUE;
2985 bCommonParent = FALSE;
2989 // We do not allow cross-volume renames to occur
2992 if( pTargetParentObject->VolumeCB != pSrcObject->VolumeCB)
2995 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2996 AFS_TRACE_LEVEL_ERROR,
2997 "AFSSetRenameInfo Attempt to rename directory to different volume %wZ\n",
2998 &pSrcCcb->DirectoryCB->NameInformation.FileName));
3000 try_return( ntStatus = STATUS_NOT_SAME_DEVICE);
3003 ulTargetCRC = AFSGenerateCRC( &uniTargetName,
3006 AFSAcquireExcl( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock,
3009 bReleaseTargetDirLock = TRUE;
3011 if( pTargetParentObject != pSrcParentObject)
3013 AFSAcquireExcl( pSrcParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock,
3016 bReleaseSourceDirLock = TRUE;
3018 pSourceDirLock = pSrcParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock;
3021 AFSLocateCaseSensitiveDirEntry( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
3025 if( pTargetDirEntry == NULL)
3029 // Missed so perform a case insensitive lookup
3032 ulTargetCRC = AFSGenerateCRC( &uniTargetName,
3035 AFSLocateCaseInsensitiveDirEntry( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
3040 if ( !BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
3041 pTargetDirEntry == NULL && RtlIsNameLegalDOS8Dot3( &uniTargetName,
3046 // Try the short name
3048 AFSLocateShortNameDirEntry( pTargetParentObject->Specific.Directory.ShortNameTree,
3054 // Increment our ref count on the dir entry
3057 if( pTargetDirEntry != NULL)
3060 ASSERT( BooleanFlagOn( pTargetDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_PARENT_FID) &&
3061 AFSIsEqualFID( &pTargetParentObject->FileId, &pTargetDirEntry->ObjectInformation->ParentFileId));
3063 lCount = InterlockedIncrement( &pTargetDirEntry->DirOpenReferenceCount);
3065 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3066 AFS_TRACE_LEVEL_VERBOSE,
3067 "AFSSetRenameInfo Increment count on %wZ DE %p Ccb %p Cnt %d\n",
3068 &pTargetDirEntry->NameInformation.FileName,
3073 ASSERT( lCount >= 0);
3075 if( !bReplaceIfExists)
3078 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3079 AFS_TRACE_LEVEL_ERROR,
3080 "AFSSetRenameInfo Attempt to rename directory with target collision %wZ Target %wZ\n",
3081 &pSrcCcb->DirectoryCB->NameInformation.FileName,
3082 &pTargetDirEntry->NameInformation.FileName));
3084 try_return( ntStatus = STATUS_OBJECT_NAME_COLLISION);
3087 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING | AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3088 AFS_TRACE_LEVEL_ERROR,
3089 "AFSSetRenameInfo Target %wZ exists DE %p Count %d, performing delete of target\n",
3090 &pTargetDirEntry->NameInformation.FileName,
3095 // Pull the directory entry from the parent
3098 AFSRemoveDirNodeFromParent( pTargetParentObject,
3102 bTargetEntryExists = TRUE;
3106 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3107 AFS_TRACE_LEVEL_VERBOSE,
3108 "AFSSetRenameInfo Target does NOT exist, normal rename\n"));
3112 // We need to remove the DirEntry from the parent node, update the index
3113 // and reinsert it into the parent tree. Note that for entries with the
3114 // same parent we do not pull the node from the enumeration list
3117 AFSRemoveDirNodeFromParent( pSrcParentObject,
3118 pSrcCcb->DirectoryCB,
3122 // OK, this is a simple rename. Issue the rename
3123 // request to the service.
3126 ntStatus = AFSNotifyRename( pSrcObject,
3127 &pSrcCcb->AuthGroup,
3129 pTargetDcb->ObjectInformation,
3130 pSrcCcb->DirectoryCB,
3134 if( !NT_SUCCESS( ntStatus))
3138 // Attempt to re-insert the directory entry
3141 AFSInsertDirectoryNode( pSrcParentObject,
3142 pSrcCcb->DirectoryCB,
3145 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3146 AFS_TRACE_LEVEL_ERROR,
3147 "AFSSetRenameInfo Failed rename of %wZ to target %wZ Status %08lX\n",
3148 &pSrcCcb->DirectoryCB->NameInformation.FileName,
3152 try_return( ntStatus);
3156 // Set the notification up for the source file
3159 if( pSrcParentObject == pTargetParentObject &&
3160 !bTargetEntryExists)
3163 ulNotificationAction = FILE_ACTION_RENAMED_OLD_NAME;
3168 ulNotificationAction = FILE_ACTION_REMOVED;
3171 if( pSrcObject->FileType == AFS_FILE_TYPE_DIRECTORY)
3174 ulNotifyFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
3179 ulNotifyFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
3182 AFSFsRtlNotifyFullReportChange( pSrcParentObject,
3184 (ULONG)ulNotifyFilter,
3185 (ULONG)ulNotificationAction);
3188 // Update the name in the dir entry.
3191 ntStatus = AFSUpdateDirEntryName( pSrcCcb->DirectoryCB,
3194 if( !NT_SUCCESS( ntStatus))
3198 // Attempt to re-insert the directory entry
3201 AFSInsertDirectoryNode( pSrcParentObject,
3202 pSrcCcb->DirectoryCB,
3205 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3206 AFS_TRACE_LEVEL_ERROR,
3207 "AFSSetRenameInfo Failed update of dir entry %wZ to target %wZ Status %08lX\n",
3208 &pSrcCcb->DirectoryCB->NameInformation.FileName,
3212 try_return( ntStatus);
3216 // Update the object information block, if needed
3219 if( !AFSIsEqualFID( &pSrcObject->FileId,
3223 AFSAcquireExcl( pSrcObject->VolumeCB->ObjectInfoTree.TreeLock,
3227 // Remove the old information entry
3230 AFSRemoveHashEntry( &pSrcObject->VolumeCB->ObjectInfoTree.TreeHead,
3231 &pSrcObject->TreeEntry);
3233 RtlCopyMemory( &pSrcObject->FileId,
3235 sizeof( AFSFileID));
3238 // Insert the entry into the new object table.
3241 pSrcObject->TreeEntry.HashIndex = AFSCreateLowIndex( &pSrcObject->FileId);
3243 if( pSrcObject->VolumeCB->ObjectInfoTree.TreeHead == NULL)
3246 pSrcObject->VolumeCB->ObjectInfoTree.TreeHead = &pSrcObject->TreeEntry;
3251 if ( !NT_SUCCESS( AFSInsertHashEntry( pSrcObject->VolumeCB->ObjectInfoTree.TreeHead,
3252 &pSrcObject->TreeEntry)))
3256 // Lost a race, an ObjectInfo object already exists for this FID.
3257 // Let this copy be garbage collected.
3260 ClearFlag( pSrcObject->Flags, AFS_OBJECT_INSERTED_HASH_TREE);
3264 AFSReleaseResource( pSrcObject->VolumeCB->ObjectInfoTree.TreeLock);
3268 // Update the hash values for the name trees.
3271 pSrcCcb->DirectoryCB->CaseSensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pSrcCcb->DirectoryCB->NameInformation.FileName,
3274 pSrcCcb->DirectoryCB->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pSrcCcb->DirectoryCB->NameInformation.FileName,
3277 if( !BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
3278 pSrcCcb->DirectoryCB->NameInformation.ShortNameLength > 0 &&
3279 !RtlIsNameLegalDOS8Dot3( &pSrcCcb->DirectoryCB->NameInformation.FileName,
3284 uniShortName.Length = pSrcCcb->DirectoryCB->NameInformation.ShortNameLength;
3285 uniShortName.MaximumLength = uniShortName.Length;
3286 uniShortName.Buffer = pSrcCcb->DirectoryCB->NameInformation.ShortName;
3288 pSrcCcb->DirectoryCB->Type.Data.ShortNameTreeEntry.HashIndex = AFSGenerateCRC( &uniShortName,
3291 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3292 AFS_TRACE_LEVEL_VERBOSE,
3293 "AFSSetRenameInfo Initialized short name hash for %wZ longname %wZ\n",
3295 &pSrcCcb->DirectoryCB->NameInformation.FileName));
3300 pSrcCcb->DirectoryCB->Type.Data.ShortNameTreeEntry.HashIndex = 0;
3307 // Update the file index for the object in the new parent
3310 pSrcCcb->DirectoryCB->FileIndex = (ULONG)InterlockedIncrement( &pTargetParentObject->Specific.Directory.DirectoryNodeHdr.ContentIndex);
3314 // Re-insert the directory entry
3317 AFSInsertDirectoryNode( pTargetParentObject,
3318 pSrcCcb->DirectoryCB,
3322 // Update the parent pointer in the source object if they are different
3325 if( pSrcParentObject != pTargetParentObject)
3328 lCount = InterlockedDecrement( &pSrcParentObject->Specific.Directory.ChildOpenHandleCount);
3330 lCount = InterlockedDecrement( &pSrcParentObject->Specific.Directory.ChildOpenReferenceCount);
3332 lCount = InterlockedIncrement( &pTargetParentObject->Specific.Directory.ChildOpenHandleCount);
3334 lCount = InterlockedIncrement( &pTargetParentObject->Specific.Directory.ChildOpenReferenceCount);
3338 // Guaranteed to be in the same volume
3341 AFSAcquireExcl( pSrcParentObject->VolumeCB->ObjectInfoTree.TreeLock,
3344 lCount = AFSObjectInfoIncrement( pTargetParentObject,
3345 AFS_OBJECT_REFERENCE_CHILD);
3347 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
3348 AFS_TRACE_LEVEL_VERBOSE,
3349 "AFSSetRenameInfo Increment count on parent object %p Cnt %d\n",
3350 pTargetParentObject,
3353 lCount = AFSObjectInfoDecrement( pSrcParentObject,
3354 AFS_OBJECT_REFERENCE_CHILD);
3356 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
3357 AFS_TRACE_LEVEL_VERBOSE,
3358 "AFSSetRenameInfo Decrement count on parent object %p Cnt %d\n",
3362 pSrcObject->ParentFileId = pTargetParentObject->FileId;
3364 SetFlag( pSrcObject->Flags, AFS_OBJECT_FLAGS_PARENT_FID);
3366 AFSReleaseResource( pSrcParentObject->VolumeCB->ObjectInfoTree.TreeLock);
3368 ulNotificationAction = FILE_ACTION_ADDED;
3373 ulNotificationAction = FILE_ACTION_RENAMED_NEW_NAME;
3377 // Now update the notification for the target file
3380 AFSFsRtlNotifyFullReportChange( pTargetParentObject,
3382 (ULONG)ulNotifyFilter,
3383 (ULONG)ulNotificationAction);
3386 // If we performed the rename of the target because it existed, we now need to
3387 // delete the tmp target we created above
3390 if( bTargetEntryExists)
3393 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3394 AFS_TRACE_LEVEL_VERBOSE,
3395 "AFSSetRenameInfo Setting DELETE flag in dir entry %p name %wZ\n",
3397 &pTargetDirEntry->NameInformation.FileName));
3399 SetFlag( pTargetDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
3402 // Try and purge the cache map if this is a file
3405 if( pTargetDirEntry->ObjectInformation->FileType == AFS_FILE_TYPE_FILE &&
3406 pTargetDirEntry->ObjectInformation->Fcb != NULL &&
3407 pTargetDirEntry->DirOpenReferenceCount > 1)
3410 pTargetFcb = pTargetDirEntry->ObjectInformation->Fcb;
3413 ASSERT( pTargetDirEntry->DirOpenReferenceCount > 0);
3415 lCount = InterlockedDecrement( &pTargetDirEntry->DirOpenReferenceCount); // The count we added above
3417 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3418 AFS_TRACE_LEVEL_VERBOSE,
3419 "AFSSetRenameInfo Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
3420 &pTargetDirEntry->NameInformation.FileName,
3425 ASSERT( lCount >= 0);
3428 pTargetDirEntry->NameArrayReferenceCount <= 0)
3431 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3432 AFS_TRACE_LEVEL_VERBOSE,
3433 "AFSSetRenameInfo Deleting dir entry %p name %wZ\n",
3435 &pTargetDirEntry->NameInformation.FileName));
3437 AFSDeleteDirEntry( pTargetParentObject,
3441 pTargetDirEntry = NULL;
3443 if ( pTargetFcb != NULL)
3447 // Do not hold TreeLocks across the MmForceSectionClosed() call as
3448 // it can deadlock with Trend Micro's TmPreFlt!TmpQueryFullName
3451 if( bReleaseTargetDirLock)
3453 AFSReleaseResource( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
3455 bReleaseTargetDirLock = FALSE;
3458 if( bReleaseSourceDirLock)
3461 AFSReleaseResource( pSourceDirLock);
3463 bReleaseSourceDirLock = FALSE;
3467 // MmForceSectionClosed() can eventually call back into AFSCleanup
3468 // which will need to acquire Fcb->Resource exclusively. Failure
3469 // to obtain it here before holding the SectionObjectResource will
3470 // permit the locks to be obtained out of order risking a deadlock.
3473 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
3474 AFS_TRACE_LEVEL_VERBOSE,
3475 "AFSSetRenameInfo Acquiring Fcb lock %p EXCL %08lX\n",
3476 &pTargetFcb->NPFcb->Resource,
3477 PsGetCurrentThread()));
3479 AFSAcquireExcl( &pTargetFcb->NPFcb->Resource,
3482 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
3483 AFS_TRACE_LEVEL_VERBOSE,
3484 "AFSSetRenameInfo Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
3485 &pTargetFcb->NPFcb->SectionObjectResource,
3486 PsGetCurrentThread()));
3488 AFSAcquireExcl( &pTargetFcb->NPFcb->SectionObjectResource,
3495 // Close the section in the event it was mapped
3498 if( !MmForceSectionClosed( &pTargetFcb->NPFcb->SectionObjectPointers,
3502 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3503 AFS_TRACE_LEVEL_ERROR,
3504 "AFSSetRenameInfo Failed to delete section for target file %wZ\n",
3508 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
3511 ntStatus = GetExceptionCode();
3515 "EXCEPTION - AFSSetRenameInfo MmForceSectionClosed failed FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
3516 pTargetFcb->ObjectInformation->FileId.Cell,
3517 pTargetFcb->ObjectInformation->FileId.Volume,
3518 pTargetFcb->ObjectInformation->FileId.Vnode,
3519 pTargetFcb->ObjectInformation->FileId.Unique,
3523 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
3524 AFS_TRACE_LEVEL_VERBOSE,
3525 "AFSSetRenameInfo Releasing Fcb SectionObject lock %p EXCL %08lX\n",
3526 &pTargetFcb->NPFcb->SectionObjectResource,
3527 PsGetCurrentThread()));
3529 AFSReleaseResource( &pTargetFcb->NPFcb->SectionObjectResource);
3531 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3532 AFS_TRACE_LEVEL_VERBOSE,
3533 "AFSSetRenameInfo Releasing Fcb lock %p EXCL %08lX\n",
3534 &pTargetFcb->NPFcb->Resource,
3535 PsGetCurrentThread()));
3537 AFSReleaseResource( &pTargetFcb->NPFcb->Resource);
3543 if( !NT_SUCCESS( ntStatus))
3546 if( bTargetEntryExists)
3549 ASSERT( pTargetParentObject != NULL);
3551 AFSInsertDirectoryNode( pTargetParentObject,
3557 if( pTargetDirEntry != NULL)
3560 lCount = InterlockedDecrement( &pTargetDirEntry->DirOpenReferenceCount);
3562 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3563 AFS_TRACE_LEVEL_VERBOSE,
3564 "AFSSetRenameInfo Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
3565 &pTargetDirEntry->NameInformation.FileName,
3570 ASSERT( lCount >= 0);
3573 if( bReleaseTargetDirLock)
3576 AFSReleaseResource( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
3579 if( bReleaseSourceDirLock)
3582 AFSReleaseResource( pSourceDirLock);
3585 if ( bDereferenceTargetParentObject)
3588 ObDereferenceObject( pTargetParentFileObj);
3591 if ( pSrcParentObject != NULL)
3594 AFSReleaseObjectInfo( &pSrcParentObject);
3598 // No need to release pTargetParentObject as it is either a copy of pSrcParentObject
3599 // or (AFSFcb *)pTargetFileObj->FsContext->ObjectInformation
3602 pTargetParentObject = NULL;
3609 AFSSetPositionInfo( IN PIRP Irp,
3610 IN AFSDirectoryCB *DirectoryCB)
3612 UNREFERENCED_PARAMETER(DirectoryCB);
3613 NTSTATUS ntStatus = STATUS_SUCCESS;
3614 PFILE_POSITION_INFORMATION pBuffer;
3615 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
3617 pBuffer = (PFILE_POSITION_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
3619 pIrpSp->FileObject->CurrentByteOffset.QuadPart = pBuffer->CurrentByteOffset.QuadPart;
3625 AFSSetAllocationInfo( IN PIRP Irp,
3626 IN AFSDirectoryCB *DirectoryCB)
3628 UNREFERENCED_PARAMETER(DirectoryCB);
3629 NTSTATUS ntStatus = STATUS_SUCCESS;
3630 PFILE_ALLOCATION_INFORMATION pBuffer;
3631 BOOLEAN bReleasePaging = FALSE;
3632 BOOLEAN bTellCc = FALSE;
3633 BOOLEAN bTellService = FALSE;
3634 BOOLEAN bUserMapped = FALSE;
3635 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
3636 PFILE_OBJECT pFileObject = pIrpSp->FileObject;
3637 AFSFcb *pFcb = NULL;
3638 AFSCcb *pCcb = NULL;
3639 LARGE_INTEGER liSaveAlloc;
3640 LARGE_INTEGER liSaveFileSize;
3641 LARGE_INTEGER liSaveVDL;
3643 pBuffer = (PFILE_ALLOCATION_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
3645 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
3647 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
3650 // save values to put back
3652 liSaveAlloc = pFcb->Header.AllocationSize;
3653 liSaveFileSize = pFcb->Header.FileSize;
3654 liSaveVDL = pFcb->Header.ValidDataLength;
3656 if( pFcb->Header.AllocationSize.QuadPart == pBuffer->AllocationSize.QuadPart ||
3657 pIrpSp->Parameters.SetFile.AdvanceOnly)
3659 return STATUS_SUCCESS ;
3662 if( pFcb->Header.AllocationSize.QuadPart > pBuffer->AllocationSize.QuadPart)
3665 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
3666 AFS_TRACE_LEVEL_VERBOSE,
3667 "AFSSetAllocationInfo Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
3668 &pFcb->NPFcb->SectionObjectResource,
3669 PsGetCurrentThread()));
3671 AFSAcquireExcl( &pFcb->NPFcb->SectionObjectResource,
3677 bUserMapped = !MmCanFileBeTruncated( pFileObject->SectionObjectPointer,
3678 &pBuffer->AllocationSize);
3680 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
3683 bUserMapped = FALSE;
3685 ntStatus = GetExceptionCode();
3689 "EXCEPTION - AFSSetAllocationInfo MmCanFileBeTruncated failed FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
3690 pFcb->ObjectInformation->FileId.Cell,
3691 pFcb->ObjectInformation->FileId.Volume,
3692 pFcb->ObjectInformation->FileId.Vnode,
3693 pFcb->ObjectInformation->FileId.Unique,
3697 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
3698 AFS_TRACE_LEVEL_VERBOSE,
3699 "AFSSetAllocationInfo Releasing Fcb SectionObject lock %p EXCL %08lX\n",
3700 &pFcb->NPFcb->SectionObjectResource,
3701 PsGetCurrentThread()));
3703 AFSReleaseResource( &pFcb->NPFcb->SectionObjectResource);
3706 // Truncating the file
3711 ntStatus = STATUS_USER_MAPPED_FILE ;
3717 // If this is a truncation we need to grab the paging IO resource.
3720 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3721 AFS_TRACE_LEVEL_VERBOSE,
3722 "AFSSetAllocationInfo Acquiring Fcb PagingIo lock %p EXCL %08lX\n",
3723 &pFcb->NPFcb->PagingResource,
3724 PsGetCurrentThread()));
3726 AFSAcquireExcl( &pFcb->NPFcb->PagingResource,
3729 bReleasePaging = TRUE;
3732 // Must drop the Fcb Resource. When changing the file size
3733 // a deadlock can occur with Trend Micro's filter if the file
3734 // size is set to zero.
3737 AFSReleaseResource( &pFcb->NPFcb->Resource);
3739 pFcb->Header.AllocationSize = pBuffer->AllocationSize;
3741 pFcb->ObjectInformation->AllocationSize = pBuffer->AllocationSize;
3744 // Tell Cc that Allocation is moved.
3748 if( pFcb->Header.FileSize.QuadPart > pBuffer->AllocationSize.QuadPart)
3751 // We are pulling the EOF back as well so we need to tell
3754 bTellService = TRUE;
3756 pFcb->Header.FileSize = pBuffer->AllocationSize;
3758 pFcb->ObjectInformation->EndOfFile = pBuffer->AllocationSize;
3766 // Tell Cc if allocation is increased.
3769 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3770 AFS_TRACE_LEVEL_VERBOSE,
3771 "AFSSetAllocationInfo Acquiring Fcb PagingIo lock %p EXCL %08lX\n",
3772 &pFcb->NPFcb->PagingResource,
3773 PsGetCurrentThread()));
3775 AFSAcquireExcl( &pFcb->NPFcb->PagingResource,
3778 bReleasePaging = TRUE;
3781 // Must drop the Fcb Resource. When changing the file size
3782 // a deadlock can occur with Trend Micro's filter if the file
3783 // size is set to zero.
3786 AFSReleaseResource( &pFcb->NPFcb->Resource);
3788 bTellCc = pBuffer->AllocationSize.QuadPart > pFcb->Header.AllocationSize.QuadPart;
3790 pFcb->Header.AllocationSize = pBuffer->AllocationSize;
3792 pFcb->ObjectInformation->AllocationSize = pBuffer->AllocationSize;
3796 // Now Tell the server if we have to
3801 ASSERT( BooleanFlagOn( pFcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_PARENT_FID));
3803 ntStatus = AFSUpdateFileInformation( &pFcb->ObjectInformation->ParentFileId,
3804 pFcb->ObjectInformation,
3808 if (NT_SUCCESS(ntStatus))
3811 // Trim extents if we told the service - the update has done an implicit
3812 // trim at the service.
3816 AFSTrimExtents( pFcb,
3817 &pFcb->Header.FileSize);
3820 KeQuerySystemTime( &pFcb->ObjectInformation->ChangeTime);
3822 SetFlag( pFcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_CHANGE_TIME);
3825 CcIsFileCached( pFileObject))
3827 CcSetFileSizes( pFileObject,
3828 (PCC_FILE_SIZES)&pFcb->Header.AllocationSize);
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);
4067 pFcb->Header.ValidDataLength = liSaveVDL;
4068 pFcb->Header.FileSize = liSaveSize;
4069 pFcb->Header.AllocationSize = liSaveAlloc;
4070 pFcb->ObjectInformation->EndOfFile = liSaveSize;
4071 pFcb->ObjectInformation->AllocationSize = liSaveAlloc;
4078 AFSReleaseResource( &pFcb->NPFcb->PagingResource);
4080 AFSAcquireExcl( &pFcb->NPFcb->Resource,
4088 AFSProcessShareSetInfo( IN IRP *Irp,
4093 UNREFERENCED_PARAMETER(Fcb);
4094 NTSTATUS ntStatus = STATUS_SUCCESS;
4095 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
4096 FILE_INFORMATION_CLASS ulFileInformationClass;
4097 void *pPipeInfo = NULL;
4101 ulFileInformationClass = pIrpSp->Parameters.SetFile.FileInformationClass;
4103 AFSDbgTrace(( AFS_SUBSYSTEM_PIPE_PROCESSING,
4104 AFS_TRACE_LEVEL_VERBOSE,
4105 "AFSProcessShareSetInfo On pipe %wZ Class %08lX\n",
4106 &Ccb->DirectoryCB->NameInformation.FileName,
4107 ulFileInformationClass));
4109 pPipeInfo = AFSLockSystemBuffer( Irp,
4110 pIrpSp->Parameters.SetFile.Length);
4112 if( pPipeInfo == NULL)
4115 AFSDbgTrace(( AFS_SUBSYSTEM_PIPE_PROCESSING,
4116 AFS_TRACE_LEVEL_ERROR,
4117 "AFSProcessShareSetInfo Failed to lock buffer on pipe %wZ\n",
4118 &Ccb->DirectoryCB->NameInformation.FileName));
4120 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4124 // Send the request to the service
4127 ntStatus = AFSNotifySetPipeInfo( Ccb,
4128 (ULONG)ulFileInformationClass,
4129 pIrpSp->Parameters.SetFile.Length,
4132 if( !NT_SUCCESS( ntStatus))
4135 AFSDbgTrace(( AFS_SUBSYSTEM_PIPE_PROCESSING,
4136 AFS_TRACE_LEVEL_ERROR,
4137 "AFSProcessShareSetInfo Failed to send request to service on pipe %wZ Status %08lX\n",
4138 &Ccb->DirectoryCB->NameInformation.FileName,
4141 try_return( ntStatus);
4144 AFSDbgTrace(( AFS_SUBSYSTEM_PIPE_PROCESSING,
4145 AFS_TRACE_LEVEL_VERBOSE,
4146 "AFSProcessShareSetInfo Completed request on pipe %wZ Class %08lX\n",
4147 &Ccb->DirectoryCB->NameInformation.FileName,
4148 ulFileInformationClass));
4159 AFSProcessShareQueryInfo( IN IRP *Irp,
4164 UNREFERENCED_PARAMETER(Fcb);
4165 NTSTATUS ntStatus = STATUS_SUCCESS;
4166 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
4167 FILE_INFORMATION_CLASS ulFileInformationClass;
4168 void *pPipeInfo = NULL;
4173 ulFileInformationClass = pIrpSp->Parameters.QueryFile.FileInformationClass;
4175 AFSDbgTrace(( AFS_SUBSYSTEM_PIPE_PROCESSING,
4176 AFS_TRACE_LEVEL_VERBOSE,
4177 "AFSProcessShareQueryInfo On pipe %wZ Class %08lX\n",
4178 &Ccb->DirectoryCB->NameInformation.FileName,
4179 ulFileInformationClass));
4181 pPipeInfo = AFSLockSystemBuffer( Irp,
4182 pIrpSp->Parameters.QueryFile.Length);
4184 if( pPipeInfo == NULL)
4187 AFSDbgTrace(( AFS_SUBSYSTEM_PIPE_PROCESSING,
4188 AFS_TRACE_LEVEL_ERROR,
4189 "AFSProcessShareQueryInfo Failed to lock buffer on pipe %wZ\n",
4190 &Ccb->DirectoryCB->NameInformation.FileName));
4192 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4196 // Send the request to the service
4199 ntStatus = AFSNotifyQueryPipeInfo( Ccb,
4200 (ULONG)ulFileInformationClass,
4201 pIrpSp->Parameters.QueryFile.Length,
4203 (ULONG *)&Irp->IoStatus.Information);
4205 if( !NT_SUCCESS( ntStatus))
4208 AFSDbgTrace(( AFS_SUBSYSTEM_PIPE_PROCESSING,
4209 AFS_TRACE_LEVEL_ERROR,
4210 "AFSProcessShareQueryInfo Failed to send request to service on pipe %wZ Status %08lX\n",
4211 &Ccb->DirectoryCB->NameInformation.FileName,
4214 try_return( ntStatus);
4217 AFSDbgTrace(( AFS_SUBSYSTEM_PIPE_PROCESSING,
4218 AFS_TRACE_LEVEL_VERBOSE,
4219 "AFSProcessShareQueryInfo Completed request on pipe %wZ Class %08lX\n",
4220 &Ccb->DirectoryCB->NameInformation.FileName,
4221 ulFileInformationClass));
4232 AFSProcessPIOCtlQueryInfo( IN IRP *Irp,
4235 IN OUT LONG *Length)
4238 UNREFERENCED_PARAMETER(Fcb);
4239 UNREFERENCED_PARAMETER(Ccb);
4240 NTSTATUS ntStatus = STATUS_SUCCESS;
4241 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
4242 FILE_INFORMATION_CLASS ulFileInformationClass;
4247 ulFileInformationClass = pIrpSp->Parameters.QueryFile.FileInformationClass;
4249 switch( ulFileInformationClass)
4252 case FileBasicInformation:
4255 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4256 AFS_TRACE_LEVEL_VERBOSE,
4257 "AFSProcessPIOCtlQueryInfo (FileBasicInformation)\n"));
4259 if ( *Length >= sizeof( FILE_BASIC_INFORMATION))
4261 PFILE_BASIC_INFORMATION pBasic = (PFILE_BASIC_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
4263 pBasic->CreationTime.QuadPart = 0;
4264 pBasic->LastAccessTime.QuadPart = 0;
4265 pBasic->ChangeTime.QuadPart = 0;
4266 pBasic->LastWriteTime.QuadPart = 0;
4267 pBasic->FileAttributes = FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM;
4269 *Length -= sizeof( FILE_BASIC_INFORMATION);
4273 ntStatus = STATUS_BUFFER_TOO_SMALL;
4279 case FileStandardInformation:
4282 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4283 AFS_TRACE_LEVEL_VERBOSE,
4284 "AFSProcessPIOCtlQueryInfo (FileStandardInformation)\n"));
4286 if ( *Length >= sizeof( FILE_STANDARD_INFORMATION))
4288 PFILE_STANDARD_INFORMATION pStandard = (PFILE_STANDARD_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
4290 pStandard->NumberOfLinks = 1;
4291 pStandard->DeletePending = 0;
4292 pStandard->AllocationSize.QuadPart = 0;
4293 pStandard->EndOfFile.QuadPart = 0;
4294 pStandard->Directory = 0;
4296 *Length -= sizeof( FILE_STANDARD_INFORMATION);
4300 ntStatus = STATUS_BUFFER_TOO_SMALL;
4306 case FileNormalizedNameInformation:
4307 case FileNameInformation:
4310 ULONG ulCopyLength = 0;
4311 AFSFcb *pFcb = NULL;
4312 AFSCcb *pCcb = NULL;
4313 USHORT usFullNameLength = 0;
4314 PFILE_NAME_INFORMATION pNameInfo = (PFILE_NAME_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
4315 UNICODE_STRING uniName;
4317 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4318 AFS_TRACE_LEVEL_VERBOSE,
4319 "AFSProcessPIOCtlQueryInfo (FileNameInformation)\n"));
4321 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
4322 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
4324 if( *Length < FIELD_OFFSET( FILE_NAME_INFORMATION, FileName))
4326 ntStatus = STATUS_BUFFER_TOO_SMALL;
4330 RtlZeroMemory( pNameInfo,
4333 usFullNameLength = sizeof( WCHAR) +
4334 AFSServerName.Length +
4335 pCcb->FullFileName.Length;
4337 if( *Length >= (LONG)(FIELD_OFFSET( FILE_NAME_INFORMATION, FileName) + (LONG)usFullNameLength))
4339 ulCopyLength = (LONG)usFullNameLength;
4343 ulCopyLength = *Length - FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
4344 ntStatus = STATUS_BUFFER_OVERFLOW;
4347 pNameInfo->FileNameLength = (ULONG)usFullNameLength;
4349 *Length -= FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
4351 if( ulCopyLength > 0)
4354 pNameInfo->FileName[ 0] = L'\\';
4355 ulCopyLength -= sizeof( WCHAR);
4357 *Length -= sizeof( WCHAR);
4359 if( ulCopyLength >= AFSServerName.Length)
4362 RtlCopyMemory( &pNameInfo->FileName[ 1],
4363 AFSServerName.Buffer,
4364 AFSServerName.Length);
4366 ulCopyLength -= AFSServerName.Length;
4367 *Length -= AFSServerName.Length;
4369 if( ulCopyLength >= pCcb->FullFileName.Length)
4372 RtlCopyMemory( &pNameInfo->FileName[ 1 + (AFSServerName.Length/sizeof( WCHAR))],
4373 pCcb->FullFileName.Buffer,
4374 pCcb->FullFileName.Length);
4376 ulCopyLength -= pCcb->FullFileName.Length;
4377 *Length -= pCcb->FullFileName.Length;
4379 uniName.Length = (USHORT)pNameInfo->FileNameLength;
4380 uniName.MaximumLength = uniName.Length;
4381 uniName.Buffer = pNameInfo->FileName;
4386 RtlCopyMemory( &pNameInfo->FileName[ 1 + (AFSServerName.Length/sizeof( WCHAR))],
4387 pCcb->FullFileName.Buffer,
4390 *Length -= ulCopyLength;
4392 uniName.Length = (USHORT)(sizeof( WCHAR) + AFSServerName.Length + ulCopyLength);
4393 uniName.MaximumLength = uniName.Length;
4394 uniName.Buffer = pNameInfo->FileName;
4397 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4398 AFS_TRACE_LEVEL_VERBOSE,
4399 "AFSProcessPIOCtlQueryInfo (FileNameInformation) Returning %wZ\n",
4407 case FileInternalInformation:
4410 PFILE_INTERNAL_INFORMATION pInternalInfo = (PFILE_INTERNAL_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
4412 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4413 AFS_TRACE_LEVEL_VERBOSE,
4414 "AFSProcessPIOCtlQueryInfo (FileInternalInformation)\n"));
4416 if( *Length >= sizeof( FILE_INTERNAL_INFORMATION))
4419 pInternalInfo->IndexNumber.HighPart = 0;
4421 pInternalInfo->IndexNumber.LowPart = 0;
4423 *Length -= sizeof( FILE_INTERNAL_INFORMATION);
4428 ntStatus = STATUS_BUFFER_TOO_SMALL;
4434 case FileAllInformation:
4436 ntStatus = STATUS_INVALID_PARAMETER;
4438 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4439 AFS_TRACE_LEVEL_WARNING,
4440 "AFSProcessPIOCtlQueryInfo (FileAllInformation) Not Implemented\n"));
4445 case FileEaInformation:
4447 ntStatus = STATUS_INVALID_PARAMETER;
4449 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4450 AFS_TRACE_LEVEL_WARNING,
4451 "AFSProcessPIOCtlQueryInfo (FileEaInformation) Not Implemented\n"));
4456 case FilePositionInformation:
4458 ntStatus = STATUS_INVALID_PARAMETER;
4460 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4461 AFS_TRACE_LEVEL_WARNING,
4462 "AFSProcessPIOCtlQueryInfo (FilePositionInformation) Not Implemented\n"));
4467 case FileAlternateNameInformation:
4469 ntStatus = STATUS_INVALID_PARAMETER;
4471 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4472 AFS_TRACE_LEVEL_WARNING,
4473 "AFSProcessPIOCtlQueryInfo (FileAlternateNameInformation) Not Implemented\n"));
4478 case FileNetworkOpenInformation:
4480 ntStatus = STATUS_INVALID_PARAMETER;
4482 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4483 AFS_TRACE_LEVEL_WARNING,
4484 "AFSProcessPIOCtlQueryInfo (FileNetworkOpenInformation) Not Implemented\n"));
4489 case FileStreamInformation:
4491 ntStatus = STATUS_INVALID_PARAMETER;
4493 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4494 AFS_TRACE_LEVEL_WARNING,
4495 "AFSProcessPIOCtlQueryInfo (FileStreamInformation) Not Implemented\n"));
4500 case FileAttributeTagInformation:
4502 ntStatus = STATUS_INVALID_PARAMETER;
4504 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4505 AFS_TRACE_LEVEL_WARNING,
4506 "AFSProcessPIOCtlQueryInfo (FileAttributeTagInformation) Not Implemented\n"));
4511 case FileRemoteProtocolInformation:
4513 ntStatus = STATUS_INVALID_PARAMETER;
4515 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4516 AFS_TRACE_LEVEL_WARNING,
4517 "AFSProcessPIOCtlQueryInfo (FileRemoteProtocolInformation) Not Implemented\n"));
4522 case FileNetworkPhysicalNameInformation:
4524 ntStatus = STATUS_INVALID_PARAMETER;
4526 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4527 AFS_TRACE_LEVEL_WARNING,
4528 "AFSProcessPIOCtlQueryInfo (FileNetworkPhysicalNameInformation) Not Implemented\n"));
4535 ntStatus = STATUS_INVALID_PARAMETER;
4537 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4538 AFS_TRACE_LEVEL_WARNING,
4539 "AFSProcessPIOCtlQueryInfo Not handling request %08lX\n",
4540 ulFileInformationClass));
4547 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4548 AFS_TRACE_LEVEL_VERBOSE,
4549 "AFSProcessPIOCtlQueryInfo ntStatus %08lX\n",