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 SectionObject lock %p EXCL %08lX\n",
2207 &pFcb->NPFcb->SectionObjectResource,
2208 PsGetCurrentThread()));
2210 AFSAcquireExcl( &pFcb->NPFcb->SectionObjectResource,
2217 // Attempt to flush any outstanding data
2220 bMmFlushed = MmFlushImageSection( &pFcb->NPFcb->SectionObjectPointers,
2227 // Set PENDING_DELETE before CcPurgeCacheSection to avoid a
2228 // deadlock with Trend Micro's Enterprise anti-virus product
2229 // which attempts to open the file which is being deleted.
2232 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2233 AFS_TRACE_LEVEL_VERBOSE,
2234 "AFSSetDispositionInfo Setting PENDING_DELETE on DirEntry %p Name %wZ\n",
2236 &DirectoryCB->NameInformation.FileName));
2238 SetFlag( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
2241 // Purge the cache as well
2244 if( pFcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
2247 if ( !CcPurgeCacheSection( &pFcb->NPFcb->SectionObjectPointers,
2253 SetFlag( pFcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
2258 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
2263 ntStatus = GetExceptionCode();
2267 "EXCEPTION - AFSSetDispositionInfo MmFlushImageSection failed FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
2268 pFcb->ObjectInformation->FileId.Cell,
2269 pFcb->ObjectInformation->FileId.Volume,
2270 pFcb->ObjectInformation->FileId.Vnode,
2271 pFcb->ObjectInformation->FileId.Unique,
2275 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
2276 AFS_TRACE_LEVEL_VERBOSE,
2277 "AFSSetDispositionInfo Releasing Fcb SectionObject lock %p EXCL %08lX\n",
2278 &pFcb->NPFcb->SectionObjectResource,
2279 PsGetCurrentThread()));
2281 AFSReleaseResource( &pFcb->NPFcb->SectionObjectResource);
2286 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2287 AFS_TRACE_LEVEL_ERROR,
2288 "AFSSetDispositionInfo Failed to flush image section for delete Entry %wZ\n",
2289 &DirectoryCB->NameInformation.FileName));
2291 try_return( ntStatus = STATUS_CANNOT_DELETE);
2294 else if( pFcb->Header.NodeTypeCode == AFS_SYMBOLIC_LINK_FCB ||
2295 pFcb->Header.NodeTypeCode == AFS_MOUNT_POINT_FCB ||
2296 pFcb->Header.NodeTypeCode == AFS_DFS_LINK_FCB ||
2297 pFcb->Header.NodeTypeCode == AFS_INVALID_FCB)
2300 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2301 AFS_TRACE_LEVEL_VERBOSE,
2302 "AFSSetDispositionInfo Setting PENDING_DELETE on DirEntry %p Name %wZ\n",
2304 &DirectoryCB->NameInformation.FileName));
2306 SetFlag( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
2312 ClearFlag( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
2316 // OK, should be good to go, set the flag in the file object
2319 pIrpSp->FileObject->DeletePending = pBuffer->DeleteFile;
2330 AFSSetFileLinkInfo( IN PIRP Irp)
2333 NTSTATUS ntStatus = STATUS_SUCCESS;
2334 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
2335 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2336 PFILE_LINK_INFORMATION pFileLinkInfo = NULL;
2337 PFILE_OBJECT pSrcFileObj = NULL;
2338 PFILE_OBJECT pTargetFileObj = pIrpSp->Parameters.SetFile.FileObject;
2339 AFSFcb *pSrcFcb = NULL, *pTargetDcb = NULL;
2340 AFSCcb *pSrcCcb = NULL, *pTargetDirCcb = NULL;
2341 AFSObjectInfoCB *pSrcObject = NULL;
2342 AFSObjectInfoCB *pSrcParentObject = NULL, *pTargetParentObject = NULL;
2343 UNICODE_STRING uniSourceName, uniTargetName;
2344 UNICODE_STRING uniFullTargetName, uniTargetParentName;
2345 BOOLEAN bCommonParent = FALSE;
2346 AFSDirectoryCB *pTargetDirEntry = NULL;
2347 AFSDirectoryCB *pNewTargetDirEntry = NULL;
2349 BOOLEAN bTargetEntryExists = FALSE;
2351 BOOLEAN bReleaseTargetDirLock = FALSE;
2352 ULONG ulNotificationAction = 0, ulNotifyFilter = 0;
2357 pSrcFileObj = pIrpSp->FileObject;
2359 pSrcFcb = (AFSFcb *)pSrcFileObj->FsContext;
2360 pSrcCcb = (AFSCcb *)pSrcFileObj->FsContext2;
2362 pSrcObject = pSrcFcb->ObjectInformation;
2364 if ( BooleanFlagOn( pSrcObject->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
2367 pSrcParentObject = AFSFindObjectInfo( pSrcObject->VolumeCB,
2368 &pSrcObject->ParentFileId,
2372 if( pSrcParentObject == NULL)
2375 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2376 AFS_TRACE_LEVEL_ERROR,
2377 "AFSSetFileLinkInfo Unable to resolve SrcParentObject (INVALID_PARAMETER)\n"));
2381 try_return( ntStatus = STATUS_INVALID_PARAMETER);
2384 pFileLinkInfo = (PFILE_LINK_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
2387 // Perform some basic checks to ensure FS integrity
2390 if( pSrcFcb->Header.NodeTypeCode != AFS_FILE_FCB)
2393 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2394 AFS_TRACE_LEVEL_ERROR,
2395 "AFSSetFileLinkInfo Attempt to non-file (INVALID_PARAMETER)\n"));
2397 try_return( ntStatus = STATUS_INVALID_PARAMETER);
2400 if( pTargetFileObj == NULL)
2403 if ( pFileLinkInfo->RootDirectory)
2407 // The target directory is provided by HANDLE
2408 // RootDirectory is only set when the target directory is not the same
2409 // as the source directory.
2411 // AFS only supports hard links within a single directory.
2413 // The IOManager should translate any Handle to a FileObject for us.
2414 // However, the failure to receive a FileObject is treated as a fatal
2418 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2419 AFS_TRACE_LEVEL_ERROR,
2420 "AFSSetFileLinkInfo Attempt to link %wZ to alternate directory by handle INVALID_PARAMETER\n",
2421 &pSrcCcb->DirectoryCB->NameInformation.FileName));
2423 try_return( ntStatus = STATUS_INVALID_PARAMETER);
2428 uniFullTargetName.Length = (USHORT)pFileLinkInfo->FileNameLength;
2430 uniFullTargetName.Buffer = (PWSTR)&pFileLinkInfo->FileName;
2432 AFSRetrieveFinalComponent( &uniFullTargetName,
2435 AFSRetrieveParentPath( &uniFullTargetName,
2436 &uniTargetParentName);
2438 if ( uniTargetParentName.Length == 0)
2442 // This is a simple rename. Here the target directory is the same as the source parent directory
2443 // and the name is retrieved from the system buffer information
2446 pTargetParentObject = pSrcParentObject;
2451 // uniTargetParentName contains the directory the renamed object
2452 // will be moved to. Must obtain the TargetParentObject.
2455 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2456 AFS_TRACE_LEVEL_ERROR,
2457 "AFSSetFileLinkInfo Attempt to link %wZ to alternate directory %wZ (NOT_SAME_DEVICE)\n",
2458 &pSrcCcb->DirectoryCB->NameInformation.FileName,
2459 &uniFullTargetName));
2461 try_return( ntStatus = STATUS_NOT_SAME_DEVICE);
2465 pTargetDcb = pTargetParentObject->Fcb;
2471 // So here we have the target directory taken from the targetfile object
2474 pTargetDcb = (AFSFcb *)pTargetFileObj->FsContext;
2476 pTargetDirCcb = (AFSCcb *)pTargetFileObj->FsContext2;
2478 pTargetParentObject = (AFSObjectInfoCB *)pTargetDcb->ObjectInformation;
2481 // Grab the target name which we setup in the IRP_MJ_CREATE handler. By how we set this up
2482 // it is only the target component of the rename operation
2485 uniTargetName = *((PUNICODE_STRING)&pTargetFileObj->FileName);
2489 // The quick check to see if they are self linking.
2490 // Do the names match? Only do this where the parent directories are
2494 if( pTargetParentObject == pSrcParentObject)
2497 if( FsRtlAreNamesEqual( &uniTargetName,
2502 try_return( ntStatus = STATUS_SUCCESS);
2505 bCommonParent = TRUE;
2511 // We do not allow cross-volume hard links
2514 if( pTargetParentObject->VolumeCB != pSrcObject->VolumeCB)
2517 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2518 AFS_TRACE_LEVEL_ERROR,
2519 "AFSSetFileLinkInfo Attempt to link to different volume %wZ\n",
2520 &pSrcCcb->DirectoryCB->NameInformation.FileName));
2522 try_return( ntStatus = STATUS_NOT_SAME_DEVICE);
2526 ulTargetCRC = AFSGenerateCRC( &uniTargetName,
2529 AFSAcquireExcl( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock,
2532 bReleaseTargetDirLock = TRUE;
2534 AFSLocateCaseSensitiveDirEntry( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
2538 if( pTargetDirEntry == NULL)
2542 // Missed so perform a case insensitive lookup
2545 ulTargetCRC = AFSGenerateCRC( &uniTargetName,
2548 AFSLocateCaseInsensitiveDirEntry( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
2553 if ( !BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
2554 pTargetDirEntry == NULL && RtlIsNameLegalDOS8Dot3( &uniTargetName,
2559 // Try the short name
2561 AFSLocateShortNameDirEntry( pTargetParentObject->Specific.Directory.ShortNameTree,
2567 // Increment our ref count on the dir entry
2570 if( pTargetDirEntry != NULL)
2573 ASSERT( BooleanFlagOn( pTargetDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_PARENT_FID) &&
2574 AFSIsEqualFID( &pTargetParentObject->FileId, &pTargetDirEntry->ObjectInformation->ParentFileId));
2576 lCount = InterlockedIncrement( &pTargetDirEntry->DirOpenReferenceCount);
2578 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2579 AFS_TRACE_LEVEL_VERBOSE,
2580 "AFSSetFileLinkInfo Increment count on %wZ DE %p Ccb %p Cnt %d\n",
2581 &pTargetDirEntry->NameInformation.FileName,
2586 ASSERT( lCount >= 0);
2588 if( !pFileLinkInfo->ReplaceIfExists)
2591 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2592 AFS_TRACE_LEVEL_ERROR,
2593 "AFSSetFileLinkInfo Attempt to link with target collision %wZ Target %wZ\n",
2594 &pSrcCcb->DirectoryCB->NameInformation.FileName,
2595 &pTargetDirEntry->NameInformation.FileName));
2597 try_return( ntStatus = STATUS_OBJECT_NAME_COLLISION);
2600 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING | AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2601 AFS_TRACE_LEVEL_ERROR,
2602 "AFSSetFileLinkInfo Target %wZ exists DE %p Count %d, performing delete of target\n",
2603 &pTargetDirEntry->NameInformation.FileName,
2608 // Pull the directory entry from the parent
2611 AFSRemoveDirNodeFromParent( pTargetParentObject,
2615 bTargetEntryExists = TRUE;
2619 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2620 AFS_TRACE_LEVEL_VERBOSE,
2621 "AFSSetFileLinkInfo Target does NOT exist, normal linking\n"));
2625 // OK, this is a simple rename. Issue the rename
2626 // request to the service.
2629 ntStatus = AFSNotifyHardLink( pSrcObject,
2630 &pSrcCcb->AuthGroup,
2632 pTargetDcb->ObjectInformation,
2633 pSrcCcb->DirectoryCB,
2635 pFileLinkInfo->ReplaceIfExists,
2636 &pNewTargetDirEntry);
2638 if( ntStatus != STATUS_REPARSE &&
2639 !NT_SUCCESS( ntStatus))
2642 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2643 AFS_TRACE_LEVEL_ERROR,
2644 "AFSSetFileLinkInfo Failed link of %wZ to target %wZ Status %08lX\n",
2645 &pSrcCcb->DirectoryCB->NameInformation.FileName,
2649 try_return( ntStatus);
2652 if ( ntStatus != STATUS_REPARSE)
2655 AFSInsertDirectoryNode( pTargetDcb->ObjectInformation,
2661 // Send notification for the target link file
2664 if( bTargetEntryExists || pNewTargetDirEntry)
2667 ulNotificationAction = FILE_ACTION_MODIFIED;
2672 ulNotificationAction = FILE_ACTION_ADDED;
2675 AFSFsRtlNotifyFullReportChange( pTargetParentObject,
2677 (ULONG)ulNotifyFilter,
2678 (ULONG)ulNotificationAction);
2682 if( !NT_SUCCESS( ntStatus))
2685 if( bTargetEntryExists)
2688 AFSInsertDirectoryNode( pTargetParentObject,
2694 if( pTargetDirEntry != NULL)
2698 // Release DirOpenReferenceCount obtained above
2701 lCount = InterlockedDecrement( &pTargetDirEntry->DirOpenReferenceCount);
2703 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2704 AFS_TRACE_LEVEL_VERBOSE,
2705 "AFSSetFileLinkInfo Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
2706 &pTargetDirEntry->NameInformation.FileName,
2711 ASSERT( lCount >= 0);
2714 if( pNewTargetDirEntry != NULL)
2718 // Release DirOpenReferenceCount obtained from AFSNotifyHardLink
2721 lCount = InterlockedDecrement( &pNewTargetDirEntry->DirOpenReferenceCount);
2723 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2724 AFS_TRACE_LEVEL_VERBOSE,
2725 "AFSSetFileLinkInfo Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
2726 &pNewTargetDirEntry->NameInformation.FileName,
2731 ASSERT( lCount >= 0);
2734 if( bReleaseTargetDirLock)
2737 AFSReleaseResource( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
2740 if ( pSrcParentObject != NULL)
2743 AFSReleaseObjectInfo( &pSrcParentObject);
2747 // No need to release pTargetParentObject as it is either a copy of pSrcParentObject
2748 // or (AFSFcb *)pTargetFileObj->FsContext->ObjectInformation
2751 pTargetParentObject = NULL;
2758 AFSSetRenameInfo( IN PIRP Irp)
2761 NTSTATUS ntStatus = STATUS_SUCCESS;
2762 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
2763 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2764 AFSFcb *pSrcFcb = NULL, *pTargetDcb = NULL, *pTargetFcb = NULL;
2765 AFSCcb *pSrcCcb = NULL, *pTargetDirCcb = NULL;
2766 PFILE_OBJECT pSrcFileObj = pIrpSp->FileObject;
2767 PFILE_OBJECT pTargetFileObj = pIrpSp->Parameters.SetFile.FileObject;
2768 PFILE_OBJECT pTargetParentFileObj = NULL;
2769 PFILE_RENAME_INFORMATION pRenameInfo = NULL;
2770 UNICODE_STRING uniTargetName, uniSourceName, uniTargetParentName;
2771 BOOLEAN bReplaceIfExists = FALSE;
2772 UNICODE_STRING uniShortName;
2773 AFSDirectoryCB *pTargetDirEntry = NULL;
2774 ULONG ulTargetCRC = 0;
2775 BOOLEAN bTargetEntryExists = FALSE;
2776 AFSObjectInfoCB *pSrcObject = NULL;
2777 AFSObjectInfoCB *pSrcParentObject = NULL, *pTargetParentObject = NULL;
2779 ULONG ulNotificationAction = 0, ulNotifyFilter = 0;
2780 UNICODE_STRING uniFullTargetName;
2781 BOOLEAN bCommonParent = FALSE;
2782 BOOLEAN bReleaseTargetDirLock = FALSE;
2783 BOOLEAN bReleaseSourceDirLock = FALSE;
2784 BOOLEAN bDereferenceTargetParentObject = FALSE;
2785 PERESOURCE pSourceDirLock = NULL;
2791 bReplaceIfExists = pIrpSp->Parameters.SetFile.ReplaceIfExists;
2793 pRenameInfo = (PFILE_RENAME_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
2795 pSrcFcb = (AFSFcb *)pSrcFileObj->FsContext;
2796 pSrcCcb = (AFSCcb *)pSrcFileObj->FsContext2;
2798 pSrcObject = pSrcFcb->ObjectInformation;
2800 if ( BooleanFlagOn( pSrcObject->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
2803 pSrcParentObject = AFSFindObjectInfo( pSrcObject->VolumeCB,
2804 &pSrcObject->ParentFileId,
2808 if( pSrcParentObject == NULL)
2811 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2812 AFS_TRACE_LEVEL_ERROR,
2813 "AFSSetRenameInfo Unable to resolve SrcParentObject (INVALID_PARAMETER)\n"));
2817 try_return( ntStatus = STATUS_INVALID_PARAMETER);
2821 // Perform some basic checks to ensure FS integrity
2824 if( pSrcFcb->Header.NodeTypeCode == AFS_ROOT_FCB)
2828 // Can't rename the root directory
2831 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2832 AFS_TRACE_LEVEL_ERROR,
2833 "AFSSetRenameInfo Attempt to rename root entry\n"));
2835 try_return( ntStatus = STATUS_INVALID_PARAMETER);
2838 if( pSrcFcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB)
2842 // If there are any open children then fail the rename
2845 if( pSrcObject->Specific.Directory.ChildOpenHandleCount > 0)
2848 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2849 AFS_TRACE_LEVEL_ERROR,
2850 "AFSSetRenameInfo Attempt to rename directory with open children %wZ\n",
2851 &pSrcCcb->DirectoryCB->NameInformation.FileName));
2853 try_return( ntStatus = STATUS_ACCESS_DENIED);
2859 // Extract off the final component name from the Fcb
2862 uniSourceName.Length = (USHORT)pSrcCcb->DirectoryCB->NameInformation.FileName.Length;
2863 uniSourceName.MaximumLength = uniSourceName.Length;
2865 uniSourceName.Buffer = pSrcCcb->DirectoryCB->NameInformation.FileName.Buffer;
2868 // Resolve the target fileobject
2871 if( pTargetFileObj == NULL)
2874 if ( pRenameInfo->RootDirectory)
2877 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2878 AFS_TRACE_LEVEL_ERROR,
2879 "AFSSetRenameInfo Handle provided but no FileObject ntStatus INVALID_PARAMETER\n"));
2881 try_return( ntStatus = STATUS_INVALID_PARAMETER);
2886 uniFullTargetName.Length = (USHORT)pRenameInfo->FileNameLength;
2888 uniFullTargetName.Buffer = (PWSTR)&pRenameInfo->FileName;
2890 AFSRetrieveFinalComponent( &uniFullTargetName,
2893 AFSRetrieveParentPath( &uniFullTargetName,
2894 &uniTargetParentName);
2896 if ( uniTargetParentName.Length == 0)
2900 // This is a simple rename. Here the target directory is the same as the source parent directory
2901 // and the name is retrieved from the system buffer information
2904 pTargetParentObject = pSrcParentObject;
2909 // uniTargetParentName contains the directory the renamed object
2910 // will be moved to. Must obtain the TargetParentObject.
2913 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2914 AFS_TRACE_LEVEL_ERROR,
2915 "AFSSetRenameInfo Attempt to move %wZ to %wZ -- not yet supported (NOT_SAME_DEVICE)\n",
2916 &pSrcCcb->DirectoryCB->NameInformation.FileName,
2917 &uniFullTargetName));
2919 try_return( ntStatus = STATUS_NOT_SAME_DEVICE);
2923 pTargetDcb = pTargetParentObject->Fcb;
2929 // So here we have the target directory taken from the targetfile object
2932 pTargetDcb = (AFSFcb *)pTargetFileObj->FsContext;
2934 pTargetDirCcb = (AFSCcb *)pTargetFileObj->FsContext2;
2936 pTargetParentObject = (AFSObjectInfoCB *)pTargetDcb->ObjectInformation;
2939 // Grab the target name which we setup in the IRP_MJ_CREATE handler. By how we set this up
2940 // it is only the target component of the rename operation
2943 uniTargetName = *((PUNICODE_STRING)&pTargetFileObj->FileName);
2947 // The quick check to see if they are not really performing a rename
2948 // Do the names match? Only do this where the parent directories are
2952 if( pTargetParentObject == pSrcParentObject)
2955 if( FsRtlAreNamesEqual( &uniTargetName,
2960 try_return( ntStatus = STATUS_SUCCESS);
2963 bCommonParent = TRUE;
2968 bCommonParent = FALSE;
2972 // We do not allow cross-volume renames to occur
2975 if( pTargetParentObject->VolumeCB != pSrcObject->VolumeCB)
2978 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2979 AFS_TRACE_LEVEL_ERROR,
2980 "AFSSetRenameInfo Attempt to rename directory to different volume %wZ\n",
2981 &pSrcCcb->DirectoryCB->NameInformation.FileName));
2983 try_return( ntStatus = STATUS_NOT_SAME_DEVICE);
2986 ulTargetCRC = AFSGenerateCRC( &uniTargetName,
2989 AFSAcquireExcl( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock,
2992 bReleaseTargetDirLock = TRUE;
2994 if( pTargetParentObject != pSrcParentObject)
2996 AFSAcquireExcl( pSrcParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock,
2999 bReleaseSourceDirLock = TRUE;
3001 pSourceDirLock = pSrcParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock;
3004 AFSLocateCaseSensitiveDirEntry( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
3008 if( pTargetDirEntry == NULL)
3012 // Missed so perform a case insensitive lookup
3015 ulTargetCRC = AFSGenerateCRC( &uniTargetName,
3018 AFSLocateCaseInsensitiveDirEntry( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
3023 if ( !BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
3024 pTargetDirEntry == NULL && RtlIsNameLegalDOS8Dot3( &uniTargetName,
3029 // Try the short name
3031 AFSLocateShortNameDirEntry( pTargetParentObject->Specific.Directory.ShortNameTree,
3037 // Increment our ref count on the dir entry
3040 if( pTargetDirEntry != NULL)
3043 ASSERT( BooleanFlagOn( pTargetDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_PARENT_FID) &&
3044 AFSIsEqualFID( &pTargetParentObject->FileId, &pTargetDirEntry->ObjectInformation->ParentFileId));
3046 lCount = InterlockedIncrement( &pTargetDirEntry->DirOpenReferenceCount);
3048 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3049 AFS_TRACE_LEVEL_VERBOSE,
3050 "AFSSetRenameInfo Increment count on %wZ DE %p Ccb %p Cnt %d\n",
3051 &pTargetDirEntry->NameInformation.FileName,
3056 ASSERT( lCount >= 0);
3058 if( !bReplaceIfExists)
3061 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3062 AFS_TRACE_LEVEL_ERROR,
3063 "AFSSetRenameInfo Attempt to rename directory with target collision %wZ Target %wZ\n",
3064 &pSrcCcb->DirectoryCB->NameInformation.FileName,
3065 &pTargetDirEntry->NameInformation.FileName));
3067 try_return( ntStatus = STATUS_OBJECT_NAME_COLLISION);
3070 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING | AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3071 AFS_TRACE_LEVEL_ERROR,
3072 "AFSSetRenameInfo Target %wZ exists DE %p Count %d, performing delete of target\n",
3073 &pTargetDirEntry->NameInformation.FileName,
3078 // Pull the directory entry from the parent
3081 AFSRemoveDirNodeFromParent( pTargetParentObject,
3085 bTargetEntryExists = TRUE;
3089 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3090 AFS_TRACE_LEVEL_VERBOSE,
3091 "AFSSetRenameInfo Target does NOT exist, normal rename\n"));
3095 // We need to remove the DirEntry from the parent node, update the index
3096 // and reinsert it into the parent tree. Note that for entries with the
3097 // same parent we do not pull the node from the enumeration list
3100 AFSRemoveDirNodeFromParent( pSrcParentObject,
3101 pSrcCcb->DirectoryCB,
3105 // OK, this is a simple rename. Issue the rename
3106 // request to the service.
3109 ntStatus = AFSNotifyRename( pSrcObject,
3110 &pSrcCcb->AuthGroup,
3112 pTargetDcb->ObjectInformation,
3113 pSrcCcb->DirectoryCB,
3117 if( !NT_SUCCESS( ntStatus))
3121 // Attempt to re-insert the directory entry
3124 AFSInsertDirectoryNode( pSrcParentObject,
3125 pSrcCcb->DirectoryCB,
3128 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3129 AFS_TRACE_LEVEL_ERROR,
3130 "AFSSetRenameInfo Failed rename of %wZ to target %wZ Status %08lX\n",
3131 &pSrcCcb->DirectoryCB->NameInformation.FileName,
3135 try_return( ntStatus);
3139 // Set the notification up for the source file
3142 if( pSrcParentObject == pTargetParentObject &&
3143 !bTargetEntryExists)
3146 ulNotificationAction = FILE_ACTION_RENAMED_OLD_NAME;
3151 ulNotificationAction = FILE_ACTION_REMOVED;
3154 if( pSrcObject->FileType == AFS_FILE_TYPE_DIRECTORY)
3157 ulNotifyFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
3162 ulNotifyFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
3165 AFSFsRtlNotifyFullReportChange( pSrcParentObject,
3167 (ULONG)ulNotifyFilter,
3168 (ULONG)ulNotificationAction);
3171 // Update the name in the dir entry.
3174 ntStatus = AFSUpdateDirEntryName( pSrcCcb->DirectoryCB,
3177 if( !NT_SUCCESS( ntStatus))
3181 // Attempt to re-insert the directory entry
3184 AFSInsertDirectoryNode( pSrcParentObject,
3185 pSrcCcb->DirectoryCB,
3188 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3189 AFS_TRACE_LEVEL_ERROR,
3190 "AFSSetRenameInfo Failed update of dir entry %wZ to target %wZ Status %08lX\n",
3191 &pSrcCcb->DirectoryCB->NameInformation.FileName,
3195 try_return( ntStatus);
3199 // Update the object information block, if needed
3202 if( !AFSIsEqualFID( &pSrcObject->FileId,
3206 AFSAcquireExcl( pSrcObject->VolumeCB->ObjectInfoTree.TreeLock,
3210 // Remove the old information entry
3213 AFSRemoveHashEntry( &pSrcObject->VolumeCB->ObjectInfoTree.TreeHead,
3214 &pSrcObject->TreeEntry);
3216 RtlCopyMemory( &pSrcObject->FileId,
3218 sizeof( AFSFileID));
3221 // Insert the entry into the new object table.
3224 pSrcObject->TreeEntry.HashIndex = AFSCreateLowIndex( &pSrcObject->FileId);
3226 if( pSrcObject->VolumeCB->ObjectInfoTree.TreeHead == NULL)
3229 pSrcObject->VolumeCB->ObjectInfoTree.TreeHead = &pSrcObject->TreeEntry;
3234 if ( !NT_SUCCESS( AFSInsertHashEntry( pSrcObject->VolumeCB->ObjectInfoTree.TreeHead,
3235 &pSrcObject->TreeEntry)))
3239 // Lost a race, an ObjectInfo object already exists for this FID.
3240 // Let this copy be garbage collected.
3243 ClearFlag( pSrcObject->Flags, AFS_OBJECT_INSERTED_HASH_TREE);
3247 AFSReleaseResource( pSrcObject->VolumeCB->ObjectInfoTree.TreeLock);
3251 // Update the hash values for the name trees.
3254 pSrcCcb->DirectoryCB->CaseSensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pSrcCcb->DirectoryCB->NameInformation.FileName,
3257 pSrcCcb->DirectoryCB->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pSrcCcb->DirectoryCB->NameInformation.FileName,
3260 if( !BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
3261 pSrcCcb->DirectoryCB->NameInformation.ShortNameLength > 0 &&
3262 !RtlIsNameLegalDOS8Dot3( &pSrcCcb->DirectoryCB->NameInformation.FileName,
3267 uniShortName.Length = pSrcCcb->DirectoryCB->NameInformation.ShortNameLength;
3268 uniShortName.MaximumLength = uniShortName.Length;
3269 uniShortName.Buffer = pSrcCcb->DirectoryCB->NameInformation.ShortName;
3271 pSrcCcb->DirectoryCB->Type.Data.ShortNameTreeEntry.HashIndex = AFSGenerateCRC( &uniShortName,
3274 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3275 AFS_TRACE_LEVEL_VERBOSE,
3276 "AFSSetRenameInfo Initialized short name hash for %wZ longname %wZ\n",
3278 &pSrcCcb->DirectoryCB->NameInformation.FileName));
3283 pSrcCcb->DirectoryCB->Type.Data.ShortNameTreeEntry.HashIndex = 0;
3290 // Update the file index for the object in the new parent
3293 pSrcCcb->DirectoryCB->FileIndex = (ULONG)InterlockedIncrement( &pTargetParentObject->Specific.Directory.DirectoryNodeHdr.ContentIndex);
3297 // Re-insert the directory entry
3300 AFSInsertDirectoryNode( pTargetParentObject,
3301 pSrcCcb->DirectoryCB,
3305 // Update the parent pointer in the source object if they are different
3308 if( pSrcParentObject != pTargetParentObject)
3311 lCount = InterlockedDecrement( &pSrcParentObject->Specific.Directory.ChildOpenHandleCount);
3313 lCount = InterlockedDecrement( &pSrcParentObject->Specific.Directory.ChildOpenReferenceCount);
3315 lCount = InterlockedIncrement( &pTargetParentObject->Specific.Directory.ChildOpenHandleCount);
3317 lCount = InterlockedIncrement( &pTargetParentObject->Specific.Directory.ChildOpenReferenceCount);
3321 // Guaranteed to be in the same volume
3324 AFSAcquireExcl( pSrcParentObject->VolumeCB->ObjectInfoTree.TreeLock,
3327 lCount = AFSObjectInfoIncrement( pTargetParentObject,
3328 AFS_OBJECT_REFERENCE_CHILD);
3330 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
3331 AFS_TRACE_LEVEL_VERBOSE,
3332 "AFSSetRenameInfo Increment count on parent object %p Cnt %d\n",
3333 pTargetParentObject,
3336 lCount = AFSObjectInfoDecrement( pSrcParentObject,
3337 AFS_OBJECT_REFERENCE_CHILD);
3339 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
3340 AFS_TRACE_LEVEL_VERBOSE,
3341 "AFSSetRenameInfo Decrement count on parent object %p Cnt %d\n",
3345 pSrcObject->ParentFileId = pTargetParentObject->FileId;
3347 SetFlag( pSrcObject->Flags, AFS_OBJECT_FLAGS_PARENT_FID);
3349 AFSReleaseResource( pSrcParentObject->VolumeCB->ObjectInfoTree.TreeLock);
3351 ulNotificationAction = FILE_ACTION_ADDED;
3356 ulNotificationAction = FILE_ACTION_RENAMED_NEW_NAME;
3360 // Now update the notification for the target file
3363 AFSFsRtlNotifyFullReportChange( pTargetParentObject,
3365 (ULONG)ulNotifyFilter,
3366 (ULONG)ulNotificationAction);
3369 // If we performed the rename of the target because it existed, we now need to
3370 // delete the tmp target we created above
3373 if( bTargetEntryExists)
3376 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3377 AFS_TRACE_LEVEL_VERBOSE,
3378 "AFSSetRenameInfo Setting DELETE flag in dir entry %p name %wZ\n",
3380 &pTargetDirEntry->NameInformation.FileName));
3382 SetFlag( pTargetDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
3385 // Try and purge the cache map if this is a file
3388 if( pTargetDirEntry->ObjectInformation->FileType == AFS_FILE_TYPE_FILE &&
3389 pTargetDirEntry->ObjectInformation->Fcb != NULL &&
3390 pTargetDirEntry->DirOpenReferenceCount > 1)
3393 pTargetFcb = pTargetDirEntry->ObjectInformation->Fcb;
3396 ASSERT( pTargetDirEntry->DirOpenReferenceCount > 0);
3398 lCount = InterlockedDecrement( &pTargetDirEntry->DirOpenReferenceCount); // The count we added above
3400 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3401 AFS_TRACE_LEVEL_VERBOSE,
3402 "AFSSetRenameInfo Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
3403 &pTargetDirEntry->NameInformation.FileName,
3408 ASSERT( lCount >= 0);
3411 pTargetDirEntry->NameArrayReferenceCount <= 0)
3414 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3415 AFS_TRACE_LEVEL_VERBOSE,
3416 "AFSSetRenameInfo Deleting dir entry %p name %wZ\n",
3418 &pTargetDirEntry->NameInformation.FileName));
3420 AFSDeleteDirEntry( pTargetParentObject,
3424 pTargetDirEntry = NULL;
3426 if ( pTargetFcb != NULL)
3430 // Do not hold TreeLocks across the MmForceSectionClosed() call as
3431 // it can deadlock with Trend Micro's TmPreFlt!TmpQueryFullName
3434 if( bReleaseTargetDirLock)
3436 AFSReleaseResource( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
3438 bReleaseTargetDirLock = FALSE;
3441 if( bReleaseSourceDirLock)
3444 AFSReleaseResource( pSourceDirLock);
3446 bReleaseSourceDirLock = FALSE;
3450 // MmForceSectionClosed() can eventually call back into AFSCleanup
3451 // which will need to acquire Fcb->Resource exclusively. Failure
3452 // to obtain it here before holding the SectionObjectResource will
3453 // permit the locks to be obtained out of order risking a deadlock.
3456 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3457 AFS_TRACE_LEVEL_VERBOSE,
3458 "AFSSetRenameInfo Acquiring Fcb lock %p EXCL %08lX\n",
3459 &pTargetFcb->NPFcb->Resource,
3460 PsGetCurrentThread()));
3462 AFSAcquireExcl( &pTargetFcb->NPFcb->Resource,
3465 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3466 AFS_TRACE_LEVEL_VERBOSE,
3467 "AFSSetRenameInfo Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
3468 &pTargetFcb->NPFcb->SectionObjectResource,
3469 PsGetCurrentThread()));
3471 AFSAcquireExcl( &pTargetFcb->NPFcb->SectionObjectResource,
3478 // Close the section in the event it was mapped
3481 if( !MmForceSectionClosed( &pTargetFcb->NPFcb->SectionObjectPointers,
3485 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3486 AFS_TRACE_LEVEL_ERROR,
3487 "AFSSetRenameInfo Failed to delete section for target file %wZ\n",
3491 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
3494 ntStatus = GetExceptionCode();
3498 "EXCEPTION - AFSSetRenameInfo MmForceSectionClosed failed FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
3499 pTargetFcb->ObjectInformation->FileId.Cell,
3500 pTargetFcb->ObjectInformation->FileId.Volume,
3501 pTargetFcb->ObjectInformation->FileId.Vnode,
3502 pTargetFcb->ObjectInformation->FileId.Unique,
3506 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3507 AFS_TRACE_LEVEL_VERBOSE,
3508 "AFSSetRenameInfo Releasing Fcb SectionObject lock %p EXCL %08lX\n",
3509 &pTargetFcb->NPFcb->SectionObjectResource,
3510 PsGetCurrentThread()));
3512 AFSReleaseResource( &pTargetFcb->NPFcb->SectionObjectResource);
3514 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3515 AFS_TRACE_LEVEL_VERBOSE,
3516 "AFSSetRenameInfo Releasing Fcb lock %p EXCL %08lX\n",
3517 &pTargetFcb->NPFcb->Resource,
3518 PsGetCurrentThread()));
3520 AFSReleaseResource( &pTargetFcb->NPFcb->Resource);
3526 if( !NT_SUCCESS( ntStatus))
3529 if( bTargetEntryExists)
3532 ASSERT( pTargetParentObject != NULL);
3534 AFSInsertDirectoryNode( pTargetParentObject,
3540 if( pTargetDirEntry != NULL)
3543 lCount = InterlockedDecrement( &pTargetDirEntry->DirOpenReferenceCount);
3545 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3546 AFS_TRACE_LEVEL_VERBOSE,
3547 "AFSSetRenameInfo Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
3548 &pTargetDirEntry->NameInformation.FileName,
3553 ASSERT( lCount >= 0);
3556 if( bReleaseTargetDirLock)
3559 AFSReleaseResource( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
3562 if( bReleaseSourceDirLock)
3565 AFSReleaseResource( pSourceDirLock);
3568 if ( bDereferenceTargetParentObject)
3571 ObDereferenceObject( pTargetParentFileObj);
3574 if ( pSrcParentObject != NULL)
3577 AFSReleaseObjectInfo( &pSrcParentObject);
3581 // No need to release pTargetParentObject as it is either a copy of pSrcParentObject
3582 // or (AFSFcb *)pTargetFileObj->FsContext->ObjectInformation
3585 pTargetParentObject = NULL;
3592 AFSSetPositionInfo( IN PIRP Irp,
3593 IN AFSDirectoryCB *DirectoryCB)
3595 UNREFERENCED_PARAMETER(DirectoryCB);
3596 NTSTATUS ntStatus = STATUS_SUCCESS;
3597 PFILE_POSITION_INFORMATION pBuffer;
3598 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
3600 pBuffer = (PFILE_POSITION_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
3602 pIrpSp->FileObject->CurrentByteOffset.QuadPart = pBuffer->CurrentByteOffset.QuadPart;
3608 AFSSetAllocationInfo( IN PIRP Irp,
3609 IN AFSDirectoryCB *DirectoryCB)
3611 UNREFERENCED_PARAMETER(DirectoryCB);
3612 NTSTATUS ntStatus = STATUS_SUCCESS;
3613 PFILE_ALLOCATION_INFORMATION pBuffer;
3614 BOOLEAN bReleasePaging = FALSE;
3615 BOOLEAN bTellCc = FALSE;
3616 BOOLEAN bTellService = FALSE;
3617 BOOLEAN bUserMapped = FALSE;
3618 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
3619 PFILE_OBJECT pFileObject = pIrpSp->FileObject;
3620 AFSFcb *pFcb = NULL;
3621 AFSCcb *pCcb = NULL;
3622 LARGE_INTEGER liSaveAlloc;
3623 LARGE_INTEGER liSaveFileSize;
3624 LARGE_INTEGER liSaveVDL;
3626 pBuffer = (PFILE_ALLOCATION_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
3628 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
3630 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
3633 // save values to put back
3635 liSaveAlloc = pFcb->Header.AllocationSize;
3636 liSaveFileSize = pFcb->Header.FileSize;
3637 liSaveVDL = pFcb->Header.ValidDataLength;
3639 if( pFcb->Header.AllocationSize.QuadPart == pBuffer->AllocationSize.QuadPart ||
3640 pIrpSp->Parameters.SetFile.AdvanceOnly)
3642 return STATUS_SUCCESS ;
3645 if( pFcb->Header.AllocationSize.QuadPart > pBuffer->AllocationSize.QuadPart)
3648 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3649 AFS_TRACE_LEVEL_VERBOSE,
3650 "AFSSetAllocationInfo Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
3651 &pFcb->NPFcb->SectionObjectResource,
3652 PsGetCurrentThread()));
3654 AFSAcquireExcl( &pFcb->NPFcb->SectionObjectResource,
3660 bUserMapped = !MmCanFileBeTruncated( pFileObject->SectionObjectPointer,
3661 &pBuffer->AllocationSize);
3663 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
3666 bUserMapped = FALSE;
3668 ntStatus = GetExceptionCode();
3672 "EXCEPTION - AFSSetAllocationInfo MmCanFileBeTruncated failed FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
3673 pFcb->ObjectInformation->FileId.Cell,
3674 pFcb->ObjectInformation->FileId.Volume,
3675 pFcb->ObjectInformation->FileId.Vnode,
3676 pFcb->ObjectInformation->FileId.Unique,
3680 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3681 AFS_TRACE_LEVEL_VERBOSE,
3682 "AFSSetAllocationInfo Releasing Fcb SectionObject lock %p EXCL %08lX\n",
3683 &pFcb->NPFcb->SectionObjectResource,
3684 PsGetCurrentThread()));
3686 AFSReleaseResource( &pFcb->NPFcb->SectionObjectResource);
3689 // Truncating the file
3694 ntStatus = STATUS_USER_MAPPED_FILE ;
3700 // If this is a truncation we need to grab the paging IO resource.
3703 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3704 AFS_TRACE_LEVEL_VERBOSE,
3705 "AFSSetAllocationInfo Acquiring Fcb PagingIo lock %p EXCL %08lX\n",
3706 &pFcb->NPFcb->PagingResource,
3707 PsGetCurrentThread()));
3709 AFSAcquireExcl( &pFcb->NPFcb->PagingResource,
3712 bReleasePaging = TRUE;
3715 // Must drop the Fcb Resource. When changing the file size
3716 // a deadlock can occur with Trend Micro's filter if the file
3717 // size is set to zero.
3720 AFSReleaseResource( &pFcb->NPFcb->Resource);
3722 pFcb->Header.AllocationSize = pBuffer->AllocationSize;
3724 pFcb->ObjectInformation->AllocationSize = pBuffer->AllocationSize;
3727 // Tell Cc that Allocation is moved.
3731 if( pFcb->Header.FileSize.QuadPart > pBuffer->AllocationSize.QuadPart)
3734 // We are pulling the EOF back as well so we need to tell
3737 bTellService = TRUE;
3739 pFcb->Header.FileSize = pBuffer->AllocationSize;
3741 pFcb->ObjectInformation->EndOfFile = pBuffer->AllocationSize;
3749 // Tell Cc if allocation is increased.
3752 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3753 AFS_TRACE_LEVEL_VERBOSE,
3754 "AFSSetAllocationInfo Acquiring Fcb PagingIo lock %p EXCL %08lX\n",
3755 &pFcb->NPFcb->PagingResource,
3756 PsGetCurrentThread()));
3758 AFSAcquireExcl( &pFcb->NPFcb->PagingResource,
3761 bReleasePaging = TRUE;
3764 // Must drop the Fcb Resource. When changing the file size
3765 // a deadlock can occur with Trend Micro's filter if the file
3766 // size is set to zero.
3769 AFSReleaseResource( &pFcb->NPFcb->Resource);
3771 bTellCc = pBuffer->AllocationSize.QuadPart > pFcb->Header.AllocationSize.QuadPart;
3773 pFcb->Header.AllocationSize = pBuffer->AllocationSize;
3775 pFcb->ObjectInformation->AllocationSize = pBuffer->AllocationSize;
3779 // Now Tell the server if we have to
3784 ASSERT( BooleanFlagOn( pFcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_PARENT_FID));
3786 ntStatus = AFSUpdateFileInformation( &pFcb->ObjectInformation->ParentFileId,
3787 pFcb->ObjectInformation,
3791 if (NT_SUCCESS(ntStatus))
3794 // Trim extents if we told the service - the update has done an implicit
3795 // trim at the service.
3799 AFSTrimExtents( pFcb,
3800 &pFcb->Header.FileSize);
3803 KeQuerySystemTime( &pFcb->ObjectInformation->ChangeTime);
3805 SetFlag( pFcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_CHANGE_TIME);
3808 CcIsFileCached( pFileObject))
3810 CcSetFileSizes( pFileObject,
3811 (PCC_FILE_SIZES)&pFcb->Header.AllocationSize);
3817 // Put the saved values back
3819 pFcb->Header.ValidDataLength = liSaveVDL;
3820 pFcb->Header.FileSize = liSaveFileSize;
3821 pFcb->Header.AllocationSize = liSaveAlloc;
3822 pFcb->ObjectInformation->EndOfFile = liSaveFileSize;
3823 pFcb->ObjectInformation->AllocationSize = liSaveAlloc;
3829 AFSReleaseResource( &pFcb->NPFcb->PagingResource);
3831 AFSAcquireExcl( &pFcb->NPFcb->Resource,
3839 AFSSetEndOfFileInfo( IN PIRP Irp,
3840 IN AFSDirectoryCB *DirectoryCB)
3842 UNREFERENCED_PARAMETER(DirectoryCB);
3843 NTSTATUS ntStatus = STATUS_SUCCESS;
3844 PFILE_END_OF_FILE_INFORMATION pBuffer;
3845 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
3846 PFILE_OBJECT pFileObject = pIrpSp->FileObject;
3847 LARGE_INTEGER liSaveSize;
3848 LARGE_INTEGER liSaveVDL;
3849 LARGE_INTEGER liSaveAlloc;
3850 BOOLEAN bModified = FALSE;
3851 BOOLEAN bReleasePaging = FALSE;
3852 BOOLEAN bTruncated = FALSE;
3853 BOOLEAN bUserMapped = FALSE;
3854 AFSFcb *pFcb = NULL;
3855 AFSCcb *pCcb = NULL;
3857 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
3859 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
3861 pBuffer = (PFILE_END_OF_FILE_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
3863 liSaveSize = pFcb->Header.FileSize;
3864 liSaveAlloc = pFcb->Header.AllocationSize;
3865 liSaveVDL = pFcb->Header.ValidDataLength;
3867 if( pFcb->Header.FileSize.QuadPart != pBuffer->EndOfFile.QuadPart &&
3868 !pIrpSp->Parameters.SetFile.AdvanceOnly)
3871 if( pBuffer->EndOfFile.QuadPart < pFcb->Header.FileSize.QuadPart)
3874 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3875 AFS_TRACE_LEVEL_VERBOSE,
3876 "AFSSetEndOfFileInfo Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
3877 &pFcb->NPFcb->SectionObjectResource,
3878 PsGetCurrentThread()));
3880 AFSAcquireExcl( &pFcb->NPFcb->SectionObjectResource,
3886 bUserMapped = !MmCanFileBeTruncated( pFileObject->SectionObjectPointer,
3887 &pBuffer->EndOfFile);
3889 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
3892 bUserMapped = FALSE;
3894 ntStatus = GetExceptionCode();
3898 "EXCEPTION - AFSSetEndOfFileInfo MmCanFileBeTruncated failed FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
3899 pFcb->ObjectInformation->FileId.Cell,
3900 pFcb->ObjectInformation->FileId.Volume,
3901 pFcb->ObjectInformation->FileId.Vnode,
3902 pFcb->ObjectInformation->FileId.Unique,
3906 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3907 AFS_TRACE_LEVEL_VERBOSE,
3908 "AFSSetEndOfFileInfo Releasing Fcb SectionObject lock %p EXCL %08lX\n",
3909 &pFcb->NPFcb->SectionObjectResource,
3910 PsGetCurrentThread()));
3912 AFSReleaseResource( &pFcb->NPFcb->SectionObjectResource);
3914 // Truncating the file
3918 ntStatus = STATUS_USER_MAPPED_FILE;
3924 // If this is a truncation we need to grab the paging
3927 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3928 AFS_TRACE_LEVEL_VERBOSE,
3929 "AFSSetAllocationInfo Acquiring Fcb PagingIo lock %p EXCL %08lX\n",
3930 &pFcb->NPFcb->PagingResource,
3931 PsGetCurrentThread()));
3933 AFSAcquireExcl( &pFcb->NPFcb->PagingResource,
3936 bReleasePaging = TRUE;
3939 // Must drop the Fcb Resource. When changing the file size
3940 // a deadlock can occur with Trend Micro's filter if the file
3941 // size is set to zero.
3944 AFSReleaseResource( &pFcb->NPFcb->Resource);
3946 pFcb->Header.AllocationSize = pBuffer->EndOfFile;
3948 pFcb->Header.FileSize = pBuffer->EndOfFile;
3950 pFcb->ObjectInformation->EndOfFile = pBuffer->EndOfFile;
3952 pFcb->ObjectInformation->AllocationSize = pBuffer->EndOfFile;
3954 if( pFcb->Header.ValidDataLength.QuadPart > pFcb->Header.FileSize.QuadPart)
3957 pFcb->Header.ValidDataLength = pFcb->Header.FileSize;
3969 // extending the file, move EOF
3973 // If this is a truncation we need to grab the paging
3976 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3977 AFS_TRACE_LEVEL_VERBOSE,
3978 "AFSSetAllocationInfo Acquiring Fcb PagingIo lock %p EXCL %08lX\n",
3979 &pFcb->NPFcb->PagingResource,
3980 PsGetCurrentThread()));
3982 AFSAcquireExcl( &pFcb->NPFcb->PagingResource,
3985 bReleasePaging = TRUE;
3988 // Must drop the Fcb Resource. When changing the file size
3989 // a deadlock can occur with Trend Micro's filter if the file
3990 // size is set to zero.
3993 AFSReleaseResource( &pFcb->NPFcb->Resource);
3995 pFcb->Header.FileSize = pBuffer->EndOfFile;
3997 pFcb->ObjectInformation->EndOfFile = pBuffer->EndOfFile;
3999 if (pFcb->Header.FileSize.QuadPart > pFcb->Header.AllocationSize.QuadPart)
4002 // And Allocation as needed.
4004 pFcb->Header.AllocationSize = pBuffer->EndOfFile;
4006 pFcb->ObjectInformation->AllocationSize = pBuffer->EndOfFile;
4016 KeQuerySystemTime( &pFcb->ObjectInformation->ChangeTime);
4018 SetFlag( pFcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_CHANGE_TIME);
4024 ASSERT( BooleanFlagOn( pFcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_PARENT_FID));
4026 ntStatus = AFSUpdateFileInformation( &pFcb->ObjectInformation->ParentFileId,
4027 pFcb->ObjectInformation,
4030 if( NT_SUCCESS(ntStatus))
4033 // We are now good to go so tell CC.
4035 CcSetFileSizes( pFileObject,
4036 (PCC_FILE_SIZES)&pFcb->Header.AllocationSize);
4039 // And give up those extents
4044 AFSTrimExtents( pFcb,
4045 &pFcb->Header.FileSize);
4050 pFcb->Header.ValidDataLength = liSaveVDL;
4051 pFcb->Header.FileSize = liSaveSize;
4052 pFcb->Header.AllocationSize = liSaveAlloc;
4053 pFcb->ObjectInformation->EndOfFile = liSaveSize;
4054 pFcb->ObjectInformation->AllocationSize = liSaveAlloc;
4061 AFSReleaseResource( &pFcb->NPFcb->PagingResource);
4063 AFSAcquireExcl( &pFcb->NPFcb->Resource,
4071 AFSProcessShareSetInfo( IN IRP *Irp,
4076 UNREFERENCED_PARAMETER(Fcb);
4077 NTSTATUS ntStatus = STATUS_SUCCESS;
4078 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
4079 FILE_INFORMATION_CLASS ulFileInformationClass;
4080 void *pPipeInfo = NULL;
4084 ulFileInformationClass = pIrpSp->Parameters.SetFile.FileInformationClass;
4086 AFSDbgTrace(( AFS_SUBSYSTEM_PIPE_PROCESSING,
4087 AFS_TRACE_LEVEL_VERBOSE,
4088 "AFSProcessShareSetInfo On pipe %wZ Class %08lX\n",
4089 &Ccb->DirectoryCB->NameInformation.FileName,
4090 ulFileInformationClass));
4092 pPipeInfo = AFSLockSystemBuffer( Irp,
4093 pIrpSp->Parameters.SetFile.Length);
4095 if( pPipeInfo == NULL)
4098 AFSDbgTrace(( AFS_SUBSYSTEM_PIPE_PROCESSING,
4099 AFS_TRACE_LEVEL_ERROR,
4100 "AFSProcessShareSetInfo Failed to lock buffer on pipe %wZ\n",
4101 &Ccb->DirectoryCB->NameInformation.FileName));
4103 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4107 // Send the request to the service
4110 ntStatus = AFSNotifySetPipeInfo( Ccb,
4111 (ULONG)ulFileInformationClass,
4112 pIrpSp->Parameters.SetFile.Length,
4115 if( !NT_SUCCESS( ntStatus))
4118 AFSDbgTrace(( AFS_SUBSYSTEM_PIPE_PROCESSING,
4119 AFS_TRACE_LEVEL_ERROR,
4120 "AFSProcessShareSetInfo Failed to send request to service on pipe %wZ Status %08lX\n",
4121 &Ccb->DirectoryCB->NameInformation.FileName,
4124 try_return( ntStatus);
4127 AFSDbgTrace(( AFS_SUBSYSTEM_PIPE_PROCESSING,
4128 AFS_TRACE_LEVEL_VERBOSE,
4129 "AFSProcessShareSetInfo Completed request on pipe %wZ Class %08lX\n",
4130 &Ccb->DirectoryCB->NameInformation.FileName,
4131 ulFileInformationClass));
4142 AFSProcessShareQueryInfo( IN IRP *Irp,
4147 UNREFERENCED_PARAMETER(Fcb);
4148 NTSTATUS ntStatus = STATUS_SUCCESS;
4149 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
4150 FILE_INFORMATION_CLASS ulFileInformationClass;
4151 void *pPipeInfo = NULL;
4156 ulFileInformationClass = pIrpSp->Parameters.QueryFile.FileInformationClass;
4158 AFSDbgTrace(( AFS_SUBSYSTEM_PIPE_PROCESSING,
4159 AFS_TRACE_LEVEL_VERBOSE,
4160 "AFSProcessShareQueryInfo On pipe %wZ Class %08lX\n",
4161 &Ccb->DirectoryCB->NameInformation.FileName,
4162 ulFileInformationClass));
4164 pPipeInfo = AFSLockSystemBuffer( Irp,
4165 pIrpSp->Parameters.QueryFile.Length);
4167 if( pPipeInfo == NULL)
4170 AFSDbgTrace(( AFS_SUBSYSTEM_PIPE_PROCESSING,
4171 AFS_TRACE_LEVEL_ERROR,
4172 "AFSProcessShareQueryInfo Failed to lock buffer on pipe %wZ\n",
4173 &Ccb->DirectoryCB->NameInformation.FileName));
4175 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4179 // Send the request to the service
4182 ntStatus = AFSNotifyQueryPipeInfo( Ccb,
4183 (ULONG)ulFileInformationClass,
4184 pIrpSp->Parameters.QueryFile.Length,
4186 (ULONG *)&Irp->IoStatus.Information);
4188 if( !NT_SUCCESS( ntStatus))
4191 AFSDbgTrace(( AFS_SUBSYSTEM_PIPE_PROCESSING,
4192 AFS_TRACE_LEVEL_ERROR,
4193 "AFSProcessShareQueryInfo Failed to send request to service on pipe %wZ Status %08lX\n",
4194 &Ccb->DirectoryCB->NameInformation.FileName,
4197 try_return( ntStatus);
4200 AFSDbgTrace(( AFS_SUBSYSTEM_PIPE_PROCESSING,
4201 AFS_TRACE_LEVEL_VERBOSE,
4202 "AFSProcessShareQueryInfo Completed request on pipe %wZ Class %08lX\n",
4203 &Ccb->DirectoryCB->NameInformation.FileName,
4204 ulFileInformationClass));
4215 AFSProcessPIOCtlQueryInfo( IN IRP *Irp,
4218 IN OUT LONG *Length)
4221 UNREFERENCED_PARAMETER(Fcb);
4222 UNREFERENCED_PARAMETER(Ccb);
4223 NTSTATUS ntStatus = STATUS_SUCCESS;
4224 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
4225 FILE_INFORMATION_CLASS ulFileInformationClass;
4230 ulFileInformationClass = pIrpSp->Parameters.QueryFile.FileInformationClass;
4232 switch( ulFileInformationClass)
4235 case FileBasicInformation:
4238 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4239 AFS_TRACE_LEVEL_VERBOSE,
4240 "AFSProcessPIOCtlQueryInfo (FileBasicInformation)\n"));
4242 if ( *Length >= sizeof( FILE_BASIC_INFORMATION))
4244 PFILE_BASIC_INFORMATION pBasic = (PFILE_BASIC_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
4246 pBasic->CreationTime.QuadPart = 0;
4247 pBasic->LastAccessTime.QuadPart = 0;
4248 pBasic->ChangeTime.QuadPart = 0;
4249 pBasic->LastWriteTime.QuadPart = 0;
4250 pBasic->FileAttributes = FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM;
4252 *Length -= sizeof( FILE_BASIC_INFORMATION);
4256 ntStatus = STATUS_BUFFER_TOO_SMALL;
4262 case FileStandardInformation:
4265 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4266 AFS_TRACE_LEVEL_VERBOSE,
4267 "AFSProcessPIOCtlQueryInfo (FileStandardInformation)\n"));
4269 if ( *Length >= sizeof( FILE_STANDARD_INFORMATION))
4271 PFILE_STANDARD_INFORMATION pStandard = (PFILE_STANDARD_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
4273 pStandard->NumberOfLinks = 1;
4274 pStandard->DeletePending = 0;
4275 pStandard->AllocationSize.QuadPart = 0;
4276 pStandard->EndOfFile.QuadPart = 0;
4277 pStandard->Directory = 0;
4279 *Length -= sizeof( FILE_STANDARD_INFORMATION);
4283 ntStatus = STATUS_BUFFER_TOO_SMALL;
4289 case FileNormalizedNameInformation:
4290 case FileNameInformation:
4293 ULONG ulCopyLength = 0;
4294 AFSFcb *pFcb = NULL;
4295 AFSCcb *pCcb = NULL;
4296 USHORT usFullNameLength = 0;
4297 PFILE_NAME_INFORMATION pNameInfo = (PFILE_NAME_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
4298 UNICODE_STRING uniName;
4300 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4301 AFS_TRACE_LEVEL_VERBOSE,
4302 "AFSProcessPIOCtlQueryInfo (FileNameInformation)\n"));
4304 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
4305 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
4307 if( *Length < FIELD_OFFSET( FILE_NAME_INFORMATION, FileName))
4309 ntStatus = STATUS_BUFFER_TOO_SMALL;
4313 RtlZeroMemory( pNameInfo,
4316 usFullNameLength = sizeof( WCHAR) +
4317 AFSServerName.Length +
4318 pCcb->FullFileName.Length;
4320 if( *Length >= (LONG)(FIELD_OFFSET( FILE_NAME_INFORMATION, FileName) + (LONG)usFullNameLength))
4322 ulCopyLength = (LONG)usFullNameLength;
4326 ulCopyLength = *Length - FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
4327 ntStatus = STATUS_BUFFER_OVERFLOW;
4330 pNameInfo->FileNameLength = (ULONG)usFullNameLength;
4332 *Length -= FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
4334 if( ulCopyLength > 0)
4337 pNameInfo->FileName[ 0] = L'\\';
4338 ulCopyLength -= sizeof( WCHAR);
4340 *Length -= sizeof( WCHAR);
4342 if( ulCopyLength >= AFSServerName.Length)
4345 RtlCopyMemory( &pNameInfo->FileName[ 1],
4346 AFSServerName.Buffer,
4347 AFSServerName.Length);
4349 ulCopyLength -= AFSServerName.Length;
4350 *Length -= AFSServerName.Length;
4352 if( ulCopyLength >= pCcb->FullFileName.Length)
4355 RtlCopyMemory( &pNameInfo->FileName[ 1 + (AFSServerName.Length/sizeof( WCHAR))],
4356 pCcb->FullFileName.Buffer,
4357 pCcb->FullFileName.Length);
4359 ulCopyLength -= pCcb->FullFileName.Length;
4360 *Length -= pCcb->FullFileName.Length;
4362 uniName.Length = (USHORT)pNameInfo->FileNameLength;
4363 uniName.MaximumLength = uniName.Length;
4364 uniName.Buffer = pNameInfo->FileName;
4369 RtlCopyMemory( &pNameInfo->FileName[ 1 + (AFSServerName.Length/sizeof( WCHAR))],
4370 pCcb->FullFileName.Buffer,
4373 *Length -= ulCopyLength;
4375 uniName.Length = (USHORT)(sizeof( WCHAR) + AFSServerName.Length + ulCopyLength);
4376 uniName.MaximumLength = uniName.Length;
4377 uniName.Buffer = pNameInfo->FileName;
4380 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4381 AFS_TRACE_LEVEL_VERBOSE,
4382 "AFSProcessPIOCtlQueryInfo (FileNameInformation) Returning %wZ\n",
4390 case FileInternalInformation:
4393 PFILE_INTERNAL_INFORMATION pInternalInfo = (PFILE_INTERNAL_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
4395 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4396 AFS_TRACE_LEVEL_VERBOSE,
4397 "AFSProcessPIOCtlQueryInfo (FileInternalInformation)\n"));
4399 if( *Length >= sizeof( FILE_INTERNAL_INFORMATION))
4402 pInternalInfo->IndexNumber.HighPart = 0;
4404 pInternalInfo->IndexNumber.LowPart = 0;
4406 *Length -= sizeof( FILE_INTERNAL_INFORMATION);
4411 ntStatus = STATUS_BUFFER_TOO_SMALL;
4417 case FileAllInformation:
4419 ntStatus = STATUS_INVALID_PARAMETER;
4421 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4422 AFS_TRACE_LEVEL_WARNING,
4423 "AFSProcessPIOCtlQueryInfo (FileAllInformation) Not Implemented\n"));
4428 case FileEaInformation:
4430 ntStatus = STATUS_INVALID_PARAMETER;
4432 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4433 AFS_TRACE_LEVEL_WARNING,
4434 "AFSProcessPIOCtlQueryInfo (FileEaInformation) Not Implemented\n"));
4439 case FilePositionInformation:
4441 ntStatus = STATUS_INVALID_PARAMETER;
4443 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4444 AFS_TRACE_LEVEL_WARNING,
4445 "AFSProcessPIOCtlQueryInfo (FilePositionInformation) Not Implemented\n"));
4450 case FileAlternateNameInformation:
4452 ntStatus = STATUS_INVALID_PARAMETER;
4454 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4455 AFS_TRACE_LEVEL_WARNING,
4456 "AFSProcessPIOCtlQueryInfo (FileAlternateNameInformation) Not Implemented\n"));
4461 case FileNetworkOpenInformation:
4463 ntStatus = STATUS_INVALID_PARAMETER;
4465 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4466 AFS_TRACE_LEVEL_WARNING,
4467 "AFSProcessPIOCtlQueryInfo (FileNetworkOpenInformation) Not Implemented\n"));
4472 case FileStreamInformation:
4474 ntStatus = STATUS_INVALID_PARAMETER;
4476 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4477 AFS_TRACE_LEVEL_WARNING,
4478 "AFSProcessPIOCtlQueryInfo (FileStreamInformation) Not Implemented\n"));
4483 case FileAttributeTagInformation:
4485 ntStatus = STATUS_INVALID_PARAMETER;
4487 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4488 AFS_TRACE_LEVEL_WARNING,
4489 "AFSProcessPIOCtlQueryInfo (FileAttributeTagInformation) Not Implemented\n"));
4494 case FileRemoteProtocolInformation:
4496 ntStatus = STATUS_INVALID_PARAMETER;
4498 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4499 AFS_TRACE_LEVEL_WARNING,
4500 "AFSProcessPIOCtlQueryInfo (FileRemoteProtocolInformation) Not Implemented\n"));
4505 case FileNetworkPhysicalNameInformation:
4507 ntStatus = STATUS_INVALID_PARAMETER;
4509 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4510 AFS_TRACE_LEVEL_WARNING,
4511 "AFSProcessPIOCtlQueryInfo (FileNetworkPhysicalNameInformation) Not Implemented\n"));
4518 ntStatus = STATUS_INVALID_PARAMETER;
4520 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4521 AFS_TRACE_LEVEL_WARNING,
4522 "AFSProcessPIOCtlQueryInfo Not handling request %08lX\n",
4523 ulFileInformationClass));
4530 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4531 AFS_TRACE_LEVEL_VERBOSE,
4532 "AFSProcessPIOCtlQueryInfo ntStatus %08lX\n",