2 * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC.
3 * Copyright (c) 2009, 2010, 2011, 2014 Your File System, Inc.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * - Redistributions of source code must retain the above copyright notice,
11 * this list of conditions and the following disclaimer.
12 * - Redistributions in binary form must reproduce the above copyright
14 * this list of conditions and the following disclaimer in the
16 * and/or other materials provided with the distribution.
17 * - Neither the names of Kernel Drivers, LLC and Your File System, Inc.
18 * nor the names of their contributors may be used to endorse or promote
19 * products derived from this software without specific prior written
20 * permission from Kernel Drivers, LLC and Your File System, Inc.
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
24 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
25 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
26 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 // File: AFSFileInfo.cpp
39 #include "AFSCommon.h"
42 // Function: AFSQueryFileInfo
46 // This function is the dispatch handler for the IRP_MJ_QUERY_FILE_INFORMATION request
50 // A status is returned for the function
54 AFSQueryFileInfo( IN PDEVICE_OBJECT LibDeviceObject,
58 UNREFERENCED_PARAMETER(LibDeviceObject);
59 NTSTATUS ntStatus = STATUS_SUCCESS;
60 IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
63 BOOLEAN bReleaseMain = FALSE;
65 FILE_INFORMATION_CLASS stFileInformationClass;
73 // Determine the type of request this request is
76 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
78 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
83 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
84 AFS_TRACE_LEVEL_ERROR,
85 "AFSQueryFileInfo Attempted access (%p) when pFcb == NULL\n",
88 try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST);
91 lLength = (LONG)pIrpSp->Parameters.QueryFile.Length;
92 stFileInformationClass = pIrpSp->Parameters.QueryFile.FileInformationClass;
93 pBuffer = Irp->AssociatedIrp.SystemBuffer;
95 if ( BooleanFlagOn( pFcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY))
98 RtlZeroMemory( &stAuthGroup,
101 AFSRetrieveAuthGroupFnc( (ULONGLONG)PsGetCurrentProcessId(),
102 (ULONGLONG)PsGetCurrentThreadId(),
105 ntStatus = AFSVerifyEntry( &stAuthGroup,
109 if ( NT_SUCCESS( ntStatus))
112 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
113 AFS_TRACE_LEVEL_VERBOSE,
114 "AFSQueryFileInfo FID %08lX-%08lX-%08lX-%08lX Clearing Verify Flag\n",
115 pFcb->ObjectInformation->FileId.Cell,
116 pFcb->ObjectInformation->FileId.Volume,
117 pFcb->ObjectInformation->FileId.Vnode,
118 pFcb->ObjectInformation->FileId.Unique));
120 ClearFlag( pFcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY);
125 ntStatus = STATUS_SUCCESS;
130 // Grab the main shared right off the bat
133 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
134 AFS_TRACE_LEVEL_VERBOSE,
135 "AFSQueryFileInfo Acquiring Fcb lock %p SHARED %08lX\n",
136 &pFcb->NPFcb->Resource,
137 PsGetCurrentThread()));
139 AFSAcquireShared( &pFcb->NPFcb->Resource,
145 // Don't allow requests against IOCtl nodes
148 if( pFcb->Header.NodeTypeCode == AFS_SPECIAL_SHARE_FCB)
151 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
152 AFS_TRACE_LEVEL_VERBOSE,
153 "AFSQueryFileInfo Processing request against SpecialShare Fcb\n"));
155 ntStatus = AFSProcessShareQueryInfo( Irp,
159 try_return( ntStatus);
161 else if( pFcb->Header.NodeTypeCode == AFS_IOCTL_FCB)
163 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
164 AFS_TRACE_LEVEL_VERBOSE,
165 "AFSQueryFileInfo request against PIOCtl Fcb\n"));
167 ntStatus = AFSProcessPIOCtlQueryInfo( Irp,
172 try_return( ntStatus);
175 else if( pFcb->Header.NodeTypeCode == AFS_INVALID_FCB)
177 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
178 AFS_TRACE_LEVEL_VERBOSE,
179 "AFSQueryFileInfo request against Invalid Fcb\n"));
181 try_return( ntStatus = STATUS_ACCESS_DENIED);
185 // Process the request
188 switch( stFileInformationClass)
191 case FileAllInformation:
194 PFILE_ALL_INFORMATION pAllInfo;
197 // For the all information class we'll typecast a local
198 // pointer to the output buffer and then call the
199 // individual routines to fill in the buffer.
202 pAllInfo = (PFILE_ALL_INFORMATION)pBuffer;
204 ntStatus = AFSQueryBasicInfo( Irp,
206 &pAllInfo->BasicInformation,
209 if( !NT_SUCCESS( ntStatus))
212 try_return( ntStatus);
215 ntStatus = AFSQueryStandardInfo( Irp,
217 &pAllInfo->StandardInformation,
220 if( !NT_SUCCESS( ntStatus))
223 try_return( ntStatus);
226 ntStatus = AFSQueryInternalInfo( Irp,
228 &pAllInfo->InternalInformation,
231 if( !NT_SUCCESS( ntStatus))
234 try_return( ntStatus);
237 ntStatus = AFSQueryEaInfo( Irp,
239 &pAllInfo->EaInformation,
242 if( !NT_SUCCESS( ntStatus))
245 try_return( ntStatus);
248 ntStatus = AFSQueryAccess( Irp,
250 &pAllInfo->AccessInformation,
253 if( !NT_SUCCESS( ntStatus))
256 try_return( ntStatus);
259 ntStatus = AFSQueryPositionInfo( Irp,
261 &pAllInfo->PositionInformation,
264 if( !NT_SUCCESS( ntStatus))
267 try_return( ntStatus);
270 ntStatus = AFSQueryMode( Irp,
272 &pAllInfo->ModeInformation,
275 if( !NT_SUCCESS( ntStatus))
278 try_return( ntStatus);
281 ntStatus = AFSQueryAlignment( Irp,
283 &pAllInfo->AlignmentInformation,
286 if( !NT_SUCCESS( ntStatus))
289 try_return( ntStatus);
292 ntStatus = AFSQueryNameInfo( Irp,
294 &pAllInfo->NameInformation,
297 if( !NT_SUCCESS( ntStatus))
300 try_return( ntStatus);
306 case FileBasicInformation:
309 ntStatus = AFSQueryBasicInfo( Irp,
311 (PFILE_BASIC_INFORMATION)pBuffer,
317 case FileStandardInformation:
320 ntStatus = AFSQueryStandardInfo( Irp,
322 (PFILE_STANDARD_INFORMATION)pBuffer,
328 case FileInternalInformation:
331 ntStatus = AFSQueryInternalInfo( Irp,
333 (PFILE_INTERNAL_INFORMATION)pBuffer,
339 case FileEaInformation:
342 ntStatus = AFSQueryEaInfo( Irp,
344 (PFILE_EA_INFORMATION)pBuffer,
350 case FilePositionInformation:
353 ntStatus = AFSQueryPositionInfo( Irp,
355 (PFILE_POSITION_INFORMATION)pBuffer,
361 case FileNormalizedNameInformation:
362 case FileNameInformation:
365 ntStatus = AFSQueryNameInfo( Irp,
367 (PFILE_NAME_INFORMATION)pBuffer,
373 case FileAlternateNameInformation:
376 ntStatus = AFSQueryShortNameInfo( Irp,
378 (PFILE_NAME_INFORMATION)pBuffer,
384 case FileNetworkOpenInformation:
387 ntStatus = AFSQueryNetworkInfo( Irp,
389 (PFILE_NETWORK_OPEN_INFORMATION)pBuffer,
395 case FileStreamInformation:
398 ntStatus = AFSQueryStreamInfo( Irp,
400 (FILE_STREAM_INFORMATION *)pBuffer,
407 case FileAttributeTagInformation:
410 ntStatus = AFSQueryAttribTagInfo( Irp,
412 (FILE_ATTRIBUTE_TAG_INFORMATION *)pBuffer,
418 case FileRemoteProtocolInformation:
421 ntStatus = AFSQueryRemoteProtocolInfo( Irp,
423 (FILE_REMOTE_PROTOCOL_INFORMATION *)pBuffer,
429 case FileNetworkPhysicalNameInformation:
432 ntStatus = AFSQueryPhysicalNameInfo( Irp,
434 (FILE_NETWORK_PHYSICAL_NAME_INFORMATION *)pBuffer,
442 ntStatus = STATUS_INVALID_PARAMETER;
449 Irp->IoStatus.Information = pIrpSp->Parameters.QueryFile.Length - lLength;
454 AFSReleaseResource( &pFcb->NPFcb->Resource);
457 if( !NT_SUCCESS( ntStatus) &&
458 ntStatus != STATUS_INVALID_PARAMETER &&
459 ntStatus != STATUS_BUFFER_OVERFLOW)
463 pCcb->DirectoryCB != NULL)
466 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
467 AFS_TRACE_LEVEL_ERROR,
468 "AFSQueryFileInfo Failed to process request for %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
469 &pCcb->DirectoryCB->NameInformation.FileName,
470 pFcb->ObjectInformation->FileId.Cell,
471 pFcb->ObjectInformation->FileId.Volume,
472 pFcb->ObjectInformation->FileId.Vnode,
473 pFcb->ObjectInformation->FileId.Unique,
478 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
483 "EXCEPTION - AFSQueryFileInfo\n"));
485 AFSDumpTraceFilesFnc();
487 ntStatus = STATUS_UNSUCCESSFUL;
492 AFSReleaseResource( &pFcb->NPFcb->Resource);
496 AFSCompleteRequest( Irp,
503 // Function: AFSSetFileInfo
507 // This function is the dispatch handler for the IRP_MJ_SET_FILE_INFORMATION request
511 // A status is returned for the function
515 AFSSetFileInfo( IN PDEVICE_OBJECT LibDeviceObject,
519 UNREFERENCED_PARAMETER(LibDeviceObject);
520 NTSTATUS ntStatus = STATUS_SUCCESS;
521 IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
524 FILE_INFORMATION_CLASS FileInformationClass;
525 BOOLEAN bCanQueueRequest = FALSE;
526 PFILE_OBJECT pFileObject = NULL;
527 BOOLEAN bReleaseMain = FALSE;
528 BOOLEAN bUpdateFileInfo = FALSE;
529 AFSFileID stParentFileId;
534 pFileObject = pIrpSp->FileObject;
536 pFcb = (AFSFcb *)pFileObject->FsContext;
537 pCcb = (AFSCcb *)pFileObject->FsContext2;
542 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
543 AFS_TRACE_LEVEL_ERROR,
544 "AFSSetFileInfo Attempted access (%p) when pFcb == NULL\n",
547 try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST);
550 bCanQueueRequest = !(IoIsOperationSynchronous( Irp) | (KeGetCurrentIrql() != PASSIVE_LEVEL));
551 FileInformationClass = pIrpSp->Parameters.SetFile.FileInformationClass;
557 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
558 AFS_TRACE_LEVEL_VERBOSE,
559 "AFSSetFileInfo Acquiring Fcb lock %p EXCL %08lX\n",
560 &pFcb->NPFcb->Resource,
561 PsGetCurrentThread()));
563 AFSAcquireExcl( &pFcb->NPFcb->Resource,
569 // Don't allow requests against IOCtl nodes
572 if( pFcb->Header.NodeTypeCode == AFS_IOCTL_FCB)
575 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
576 AFS_TRACE_LEVEL_ERROR,
577 "AFSSetFileInfo Failing request against PIOCtl Fcb\n"));
579 try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST);
581 else if( pFcb->Header.NodeTypeCode == AFS_SPECIAL_SHARE_FCB)
584 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
585 AFS_TRACE_LEVEL_VERBOSE,
586 "AFSSetFileInfo Processing request against SpecialShare Fcb\n"));
588 ntStatus = AFSProcessShareSetInfo( Irp,
592 try_return( ntStatus);
595 if( FileInformationClass != FilePositionInformation &&
596 BooleanFlagOn( pFcb->ObjectInformation->VolumeCB->VolumeInformation.FileSystemAttributes, FILE_READ_ONLY_VOLUME))
599 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
600 AFS_TRACE_LEVEL_ERROR,
601 "AFSSetFileInfo Request failed due to read only volume\n",
604 try_return( ntStatus = STATUS_MEDIA_WRITE_PROTECTED);
607 if( pFcb->Header.NodeTypeCode == AFS_INVALID_FCB &&
608 FileInformationClass != FileDispositionInformation)
610 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
611 AFS_TRACE_LEVEL_VERBOSE,
612 "AFSSetFileInfo request against Invalid Fcb\n"));
614 try_return( ntStatus = STATUS_ACCESS_DENIED);
618 // Ensure rename operations are synchronous
621 if( FileInformationClass == FileRenameInformation)
624 bCanQueueRequest = FALSE;
628 // Store away the parent fid
631 RtlZeroMemory( &stParentFileId,
634 if( BooleanFlagOn( pFcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
637 stParentFileId = pFcb->ObjectInformation->ParentFileId;
641 // Process the request
644 switch( FileInformationClass)
647 case FileBasicInformation:
650 ntStatus = AFSSetBasicInfo( Irp,
657 case FileDispositionInformation:
660 ntStatus = AFSSetDispositionInfo( Irp,
666 case FileRenameInformation:
669 ntStatus = AFSSetRenameInfo( Irp);
674 case FilePositionInformation:
677 ntStatus = AFSSetPositionInfo( Irp,
683 case FileLinkInformation:
686 ntStatus = AFSSetFileLinkInfo( Irp);
691 case FileAllocationInformation:
694 ntStatus = AFSSetAllocationInfo( Irp,
700 case FileEndOfFileInformation:
703 ntStatus = AFSSetEndOfFileInfo( Irp,
711 ntStatus = STATUS_INVALID_PARAMETER;
721 AFSReleaseResource( &pFcb->NPFcb->Resource);
724 if( NT_SUCCESS( ntStatus) &&
728 ntStatus = AFSUpdateFileInformation( &stParentFileId,
729 pFcb->ObjectInformation,
732 if( !NT_SUCCESS( ntStatus))
735 AFSAcquireExcl( &pFcb->NPFcb->Resource,
739 // Unwind the update and fail the request
742 AFSUnwindFileInfo( pFcb,
745 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
746 AFS_TRACE_LEVEL_ERROR,
747 "AFSSetFileInfo Failed to send file info update to service request for %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
748 &pCcb->DirectoryCB->NameInformation.FileName,
749 pFcb->ObjectInformation->FileId.Cell,
750 pFcb->ObjectInformation->FileId.Volume,
751 pFcb->ObjectInformation->FileId.Vnode,
752 pFcb->ObjectInformation->FileId.Unique,
755 AFSReleaseResource( &pFcb->NPFcb->Resource);
759 if( !NT_SUCCESS( ntStatus))
763 pCcb->DirectoryCB != NULL)
766 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
767 AFS_TRACE_LEVEL_ERROR,
768 "AFSSetFileInfo Failed to process request for %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
769 &pCcb->DirectoryCB->NameInformation.FileName,
770 pFcb->ObjectInformation->FileId.Cell,
771 pFcb->ObjectInformation->FileId.Volume,
772 pFcb->ObjectInformation->FileId.Vnode,
773 pFcb->ObjectInformation->FileId.Unique,
778 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
783 "EXCEPTION - AFSSetFileInfo\n"));
785 AFSDumpTraceFilesFnc();
787 ntStatus = STATUS_UNSUCCESSFUL;
792 AFSReleaseResource( &pFcb->NPFcb->Resource);
796 AFSCompleteRequest( Irp,
803 // Function: AFSQueryBasicInfo
807 // This function is the handler for the query basic information request
811 // A status is returned for the function
815 AFSQueryBasicInfo( IN PIRP Irp,
816 IN AFSDirectoryCB *DirectoryCB,
817 IN OUT PFILE_BASIC_INFORMATION Buffer,
820 NTSTATUS ntStatus = STATUS_SUCCESS;
821 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
822 ULONG ulFileAttribs = 0;
825 IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
826 AFSFileInfoCB stFileInfo;
827 AFSDirectoryCB *pParentDirectoryCB = NULL;
828 UNICODE_STRING uniParentPath;
830 if( *Length >= sizeof( FILE_BASIC_INFORMATION))
833 RtlZeroMemory( Buffer,
836 ulFileAttribs = DirectoryCB->ObjectInformation->FileAttributes;
838 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
839 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
841 if( DirectoryCB->ObjectInformation->FileType == AFS_FILE_TYPE_SYMLINK)
844 pParentDirectoryCB = AFSGetParentEntry( pCcb->NameArray);
846 AFSRetrieveParentPath( &pCcb->FullFileName,
849 RtlZeroMemory( &stFileInfo,
850 sizeof( AFSFileInfoCB));
853 // Can't hold the Fcb while evaluating the path, leads to lock inversion
856 AFSReleaseResource( &pFcb->NPFcb->Resource);
859 // Its a reparse point regardless of whether the file attributes
860 // can be retrieved for the target.
863 if ( ulFileAttribs == FILE_ATTRIBUTE_NORMAL)
866 ulFileAttribs = FILE_ATTRIBUTE_REPARSE_POINT;
871 ulFileAttribs |= FILE_ATTRIBUTE_REPARSE_POINT;
874 if( NT_SUCCESS( AFSRetrieveFileAttributes( pParentDirectoryCB,
882 if ( stFileInfo.FileAttributes & FILE_ATTRIBUTE_DIRECTORY)
885 ulFileAttribs |= FILE_ATTRIBUTE_DIRECTORY;
889 AFSAcquireShared( &pFcb->NPFcb->Resource,
894 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
895 AFS_TRACE_LEVEL_VERBOSE_2,
896 "AFSQueryBasicInfo %wZ Type 0x%x Attrib 0x%x -> 0x%x\n",
897 &pCcb->DirectoryCB->NameInformation.FileName,
898 pFcb->ObjectInformation->FileType,
899 pFcb->ObjectInformation->FileAttributes,
902 Buffer->CreationTime = DirectoryCB->ObjectInformation->CreationTime;
903 Buffer->LastAccessTime = DirectoryCB->ObjectInformation->LastAccessTime;
904 Buffer->LastWriteTime = DirectoryCB->ObjectInformation->LastWriteTime;
905 Buffer->ChangeTime = DirectoryCB->ObjectInformation->ChangeTime;
906 Buffer->FileAttributes = ulFileAttribs;
908 if( DirectoryCB->NameInformation.FileName.Buffer[ 0] == L'.' &&
909 BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_HIDE_DOT_NAMES))
912 if ( Buffer->FileAttributes != FILE_ATTRIBUTE_NORMAL)
914 Buffer->FileAttributes |= FILE_ATTRIBUTE_HIDDEN;
918 Buffer->FileAttributes = FILE_ATTRIBUTE_HIDDEN;
922 *Length -= sizeof( FILE_BASIC_INFORMATION);
927 ntStatus = STATUS_BUFFER_TOO_SMALL;
934 AFSQueryStandardInfo( IN PIRP Irp,
935 IN AFSDirectoryCB *DirectoryCB,
936 IN OUT PFILE_STANDARD_INFORMATION Buffer,
940 NTSTATUS ntStatus = STATUS_SUCCESS;
943 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
944 AFSFileInfoCB stFileInfo;
945 AFSDirectoryCB *pParentDirectoryCB = NULL;
946 UNICODE_STRING uniParentPath;
947 ULONG ulFileAttribs = 0;
949 if( *Length >= sizeof( FILE_STANDARD_INFORMATION))
952 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
953 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
955 RtlZeroMemory( Buffer,
958 Buffer->NumberOfLinks = 1;
959 Buffer->DeletePending = BooleanFlagOn( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
961 Buffer->AllocationSize.QuadPart = (ULONGLONG)((DirectoryCB->ObjectInformation->AllocationSize.QuadPart/PAGE_SIZE) + 1) * PAGE_SIZE;
963 Buffer->EndOfFile = DirectoryCB->ObjectInformation->EndOfFile;
965 ulFileAttribs = DirectoryCB->ObjectInformation->FileAttributes;
967 if( DirectoryCB->ObjectInformation->FileType == AFS_FILE_TYPE_SYMLINK)
970 pParentDirectoryCB = AFSGetParentEntry( pCcb->NameArray);
972 AFSRetrieveParentPath( &pCcb->FullFileName,
975 RtlZeroMemory( &stFileInfo,
976 sizeof( AFSFileInfoCB));
979 // Can't hold the Fcb while evaluating the path, leads to lock inversion
982 AFSReleaseResource( &pFcb->NPFcb->Resource);
985 // Its a reparse point regardless of whether or not the
986 // file attributes can be retrieved.
989 if ( ulFileAttribs == FILE_ATTRIBUTE_NORMAL)
992 ulFileAttribs = FILE_ATTRIBUTE_REPARSE_POINT;
997 ulFileAttribs |= FILE_ATTRIBUTE_REPARSE_POINT;
1000 if( NT_SUCCESS( AFSRetrieveFileAttributes( pParentDirectoryCB,
1008 if ( stFileInfo.FileAttributes & FILE_ATTRIBUTE_DIRECTORY)
1011 ulFileAttribs |= FILE_ATTRIBUTE_DIRECTORY;
1015 AFSAcquireShared( &pFcb->NPFcb->Resource,
1019 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1020 AFS_TRACE_LEVEL_VERBOSE_2,
1021 "AFSQueryStandardInfo %wZ Type 0x%x Attrib 0x%x -> 0x%x\n",
1022 &pCcb->DirectoryCB->NameInformation.FileName,
1023 pFcb->ObjectInformation->FileType,
1024 pFcb->ObjectInformation->FileAttributes,
1027 Buffer->Directory = BooleanFlagOn( ulFileAttribs, FILE_ATTRIBUTE_DIRECTORY);
1029 *Length -= sizeof( FILE_STANDARD_INFORMATION);
1034 ntStatus = STATUS_BUFFER_TOO_SMALL;
1041 AFSQueryInternalInfo( IN PIRP Irp,
1043 IN OUT PFILE_INTERNAL_INFORMATION Buffer,
1044 IN OUT PLONG Length)
1047 UNREFERENCED_PARAMETER(Irp);
1048 NTSTATUS ntStatus = STATUS_SUCCESS;
1050 if( *Length >= sizeof( FILE_INTERNAL_INFORMATION))
1053 Buffer->IndexNumber.HighPart = Fcb->ObjectInformation->FileId.Vnode;
1055 Buffer->IndexNumber.LowPart = Fcb->ObjectInformation->FileId.Unique;
1057 *Length -= sizeof( FILE_INTERNAL_INFORMATION);
1062 ntStatus = STATUS_BUFFER_TOO_SMALL;
1069 AFSQueryEaInfo( IN PIRP Irp,
1070 IN AFSDirectoryCB *DirectoryCB,
1071 IN OUT PFILE_EA_INFORMATION Buffer,
1072 IN OUT PLONG Length)
1075 UNREFERENCED_PARAMETER(Irp);
1076 UNREFERENCED_PARAMETER(DirectoryCB);
1077 NTSTATUS ntStatus = STATUS_SUCCESS;
1079 RtlZeroMemory( Buffer,
1082 if( *Length >= sizeof( FILE_EA_INFORMATION))
1087 *Length -= sizeof( FILE_EA_INFORMATION);
1092 ntStatus = STATUS_BUFFER_TOO_SMALL;
1099 AFSQueryPositionInfo( IN PIRP Irp,
1101 IN OUT PFILE_POSITION_INFORMATION Buffer,
1102 IN OUT PLONG Length)
1105 UNREFERENCED_PARAMETER(Fcb);
1106 NTSTATUS ntStatus = STATUS_SUCCESS;
1107 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1109 if( *Length >= sizeof( FILE_POSITION_INFORMATION))
1112 RtlZeroMemory( Buffer,
1115 Buffer->CurrentByteOffset.QuadPart = pIrpSp->FileObject->CurrentByteOffset.QuadPart;
1117 *Length -= sizeof( FILE_POSITION_INFORMATION);
1122 ntStatus = STATUS_BUFFER_TOO_SMALL;
1129 AFSQueryAccess( IN PIRP Irp,
1131 IN OUT PFILE_ACCESS_INFORMATION Buffer,
1132 IN OUT PLONG Length)
1135 UNREFERENCED_PARAMETER(Irp);
1136 UNREFERENCED_PARAMETER(Fcb);
1137 NTSTATUS ntStatus = STATUS_SUCCESS;
1139 if( *Length >= sizeof( FILE_ACCESS_INFORMATION))
1142 RtlZeroMemory( Buffer,
1145 Buffer->AccessFlags = 0;
1147 *Length -= sizeof( FILE_ACCESS_INFORMATION);
1152 ntStatus = STATUS_BUFFER_TOO_SMALL;
1159 AFSQueryMode( IN PIRP Irp,
1161 IN OUT PFILE_MODE_INFORMATION Buffer,
1162 IN OUT PLONG Length)
1165 UNREFERENCED_PARAMETER(Irp);
1166 UNREFERENCED_PARAMETER(Fcb);
1167 NTSTATUS ntStatus = STATUS_SUCCESS;
1169 if( *Length >= sizeof( FILE_MODE_INFORMATION))
1172 RtlZeroMemory( Buffer,
1177 *Length -= sizeof( FILE_MODE_INFORMATION);
1182 ntStatus = STATUS_BUFFER_TOO_SMALL;
1189 AFSQueryAlignment( IN PIRP Irp,
1191 IN OUT PFILE_ALIGNMENT_INFORMATION Buffer,
1192 IN OUT PLONG Length)
1195 UNREFERENCED_PARAMETER(Irp);
1196 UNREFERENCED_PARAMETER(Fcb);
1197 NTSTATUS ntStatus = STATUS_SUCCESS;
1199 if( *Length >= sizeof( FILE_ALIGNMENT_INFORMATION))
1202 RtlZeroMemory( Buffer,
1205 Buffer->AlignmentRequirement = 1;
1207 *Length -= sizeof( FILE_ALIGNMENT_INFORMATION);
1212 ntStatus = STATUS_BUFFER_TOO_SMALL;
1219 AFSQueryNameInfo( IN PIRP Irp,
1220 IN AFSDirectoryCB *DirectoryCB,
1221 IN OUT PFILE_NAME_INFORMATION Buffer,
1222 IN OUT PLONG Length)
1225 UNREFERENCED_PARAMETER(DirectoryCB);
1226 NTSTATUS ntStatus = STATUS_SUCCESS;
1227 ULONG ulCopyLength = 0;
1228 ULONG cchCopied = 0;
1229 AFSFcb *pFcb = NULL;
1230 AFSCcb *pCcb = NULL;
1231 IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1232 BOOLEAN bAddLeadingSlash = FALSE;
1233 BOOLEAN bAddTrailingSlash = FALSE;
1234 USHORT usFullNameLength = 0;
1236 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
1238 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
1240 if( *Length >= FIELD_OFFSET( FILE_NAME_INFORMATION, FileName))
1243 RtlZeroMemory( Buffer,
1246 if( pCcb->FullFileName.Length == 0 ||
1247 pCcb->FullFileName.Buffer[ 0] != L'\\')
1249 bAddLeadingSlash = TRUE;
1252 if( pFcb->ObjectInformation->FileType == AFS_FILE_TYPE_DIRECTORY &&
1253 pCcb->FullFileName.Length > 0 &&
1254 pCcb->FullFileName.Buffer[ (pCcb->FullFileName.Length/sizeof( WCHAR)) - 1] != L'\\')
1256 bAddTrailingSlash = TRUE;
1259 usFullNameLength = sizeof( WCHAR) +
1260 AFSServerName.Length +
1261 pCcb->FullFileName.Length;
1263 if( bAddLeadingSlash)
1265 usFullNameLength += sizeof( WCHAR);
1268 if( bAddTrailingSlash)
1270 usFullNameLength += sizeof( WCHAR);
1273 if( *Length >= (LONG)(FIELD_OFFSET( FILE_NAME_INFORMATION, FileName) + (LONG)usFullNameLength))
1276 ulCopyLength = (LONG)usFullNameLength;
1281 ulCopyLength = *Length - FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
1283 ntStatus = STATUS_BUFFER_OVERFLOW;
1286 Buffer->FileNameLength = (ULONG)usFullNameLength;
1288 *Length -= FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
1290 if( ulCopyLength > 0)
1293 Buffer->FileName[ 0] = L'\\';
1294 ulCopyLength -= sizeof( WCHAR);
1296 *Length -= sizeof( WCHAR);
1299 if( ulCopyLength >= AFSServerName.Length)
1302 RtlCopyMemory( &Buffer->FileName[ 1],
1303 AFSServerName.Buffer,
1304 AFSServerName.Length);
1306 ulCopyLength -= AFSServerName.Length;
1307 *Length -= AFSServerName.Length;
1308 cchCopied += AFSServerName.Length/sizeof( WCHAR);
1310 if ( ulCopyLength > 0 &&
1314 Buffer->FileName[ cchCopied] = L'\\';
1316 ulCopyLength -= sizeof( WCHAR);
1317 *Length -= sizeof( WCHAR);
1321 if( ulCopyLength >= pCcb->FullFileName.Length)
1324 RtlCopyMemory( &Buffer->FileName[ cchCopied],
1325 pCcb->FullFileName.Buffer,
1326 pCcb->FullFileName.Length);
1328 ulCopyLength -= pCcb->FullFileName.Length;
1329 *Length -= pCcb->FullFileName.Length;
1330 cchCopied += pCcb->FullFileName.Length/sizeof( WCHAR);
1332 if( ulCopyLength > 0 &&
1335 Buffer->FileName[ cchCopied] = L'\\';
1337 *Length -= sizeof( WCHAR);
1343 RtlCopyMemory( &Buffer->FileName[ cchCopied],
1344 pCcb->FullFileName.Buffer,
1347 *Length -= ulCopyLength;
1355 ntStatus = STATUS_BUFFER_TOO_SMALL;
1362 AFSQueryShortNameInfo( IN PIRP Irp,
1363 IN AFSDirectoryCB *DirectoryCB,
1364 IN OUT PFILE_NAME_INFORMATION Buffer,
1365 IN OUT PLONG Length)
1368 UNREFERENCED_PARAMETER(Irp);
1369 NTSTATUS ntStatus = STATUS_BUFFER_TOO_SMALL;
1370 ULONG ulCopyLength = 0;
1372 RtlZeroMemory( Buffer,
1375 if( DirectoryCB->NameInformation.ShortNameLength == 0)
1379 // The short name IS the long name
1382 if( *Length >= (LONG)FIELD_OFFSET( FILE_NAME_INFORMATION, FileName))
1385 if( *Length >= (LONG)(FIELD_OFFSET( FILE_NAME_INFORMATION, FileName) + (LONG)DirectoryCB->NameInformation.FileName.Length))
1388 ulCopyLength = (LONG)DirectoryCB->NameInformation.FileName.Length;
1390 ntStatus = STATUS_SUCCESS;
1395 ulCopyLength = *Length - FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
1397 ntStatus = STATUS_BUFFER_OVERFLOW;
1400 Buffer->FileNameLength = DirectoryCB->NameInformation.FileName.Length;
1402 *Length -= FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
1404 if( ulCopyLength > 0)
1407 RtlCopyMemory( Buffer->FileName,
1408 DirectoryCB->NameInformation.FileName.Buffer,
1411 *Length -= ulCopyLength;
1418 if( *Length >= (LONG)FIELD_OFFSET( FILE_NAME_INFORMATION, FileName))
1421 if( *Length >= (LONG)(FIELD_OFFSET( FILE_NAME_INFORMATION, FileName) + (LONG)DirectoryCB->NameInformation.FileName.Length))
1424 ulCopyLength = (LONG)DirectoryCB->NameInformation.ShortNameLength;
1426 ntStatus = STATUS_SUCCESS;
1431 ulCopyLength = *Length - FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
1433 ntStatus = STATUS_BUFFER_OVERFLOW;
1436 Buffer->FileNameLength = DirectoryCB->NameInformation.ShortNameLength;
1438 *Length -= FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
1440 if( ulCopyLength > 0)
1443 RtlCopyMemory( Buffer->FileName,
1444 DirectoryCB->NameInformation.ShortName,
1445 Buffer->FileNameLength);
1447 *Length -= ulCopyLength;
1456 AFSQueryNetworkInfo( IN PIRP Irp,
1457 IN AFSDirectoryCB *DirectoryCB,
1458 IN OUT PFILE_NETWORK_OPEN_INFORMATION Buffer,
1459 IN OUT PLONG Length)
1462 NTSTATUS ntStatus = STATUS_SUCCESS;
1463 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1464 AFSFcb *pFcb = NULL;
1465 AFSCcb *pCcb = NULL;
1466 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1467 AFSFileInfoCB stFileInfo;
1468 AFSDirectoryCB *pParentDirectoryCB = NULL;
1469 UNICODE_STRING uniParentPath;
1470 ULONG ulFileAttribs = 0;
1472 RtlZeroMemory( Buffer,
1475 if( *Length >= sizeof( FILE_NETWORK_OPEN_INFORMATION))
1478 ulFileAttribs = DirectoryCB->ObjectInformation->FileAttributes;
1480 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
1481 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
1483 if( DirectoryCB->ObjectInformation->FileType == AFS_FILE_TYPE_SYMLINK)
1486 pParentDirectoryCB = AFSGetParentEntry( pCcb->NameArray);
1488 AFSRetrieveParentPath( &pCcb->FullFileName,
1491 RtlZeroMemory( &stFileInfo,
1492 sizeof( AFSFileInfoCB));
1495 // Can't hold the Fcb while evaluating the path, leads to lock inversion
1498 AFSReleaseResource( &pFcb->NPFcb->Resource);
1501 // Its a reparse point regardless of whether the file attributes
1502 // can be retrieved for the target.
1505 if ( ulFileAttribs == FILE_ATTRIBUTE_NORMAL)
1508 ulFileAttribs = FILE_ATTRIBUTE_REPARSE_POINT;
1513 ulFileAttribs |= FILE_ATTRIBUTE_REPARSE_POINT;
1516 if( NT_SUCCESS( AFSRetrieveFileAttributes( pParentDirectoryCB,
1524 if ( stFileInfo.FileAttributes & FILE_ATTRIBUTE_DIRECTORY)
1527 ulFileAttribs |= FILE_ATTRIBUTE_DIRECTORY;
1531 AFSAcquireShared( &pFcb->NPFcb->Resource,
1535 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1536 AFS_TRACE_LEVEL_VERBOSE_2,
1537 "AFSQueryNetworkInfo %wZ Type 0x%x Attrib 0x%x -> 0x%x\n",
1538 &pCcb->DirectoryCB->NameInformation.FileName,
1539 pFcb->ObjectInformation->FileType,
1540 pFcb->ObjectInformation->FileAttributes,
1543 Buffer->CreationTime.QuadPart = DirectoryCB->ObjectInformation->CreationTime.QuadPart;
1544 Buffer->LastAccessTime.QuadPart = DirectoryCB->ObjectInformation->LastAccessTime.QuadPart;
1545 Buffer->LastWriteTime.QuadPart = DirectoryCB->ObjectInformation->LastWriteTime.QuadPart;
1546 Buffer->ChangeTime.QuadPart = DirectoryCB->ObjectInformation->ChangeTime.QuadPart;
1548 Buffer->AllocationSize.QuadPart = DirectoryCB->ObjectInformation->AllocationSize.QuadPart;
1549 Buffer->EndOfFile.QuadPart = DirectoryCB->ObjectInformation->EndOfFile.QuadPart;
1551 Buffer->FileAttributes = ulFileAttribs;
1553 if( DirectoryCB->NameInformation.FileName.Buffer[ 0] == L'.' &&
1554 BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_HIDE_DOT_NAMES))
1557 if ( Buffer->FileAttributes != FILE_ATTRIBUTE_NORMAL)
1560 Buffer->FileAttributes |= FILE_ATTRIBUTE_HIDDEN;
1565 Buffer->FileAttributes = FILE_ATTRIBUTE_HIDDEN;
1569 *Length -= sizeof( FILE_NETWORK_OPEN_INFORMATION);
1574 ntStatus = STATUS_BUFFER_TOO_SMALL;
1581 AFSQueryStreamInfo( IN PIRP Irp,
1582 IN AFSDirectoryCB *DirectoryCB,
1583 IN OUT FILE_STREAM_INFORMATION *Buffer,
1584 IN OUT PLONG Length)
1587 UNREFERENCED_PARAMETER(Irp);
1588 NTSTATUS ntStatus = STATUS_BUFFER_TOO_SMALL;
1589 ULONG ulCopyLength = 0;
1591 if( *Length >= FIELD_OFFSET( FILE_STREAM_INFORMATION, StreamName))
1594 RtlZeroMemory( Buffer,
1597 Buffer->NextEntryOffset = 0;
1600 if( !BooleanFlagOn( DirectoryCB->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_DIRECTORY))
1603 if( *Length >= (LONG)(FIELD_OFFSET( FILE_STREAM_INFORMATION, StreamName) + 14)) // ::$DATA
1608 ntStatus = STATUS_SUCCESS;
1613 ulCopyLength = *Length - FIELD_OFFSET( FILE_STREAM_INFORMATION, StreamName);
1615 ntStatus = STATUS_BUFFER_OVERFLOW;
1618 Buffer->StreamNameLength = 14; // ::$DATA
1620 Buffer->StreamSize.QuadPart = DirectoryCB->ObjectInformation->EndOfFile.QuadPart;
1622 Buffer->StreamAllocationSize.QuadPart = DirectoryCB->ObjectInformation->AllocationSize.QuadPart;
1624 *Length -= FIELD_OFFSET( FILE_STREAM_INFORMATION, StreamName);
1626 if( ulCopyLength > 0)
1629 RtlCopyMemory( Buffer->StreamName,
1633 *Length -= ulCopyLength;
1639 Buffer->StreamNameLength = 0; // No stream for a directory
1641 // The response size is zero
1643 ntStatus = STATUS_SUCCESS;
1651 AFSQueryAttribTagInfo( IN PIRP Irp,
1652 IN AFSDirectoryCB *DirectoryCB,
1653 IN OUT FILE_ATTRIBUTE_TAG_INFORMATION *Buffer,
1654 IN OUT PLONG Length)
1657 NTSTATUS ntStatus = STATUS_BUFFER_TOO_SMALL;
1658 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1659 AFSFcb *pFcb = NULL;
1660 AFSCcb *pCcb = NULL;
1661 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1662 AFSFileInfoCB stFileInfo;
1663 AFSDirectoryCB *pParentDirectoryCB = NULL;
1664 UNICODE_STRING uniParentPath;
1665 ULONG ulFileAttribs = 0;
1667 if( *Length >= sizeof( FILE_ATTRIBUTE_TAG_INFORMATION))
1670 RtlZeroMemory( Buffer,
1673 ulFileAttribs = DirectoryCB->ObjectInformation->FileAttributes;
1675 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
1676 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
1678 if( DirectoryCB->ObjectInformation->FileType == AFS_FILE_TYPE_SYMLINK)
1681 pParentDirectoryCB = AFSGetParentEntry( pCcb->NameArray);
1683 AFSRetrieveParentPath( &pCcb->FullFileName,
1686 RtlZeroMemory( &stFileInfo,
1687 sizeof( AFSFileInfoCB));
1690 // Can't hold the Fcb while evaluating the path, leads to lock inversion
1693 AFSReleaseResource( &pFcb->NPFcb->Resource);
1696 // Its a reparse point regardless of whether the file attributes
1697 // can be retrieved for the target.
1700 if ( ulFileAttribs == FILE_ATTRIBUTE_NORMAL)
1703 ulFileAttribs = FILE_ATTRIBUTE_REPARSE_POINT;
1708 ulFileAttribs |= FILE_ATTRIBUTE_REPARSE_POINT;
1711 if( NT_SUCCESS( AFSRetrieveFileAttributes( pParentDirectoryCB,
1719 if ( stFileInfo.FileAttributes & FILE_ATTRIBUTE_DIRECTORY)
1722 ulFileAttribs |= FILE_ATTRIBUTE_DIRECTORY;
1726 AFSAcquireShared( &pFcb->NPFcb->Resource,
1730 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1731 AFS_TRACE_LEVEL_VERBOSE_2,
1732 "AFSAttribTagInfo %wZ Type 0x%x Attrib 0x%x -> 0x%x\n",
1733 &pCcb->DirectoryCB->NameInformation.FileName,
1734 pFcb->ObjectInformation->FileType,
1735 pFcb->ObjectInformation->FileAttributes,
1738 Buffer->FileAttributes = ulFileAttribs;
1740 if( DirectoryCB->NameInformation.FileName.Buffer[ 0] == L'.' &&
1741 BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_HIDE_DOT_NAMES))
1744 if ( Buffer->FileAttributes != FILE_ATTRIBUTE_NORMAL)
1747 Buffer->FileAttributes |= FILE_ATTRIBUTE_HIDDEN;
1752 Buffer->FileAttributes = FILE_ATTRIBUTE_HIDDEN;
1756 if ( DirectoryCB->ObjectInformation->FileType == AFS_FILE_TYPE_MOUNTPOINT)
1759 Buffer->ReparseTag = IO_REPARSE_TAG_SURROGATE|IO_REPARSE_TAG_OPENAFS_DFS;
1761 else if( BooleanFlagOn( DirectoryCB->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_REPARSE_POINT))
1764 Buffer->ReparseTag = IO_REPARSE_TAG_SYMLINK;
1767 *Length -= sizeof( FILE_ATTRIBUTE_TAG_INFORMATION);
1769 ntStatus = STATUS_SUCCESS;
1776 AFSQueryRemoteProtocolInfo( IN PIRP Irp,
1777 IN AFSDirectoryCB *DirectoryCB,
1778 IN OUT FILE_REMOTE_PROTOCOL_INFORMATION *Buffer,
1779 IN OUT PLONG Length)
1782 UNREFERENCED_PARAMETER(Irp);
1783 UNREFERENCED_PARAMETER(DirectoryCB);
1784 NTSTATUS ntStatus = STATUS_BUFFER_TOO_SMALL;
1786 if( *Length >= sizeof( FILE_REMOTE_PROTOCOL_INFORMATION))
1789 RtlZeroMemory( Buffer,
1792 Buffer->StructureVersion = 1;
1794 Buffer->StructureSize = sizeof(FILE_REMOTE_PROTOCOL_INFORMATION);
1796 Buffer->Protocol = WNNC_NET_OPENAFS;
1798 Buffer->ProtocolMajorVersion = 3;
1800 Buffer->ProtocolMinorVersion = 0;
1802 Buffer->ProtocolRevision = 0;
1804 *Length -= sizeof( FILE_REMOTE_PROTOCOL_INFORMATION);
1806 ntStatus = STATUS_SUCCESS;
1813 AFSQueryPhysicalNameInfo( IN PIRP Irp,
1814 IN AFSDirectoryCB *DirectoryCB,
1815 IN OUT PFILE_NETWORK_PHYSICAL_NAME_INFORMATION Buffer,
1816 IN OUT PLONG Length)
1819 UNREFERENCED_PARAMETER(DirectoryCB);
1820 NTSTATUS ntStatus = STATUS_SUCCESS;
1821 ULONG ulCopyLength = 0;
1822 ULONG cchCopied = 0;
1823 AFSFcb *pFcb = NULL;
1824 AFSCcb *pCcb = NULL;
1825 IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1826 BOOLEAN bAddLeadingSlash = FALSE;
1827 USHORT usFullNameLength = 0;
1829 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
1831 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
1833 if( *Length >= FIELD_OFFSET( FILE_NETWORK_PHYSICAL_NAME_INFORMATION, FileName))
1836 RtlZeroMemory( Buffer,
1839 if( pCcb->FullFileName.Length == 0 ||
1840 pCcb->FullFileName.Buffer[ 0] != L'\\')
1842 bAddLeadingSlash = TRUE;
1845 usFullNameLength = pCcb->FullFileName.Length;
1847 if( bAddLeadingSlash)
1849 usFullNameLength += sizeof( WCHAR);
1852 if( *Length >= (LONG)(FIELD_OFFSET( FILE_NETWORK_PHYSICAL_NAME_INFORMATION, FileName) + (LONG)usFullNameLength))
1854 ulCopyLength = (LONG)usFullNameLength;
1859 ulCopyLength = *Length - FIELD_OFFSET( FILE_NETWORK_PHYSICAL_NAME_INFORMATION, FileName);
1861 ntStatus = STATUS_BUFFER_OVERFLOW;
1864 Buffer->FileNameLength = (ULONG)usFullNameLength;
1866 *Length -= FIELD_OFFSET( FILE_NETWORK_PHYSICAL_NAME_INFORMATION, FileName);
1868 if( ulCopyLength > 0)
1871 if( bAddLeadingSlash)
1874 Buffer->FileName[ cchCopied] = L'\\';
1876 ulCopyLength -= sizeof( WCHAR);
1877 *Length -= sizeof( WCHAR);
1881 if( ulCopyLength >= pCcb->FullFileName.Length)
1884 RtlCopyMemory( &Buffer->FileName[ cchCopied],
1885 pCcb->FullFileName.Buffer,
1886 pCcb->FullFileName.Length);
1888 ulCopyLength -= pCcb->FullFileName.Length;
1889 *Length -= pCcb->FullFileName.Length;
1890 cchCopied += pCcb->FullFileName.Length/sizeof( WCHAR);
1895 RtlCopyMemory( &Buffer->FileName[ cchCopied],
1896 pCcb->FullFileName.Buffer,
1899 *Length -= ulCopyLength;
1906 ntStatus = STATUS_BUFFER_TOO_SMALL;
1913 AFSSetBasicInfo( IN PIRP Irp,
1914 IN AFSDirectoryCB *DirectoryCB,
1915 OUT BOOLEAN *bUpdateFileInfo)
1917 NTSTATUS ntStatus = STATUS_SUCCESS;
1918 PFILE_BASIC_INFORMATION pBuffer;
1919 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1920 ULONG ulNotifyFilter = 0;
1921 AFSCcb *pCcb = NULL;
1926 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
1928 pBuffer = (PFILE_BASIC_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
1930 pCcb->FileUnwindInfo.FileAttributes = (ULONG)-1;
1932 if( pBuffer->FileAttributes != (ULONGLONG)0)
1936 // Make sure that the reparse point attribute is not modified.
1937 // Fail if the RP attribute is requested but it is not
1938 // already a RP. Otherwise, ignore it.
1941 if ( !BooleanFlagOn( DirectoryCB->ObjectInformation->FileAttributes,
1942 FILE_ATTRIBUTE_REPARSE_POINT) &&
1943 BooleanFlagOn( pBuffer->FileAttributes,
1944 FILE_ATTRIBUTE_REPARSE_POINT))
1947 try_return( ntStatus = STATUS_INVALID_PARAMETER);
1951 // Make sure that the directory attribute is not modified.
1952 // Fail if the D attribute is requested but it is not
1953 // already a directory. Otherwise, ignore it.
1956 if ( !BooleanFlagOn( DirectoryCB->ObjectInformation->FileAttributes,
1957 FILE_ATTRIBUTE_DIRECTORY) &&
1958 BooleanFlagOn( pBuffer->FileAttributes,
1959 FILE_ATTRIBUTE_DIRECTORY))
1962 try_return( ntStatus = STATUS_INVALID_PARAMETER);
1966 // Save the original value
1969 pCcb->FileUnwindInfo.FileAttributes = DirectoryCB->ObjectInformation->FileAttributes;
1971 if( BooleanFlagOn( pBuffer->FileAttributes, FILE_ATTRIBUTE_READONLY))
1975 // Set the readonly flag.
1978 if ( !BooleanFlagOn( DirectoryCB->ObjectInformation->FileAttributes,
1979 FILE_ATTRIBUTE_READONLY))
1982 if ( DirectoryCB->ObjectInformation->FileAttributes == FILE_ATTRIBUTE_NORMAL)
1985 DirectoryCB->ObjectInformation->FileAttributes = FILE_ATTRIBUTE_READONLY;
1990 DirectoryCB->ObjectInformation->FileAttributes |= FILE_ATTRIBUTE_READONLY;
1993 ulNotifyFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
1995 SetFlag( DirectoryCB->ObjectInformation->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED);
2001 // Reset the readonly flag.
2004 if ( BooleanFlagOn( DirectoryCB->ObjectInformation->FileAttributes,
2005 FILE_ATTRIBUTE_READONLY))
2008 DirectoryCB->ObjectInformation->FileAttributes &= ~FILE_ATTRIBUTE_READONLY;
2010 if ( DirectoryCB->ObjectInformation->FileAttributes == 0)
2013 DirectoryCB->ObjectInformation->FileAttributes = FILE_ATTRIBUTE_NORMAL;
2016 ulNotifyFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
2018 SetFlag( DirectoryCB->ObjectInformation->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED);
2023 pCcb->FileUnwindInfo.CreationTime.QuadPart = (ULONGLONG)-1;
2025 if( pBuffer->CreationTime.QuadPart != (ULONGLONG)-1 &&
2026 pBuffer->CreationTime.QuadPart != (ULONGLONG)0)
2029 pCcb->FileUnwindInfo.CreationTime.QuadPart = DirectoryCB->ObjectInformation->CreationTime.QuadPart;
2031 DirectoryCB->ObjectInformation->CreationTime.QuadPart = pBuffer->CreationTime.QuadPart;
2033 ulNotifyFilter |= FILE_NOTIFY_CHANGE_CREATION;
2035 SetFlag( DirectoryCB->ObjectInformation->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_CREATE_TIME);
2038 pCcb->FileUnwindInfo.LastAccessTime.QuadPart = (ULONGLONG)-1;
2040 if( pBuffer->LastAccessTime.QuadPart != (ULONGLONG)-1 &&
2041 pBuffer->LastAccessTime.QuadPart != (ULONGLONG)0)
2044 pCcb->FileUnwindInfo.LastAccessTime.QuadPart = DirectoryCB->ObjectInformation->LastAccessTime.QuadPart;
2046 DirectoryCB->ObjectInformation->LastAccessTime.QuadPart = pBuffer->LastAccessTime.QuadPart;
2048 ulNotifyFilter |= FILE_NOTIFY_CHANGE_LAST_ACCESS;
2050 SetFlag( DirectoryCB->ObjectInformation->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_ACCESS_TIME);
2053 pCcb->FileUnwindInfo.LastWriteTime.QuadPart = (ULONGLONG)-1;
2055 if( pBuffer->LastWriteTime.QuadPart != (ULONGLONG)-1 &&
2056 pBuffer->LastWriteTime.QuadPart != (ULONGLONG)0)
2059 pCcb->FileUnwindInfo.LastWriteTime.QuadPart = DirectoryCB->ObjectInformation->LastWriteTime.QuadPart;
2061 DirectoryCB->ObjectInformation->LastWriteTime.QuadPart = pBuffer->LastWriteTime.QuadPart;
2063 ulNotifyFilter |= FILE_NOTIFY_CHANGE_LAST_WRITE;
2065 SetFlag( DirectoryCB->ObjectInformation->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_LAST_WRITE_TIME);
2067 SetFlag( pCcb->Flags, CCB_FLAG_LAST_WRITE_TIME_SET);
2069 } else if ( pBuffer->LastWriteTime.QuadPart == (ULONGLONG)-1) {
2071 SetFlag( pCcb->Flags, CCB_FLAG_LAST_WRITE_TIME_SET);
2074 pCcb->FileUnwindInfo.ChangeTime.QuadPart = (ULONGLONG)-1;
2076 if( pBuffer->ChangeTime.QuadPart != (ULONGLONG)-1 &&
2077 pBuffer->ChangeTime.QuadPart != (ULONGLONG)0)
2080 pCcb->FileUnwindInfo.ChangeTime.QuadPart = DirectoryCB->ObjectInformation->ChangeTime.QuadPart;
2082 DirectoryCB->ObjectInformation->ChangeTime.QuadPart = pBuffer->ChangeTime.QuadPart;
2084 ulNotifyFilter |= FILE_NOTIFY_CHANGE_LAST_ACCESS;
2086 SetFlag( DirectoryCB->ObjectInformation->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_CHANGE_TIME);
2089 if( ulNotifyFilter > 0)
2092 *bUpdateFileInfo = TRUE;
2094 if( BooleanFlagOn( DirectoryCB->ObjectInformation->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
2097 AFSObjectInfoCB * pParentObjectInfo = AFSFindObjectInfo( DirectoryCB->ObjectInformation->VolumeCB,
2098 &DirectoryCB->ObjectInformation->ParentFileId,
2101 if ( pParentObjectInfo != NULL)
2103 AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
2105 (ULONG)ulNotifyFilter,
2106 (ULONG)FILE_ACTION_MODIFIED);
2108 AFSReleaseObjectInfo( &pParentObjectInfo);
2122 AFSSetDispositionInfo( IN PIRP Irp,
2123 IN AFSDirectoryCB *DirectoryCB)
2125 NTSTATUS ntStatus = STATUS_SUCCESS;
2126 PFILE_DISPOSITION_INFORMATION pBuffer;
2127 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2128 AFSFcb *pFcb = NULL;
2129 AFSCcb *pCcb = NULL;
2134 pBuffer = (PFILE_DISPOSITION_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
2136 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
2138 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
2141 // Can't delete the root
2144 if( pFcb->Header.NodeTypeCode == AFS_ROOT_FCB)
2147 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2148 AFS_TRACE_LEVEL_ERROR,
2149 "AFSSetDispositionInfo Attempt to delete root entry\n"));
2151 try_return( ntStatus = STATUS_CANNOT_DELETE);
2155 // If the file is read only then do not allow the delete
2158 if( BooleanFlagOn( DirectoryCB->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_READONLY))
2161 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2162 AFS_TRACE_LEVEL_ERROR,
2163 "AFSSetDispositionInfo Attempt to delete read only entry %wZ\n",
2164 &DirectoryCB->NameInformation.FileName));
2166 try_return( ntStatus = STATUS_CANNOT_DELETE);
2169 if( pBuffer->DeleteFile)
2173 // Check if the caller can delete the file
2176 ntStatus = AFSNotifyDelete( DirectoryCB,
2180 if( !NT_SUCCESS( ntStatus))
2183 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2184 AFS_TRACE_LEVEL_ERROR,
2185 "AFSSetDispositionInfo Cannot delete entry %wZ Status %08lX\n",
2186 &DirectoryCB->NameInformation.FileName,
2189 try_return( ntStatus);
2192 if( pFcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB)
2196 // Reduce the Link count in the object information block
2197 // to correspond with the deletion of the directory entry.
2200 pFcb->ObjectInformation->Links--;
2203 // Check if this is a directory that there are not currently other opens
2206 if( pFcb->ObjectInformation->Specific.Directory.ChildOpenHandleCount > 0)
2209 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2210 AFS_TRACE_LEVEL_ERROR,
2211 "AFSSetDispositionInfo Attempt to delete directory %wZ with open %u handles\n",
2212 &DirectoryCB->NameInformation.FileName,
2213 pFcb->ObjectInformation->Specific.Directory.ChildOpenHandleCount));
2215 try_return( ntStatus = STATUS_DIRECTORY_NOT_EMPTY);
2219 // Make sure the directory is enumerated before checking to see if it is empty.
2222 if( !BooleanFlagOn( pFcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
2225 AFSAcquireExcl( pFcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
2228 if( !BooleanFlagOn( pFcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
2231 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2232 AFS_TRACE_LEVEL_VERBOSE,
2233 "AFSSetDispositionInfo Enumerating parent FID %08lX-%08lX-%08lX-%08lX\n",
2234 pFcb->ObjectInformation->FileId.Cell,
2235 pFcb->ObjectInformation->FileId.Volume,
2236 pFcb->ObjectInformation->FileId.Vnode,
2237 pFcb->ObjectInformation->FileId.Unique));
2239 ntStatus = AFSEnumerateDirectory( &pCcb->AuthGroup,
2240 pFcb->ObjectInformation,
2243 if( !NT_SUCCESS( ntStatus))
2246 AFSReleaseResource( pFcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
2248 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2249 AFS_TRACE_LEVEL_ERROR,
2250 "AFSSetDispositionInfo Failed to enumerate parent FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
2251 pFcb->ObjectInformation->FileId.Cell,
2252 pFcb->ObjectInformation->FileId.Volume,
2253 pFcb->ObjectInformation->FileId.Vnode,
2254 pFcb->ObjectInformation->FileId.Unique,
2257 try_return( ntStatus);
2261 AFSReleaseResource( pFcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
2264 if( !AFSIsDirectoryEmptyForDelete( pFcb))
2267 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2268 AFS_TRACE_LEVEL_ERROR,
2269 "AFSSetDispositionInfo Attempt to delete non-empty directory %wZ\n",
2270 &DirectoryCB->NameInformation.FileName));
2272 try_return( ntStatus = STATUS_DIRECTORY_NOT_EMPTY);
2275 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2276 AFS_TRACE_LEVEL_VERBOSE,
2277 "AFSSetDispositionInfo Setting PENDING_DELETE on DirEntry %p Name %wZ\n",
2279 &DirectoryCB->NameInformation.FileName));
2281 SetFlag( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
2283 else if( pFcb->Header.NodeTypeCode == AFS_FILE_FCB)
2287 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
2288 AFS_TRACE_LEVEL_VERBOSE,
2289 "AFSSetDispositionInfo Acquiring Fcb lock %p EXCL %08lX\n",
2290 &pFcb->NPFcb->Resource,
2291 PsGetCurrentThread()));
2293 AFSAcquireExcl( &pFcb->NPFcb->Resource,
2296 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
2297 AFS_TRACE_LEVEL_VERBOSE,
2298 "AFSSetDispositionInfo Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
2299 &pFcb->NPFcb->SectionObjectResource,
2300 PsGetCurrentThread()));
2302 AFSAcquireExcl( &pFcb->NPFcb->SectionObjectResource,
2309 // Attempt to flush any outstanding data
2312 bMmFlushed = MmFlushImageSection( &pFcb->NPFcb->SectionObjectPointers,
2319 // Set PENDING_DELETE before CcPurgeCacheSection to avoid a
2320 // deadlock with Trend Micro's Enterprise anti-virus product
2321 // which attempts to open the file which is being deleted.
2324 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2325 AFS_TRACE_LEVEL_VERBOSE,
2326 "AFSSetDispositionInfo Setting PENDING_DELETE on DirEntry %p Name %wZ\n",
2328 &DirectoryCB->NameInformation.FileName));
2330 SetFlag( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
2333 // Purge the cache as well
2336 if( pFcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
2339 if ( !CcPurgeCacheSection( &pFcb->NPFcb->SectionObjectPointers,
2345 SetFlag( pFcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
2350 __except( EXCEPTION_EXECUTE_HANDLER)
2355 ntStatus = GetExceptionCode();
2359 "EXCEPTION - AFSSetDispositionInfo MmFlushImageSection failed FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
2360 pFcb->ObjectInformation->FileId.Cell,
2361 pFcb->ObjectInformation->FileId.Volume,
2362 pFcb->ObjectInformation->FileId.Vnode,
2363 pFcb->ObjectInformation->FileId.Unique,
2367 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
2368 AFS_TRACE_LEVEL_VERBOSE,
2369 "AFSSetDispositionInfo Releasing Fcb SectionObject lock %p EXCL %08lX\n",
2370 &pFcb->NPFcb->SectionObjectResource,
2371 PsGetCurrentThread()));
2373 AFSReleaseResource( &pFcb->NPFcb->SectionObjectResource);
2375 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
2376 AFS_TRACE_LEVEL_VERBOSE,
2377 "AFSSetDispositionInfo Releasing Fcb lock %p EXCL %08lX\n",
2378 &pFcb->NPFcb->Resource,
2379 PsGetCurrentThread()));
2381 AFSReleaseResource( &pFcb->NPFcb->Resource);
2386 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2387 AFS_TRACE_LEVEL_ERROR,
2388 "AFSSetDispositionInfo Failed to flush image section for delete Entry %wZ\n",
2389 &DirectoryCB->NameInformation.FileName));
2391 try_return( ntStatus = STATUS_CANNOT_DELETE);
2394 else if( pFcb->Header.NodeTypeCode == AFS_SYMBOLIC_LINK_FCB ||
2395 pFcb->Header.NodeTypeCode == AFS_MOUNT_POINT_FCB ||
2396 pFcb->Header.NodeTypeCode == AFS_DFS_LINK_FCB ||
2397 pFcb->Header.NodeTypeCode == AFS_INVALID_FCB)
2400 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2401 AFS_TRACE_LEVEL_VERBOSE,
2402 "AFSSetDispositionInfo Setting PENDING_DELETE on DirEntry %p Name %wZ\n",
2404 &DirectoryCB->NameInformation.FileName));
2406 SetFlag( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
2412 ClearFlag( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
2416 // OK, should be good to go, set the flag in the file object
2419 pIrpSp->FileObject->DeletePending = pBuffer->DeleteFile;
2430 AFSSetFileLinkInfo( IN PIRP Irp)
2433 NTSTATUS ntStatus = STATUS_SUCCESS;
2434 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
2435 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2436 PFILE_LINK_INFORMATION pFileLinkInfo = NULL;
2437 PFILE_OBJECT pSrcFileObj = NULL;
2438 PFILE_OBJECT pTargetFileObj = pIrpSp->Parameters.SetFile.FileObject;
2439 AFSFcb *pSrcFcb = NULL, *pTargetDcb = NULL;
2440 AFSCcb *pSrcCcb = NULL, *pTargetDirCcb = NULL;
2441 AFSObjectInfoCB *pSrcObject = NULL;
2442 AFSObjectInfoCB *pSrcParentObject = NULL, *pTargetParentObject = NULL;
2443 UNICODE_STRING uniSourceName, uniTargetName;
2444 UNICODE_STRING uniFullTargetName, uniTargetParentName;
2445 BOOLEAN bCommonParent = FALSE;
2446 AFSDirectoryCB *pTargetDirEntry = NULL;
2447 AFSDirectoryCB *pNewTargetDirEntry = NULL;
2449 BOOLEAN bTargetEntryExists = FALSE;
2451 BOOLEAN bReleaseTargetDirLock = FALSE;
2452 ULONG ulNotificationAction = 0, ulNotifyFilter = 0;
2457 pSrcFileObj = pIrpSp->FileObject;
2459 pSrcFcb = (AFSFcb *)pSrcFileObj->FsContext;
2460 pSrcCcb = (AFSCcb *)pSrcFileObj->FsContext2;
2462 pSrcObject = pSrcFcb->ObjectInformation;
2464 if ( BooleanFlagOn( pSrcObject->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
2467 pSrcParentObject = AFSFindObjectInfo( pSrcObject->VolumeCB,
2468 &pSrcObject->ParentFileId,
2472 if( pSrcParentObject == NULL)
2475 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2476 AFS_TRACE_LEVEL_ERROR,
2477 "AFSSetFileLinkInfo Unable to resolve SrcParentObject (INVALID_PARAMETER)\n"));
2481 try_return( ntStatus = STATUS_INVALID_PARAMETER);
2484 pFileLinkInfo = (PFILE_LINK_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
2487 // Perform some basic checks to ensure FS integrity
2490 if( pSrcFcb->Header.NodeTypeCode != AFS_FILE_FCB)
2493 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2494 AFS_TRACE_LEVEL_ERROR,
2495 "AFSSetFileLinkInfo Attempt to non-file (INVALID_PARAMETER)\n"));
2497 try_return( ntStatus = STATUS_INVALID_PARAMETER);
2500 if( pTargetFileObj == NULL)
2503 if ( pFileLinkInfo->RootDirectory)
2507 // The target directory is provided by HANDLE
2508 // RootDirectory is only set when the target directory is not the same
2509 // as the source directory.
2511 // AFS only supports hard links within a single directory.
2513 // The IOManager should translate any Handle to a FileObject for us.
2514 // However, the failure to receive a FileObject is treated as a fatal
2518 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2519 AFS_TRACE_LEVEL_ERROR,
2520 "AFSSetFileLinkInfo Attempt to link %wZ to alternate directory by handle INVALID_PARAMETER\n",
2521 &pSrcCcb->DirectoryCB->NameInformation.FileName));
2523 try_return( ntStatus = STATUS_INVALID_PARAMETER);
2528 uniFullTargetName.Length = (USHORT)pFileLinkInfo->FileNameLength;
2530 uniFullTargetName.Buffer = (PWSTR)&pFileLinkInfo->FileName;
2532 AFSRetrieveFinalComponent( &uniFullTargetName,
2535 AFSRetrieveParentPath( &uniFullTargetName,
2536 &uniTargetParentName);
2538 if ( uniTargetParentName.Length == 0)
2542 // This is a simple rename. Here the target directory is the same as the source parent directory
2543 // and the name is retrieved from the system buffer information
2546 pTargetParentObject = pSrcParentObject;
2551 // uniTargetParentName contains the directory the renamed object
2552 // will be moved to. Must obtain the TargetParentObject.
2555 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2556 AFS_TRACE_LEVEL_ERROR,
2557 "AFSSetFileLinkInfo Attempt to link %wZ to alternate directory %wZ (NOT_SAME_DEVICE)\n",
2558 &pSrcCcb->DirectoryCB->NameInformation.FileName,
2559 &uniFullTargetName));
2561 try_return( ntStatus = STATUS_NOT_SAME_DEVICE);
2565 pTargetDcb = pTargetParentObject->Fcb;
2571 // So here we have the target directory taken from the targetfile object
2574 pTargetDcb = (AFSFcb *)pTargetFileObj->FsContext;
2576 pTargetDirCcb = (AFSCcb *)pTargetFileObj->FsContext2;
2578 pTargetParentObject = (AFSObjectInfoCB *)pTargetDcb->ObjectInformation;
2581 // Grab the target name which we setup in the IRP_MJ_CREATE handler. By how we set this up
2582 // it is only the target component of the rename operation
2585 uniTargetName = *((PUNICODE_STRING)&pTargetFileObj->FileName);
2589 // The quick check to see if they are self linking.
2590 // Do the names match? Only do this where the parent directories are
2594 if( pTargetParentObject == pSrcParentObject)
2597 if( FsRtlAreNamesEqual( &uniTargetName,
2602 try_return( ntStatus = STATUS_SUCCESS);
2605 bCommonParent = TRUE;
2611 // We do not allow cross-volume hard links
2614 if( pTargetParentObject->VolumeCB != pSrcObject->VolumeCB)
2617 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2618 AFS_TRACE_LEVEL_ERROR,
2619 "AFSSetFileLinkInfo Attempt to link to different volume %wZ\n",
2620 &pSrcCcb->DirectoryCB->NameInformation.FileName));
2622 try_return( ntStatus = STATUS_NOT_SAME_DEVICE);
2626 ulTargetCRC = AFSGenerateCRC( &uniTargetName,
2629 AFSAcquireExcl( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock,
2632 bReleaseTargetDirLock = TRUE;
2634 AFSLocateCaseSensitiveDirEntry( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
2638 if( pTargetDirEntry == NULL)
2642 // Missed so perform a case insensitive lookup
2645 ulTargetCRC = AFSGenerateCRC( &uniTargetName,
2648 AFSLocateCaseInsensitiveDirEntry( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
2653 if ( !BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
2654 pTargetDirEntry == NULL && RtlIsNameLegalDOS8Dot3( &uniTargetName,
2659 // Try the short name
2661 AFSLocateShortNameDirEntry( pTargetParentObject->Specific.Directory.ShortNameTree,
2667 // Increment our ref count on the dir entry
2670 if( pTargetDirEntry != NULL)
2673 ASSERT( BooleanFlagOn( pTargetDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_PARENT_FID) &&
2674 AFSIsEqualFID( &pTargetParentObject->FileId, &pTargetDirEntry->ObjectInformation->ParentFileId));
2676 lCount = InterlockedIncrement( &pTargetDirEntry->DirOpenReferenceCount);
2678 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2679 AFS_TRACE_LEVEL_VERBOSE,
2680 "AFSSetFileLinkInfo Increment count on %wZ DE %p Ccb %p Cnt %d\n",
2681 &pTargetDirEntry->NameInformation.FileName,
2686 ASSERT( lCount >= 0);
2688 if( !pFileLinkInfo->ReplaceIfExists)
2691 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2692 AFS_TRACE_LEVEL_ERROR,
2693 "AFSSetFileLinkInfo Attempt to link with target collision %wZ Target %wZ\n",
2694 &pSrcCcb->DirectoryCB->NameInformation.FileName,
2695 &pTargetDirEntry->NameInformation.FileName));
2697 try_return( ntStatus = STATUS_OBJECT_NAME_COLLISION);
2700 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING | AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2701 AFS_TRACE_LEVEL_ERROR,
2702 "AFSSetFileLinkInfo Target %wZ exists DE %p Count %d, performing delete of target\n",
2703 &pTargetDirEntry->NameInformation.FileName,
2708 // Pull the directory entry from the parent
2711 AFSRemoveDirNodeFromParent( pTargetParentObject,
2715 bTargetEntryExists = TRUE;
2719 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2720 AFS_TRACE_LEVEL_VERBOSE,
2721 "AFSSetFileLinkInfo Target does NOT exist, normal linking\n"));
2725 // OK, this is a simple rename. Issue the rename
2726 // request to the service.
2729 ntStatus = AFSNotifyHardLink( pSrcObject,
2730 &pSrcCcb->AuthGroup,
2732 pTargetDcb->ObjectInformation,
2733 pSrcCcb->DirectoryCB,
2735 pFileLinkInfo->ReplaceIfExists,
2736 &pNewTargetDirEntry);
2738 if( ntStatus != STATUS_REPARSE &&
2739 !NT_SUCCESS( ntStatus))
2742 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2743 AFS_TRACE_LEVEL_ERROR,
2744 "AFSSetFileLinkInfo Failed link of %wZ to target %wZ Status %08lX\n",
2745 &pSrcCcb->DirectoryCB->NameInformation.FileName,
2749 try_return( ntStatus);
2752 if ( ntStatus != STATUS_REPARSE)
2755 AFSInsertDirectoryNode( pTargetDcb->ObjectInformation,
2761 // Send notification for the target link file
2764 if( bTargetEntryExists || pNewTargetDirEntry)
2767 ulNotificationAction = FILE_ACTION_MODIFIED;
2772 ulNotificationAction = FILE_ACTION_ADDED;
2775 AFSFsRtlNotifyFullReportChange( pTargetParentObject,
2777 (ULONG)ulNotifyFilter,
2778 (ULONG)ulNotificationAction);
2782 if( !NT_SUCCESS( ntStatus))
2785 if( bTargetEntryExists)
2788 AFSInsertDirectoryNode( pTargetParentObject,
2794 if( pTargetDirEntry != NULL)
2798 // Release DirOpenReferenceCount obtained above
2801 lCount = InterlockedDecrement( &pTargetDirEntry->DirOpenReferenceCount);
2803 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2804 AFS_TRACE_LEVEL_VERBOSE,
2805 "AFSSetFileLinkInfo Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
2806 &pTargetDirEntry->NameInformation.FileName,
2811 ASSERT( lCount >= 0);
2814 if( pNewTargetDirEntry != NULL)
2818 // Release DirOpenReferenceCount obtained from AFSNotifyHardLink
2821 lCount = InterlockedDecrement( &pNewTargetDirEntry->DirOpenReferenceCount);
2823 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2824 AFS_TRACE_LEVEL_VERBOSE,
2825 "AFSSetFileLinkInfo Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
2826 &pNewTargetDirEntry->NameInformation.FileName,
2831 ASSERT( lCount >= 0);
2834 if( bReleaseTargetDirLock)
2837 AFSReleaseResource( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
2840 if ( pSrcParentObject != NULL)
2843 AFSReleaseObjectInfo( &pSrcParentObject);
2847 // No need to release pTargetParentObject as it is either a copy of pSrcParentObject
2848 // or (AFSFcb *)pTargetFileObj->FsContext->ObjectInformation
2851 pTargetParentObject = NULL;
2858 AFSSetRenameInfo( IN PIRP Irp)
2861 NTSTATUS ntStatus = STATUS_SUCCESS;
2862 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
2863 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2864 AFSFcb *pSrcFcb = NULL, *pTargetDcb = NULL, *pTargetFcb = NULL;
2865 AFSCcb *pSrcCcb = NULL, *pTargetDirCcb = NULL;
2866 PFILE_OBJECT pSrcFileObj = pIrpSp->FileObject;
2867 PFILE_OBJECT pTargetFileObj = pIrpSp->Parameters.SetFile.FileObject;
2868 PFILE_OBJECT pTargetParentFileObj = NULL;
2869 PFILE_RENAME_INFORMATION pRenameInfo = NULL;
2870 UNICODE_STRING uniTargetName, uniSourceName, uniTargetParentName;
2871 BOOLEAN bReplaceIfExists = FALSE;
2872 UNICODE_STRING uniShortName;
2873 AFSDirectoryCB *pTargetDirEntry = NULL;
2874 ULONG ulTargetCRC = 0;
2875 BOOLEAN bTargetEntryExists = FALSE;
2876 AFSObjectInfoCB *pSrcObject = NULL;
2877 AFSObjectInfoCB *pSrcParentObject = NULL, *pTargetParentObject = NULL;
2879 ULONG ulNotificationAction = 0, ulNotifyFilter = 0;
2880 UNICODE_STRING uniFullTargetName;
2881 BOOLEAN bCommonParent = FALSE;
2882 BOOLEAN bReleaseTargetDirLock = FALSE;
2883 BOOLEAN bReleaseSourceDirLock = FALSE;
2884 BOOLEAN bDereferenceTargetParentObject = FALSE;
2885 PERESOURCE pSourceDirLock = NULL;
2891 bReplaceIfExists = pIrpSp->Parameters.SetFile.ReplaceIfExists;
2893 pRenameInfo = (PFILE_RENAME_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
2895 pSrcFcb = (AFSFcb *)pSrcFileObj->FsContext;
2896 pSrcCcb = (AFSCcb *)pSrcFileObj->FsContext2;
2898 pSrcObject = pSrcFcb->ObjectInformation;
2900 if ( BooleanFlagOn( pSrcObject->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
2903 pSrcParentObject = AFSFindObjectInfo( pSrcObject->VolumeCB,
2904 &pSrcObject->ParentFileId,
2908 if( pSrcParentObject == NULL)
2911 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2912 AFS_TRACE_LEVEL_ERROR,
2913 "AFSSetRenameInfo Unable to resolve SrcParentObject (INVALID_PARAMETER)\n"));
2917 try_return( ntStatus = STATUS_INVALID_PARAMETER);
2921 // Perform some basic checks to ensure FS integrity
2924 if( pSrcFcb->Header.NodeTypeCode == AFS_ROOT_FCB)
2928 // Can't rename the root directory
2931 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2932 AFS_TRACE_LEVEL_ERROR,
2933 "AFSSetRenameInfo Attempt to rename root entry\n"));
2935 try_return( ntStatus = STATUS_INVALID_PARAMETER);
2938 if( pSrcFcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB)
2942 // If there are any open children then fail the rename
2945 if( pSrcObject->Specific.Directory.ChildOpenHandleCount > 0)
2948 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2949 AFS_TRACE_LEVEL_ERROR,
2950 "AFSSetRenameInfo Attempt to rename directory with open children %wZ\n",
2951 &pSrcCcb->DirectoryCB->NameInformation.FileName));
2953 try_return( ntStatus = STATUS_ACCESS_DENIED);
2959 // Extract off the final component name from the Fcb
2962 uniSourceName.Length = (USHORT)pSrcCcb->DirectoryCB->NameInformation.FileName.Length;
2963 uniSourceName.MaximumLength = uniSourceName.Length;
2965 uniSourceName.Buffer = pSrcCcb->DirectoryCB->NameInformation.FileName.Buffer;
2968 // Resolve the target fileobject
2971 if( pTargetFileObj == NULL)
2974 if ( pRenameInfo->RootDirectory)
2977 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2978 AFS_TRACE_LEVEL_ERROR,
2979 "AFSSetRenameInfo Handle provided but no FileObject ntStatus INVALID_PARAMETER\n"));
2981 try_return( ntStatus = STATUS_INVALID_PARAMETER);
2986 uniFullTargetName.Length = (USHORT)pRenameInfo->FileNameLength;
2988 uniFullTargetName.Buffer = (PWSTR)&pRenameInfo->FileName;
2990 AFSRetrieveFinalComponent( &uniFullTargetName,
2993 AFSRetrieveParentPath( &uniFullTargetName,
2994 &uniTargetParentName);
2996 if ( uniTargetParentName.Length == 0)
3000 // This is a simple rename. Here the target directory is the same as the source parent directory
3001 // and the name is retrieved from the system buffer information
3004 pTargetParentObject = pSrcParentObject;
3009 // uniTargetParentName contains the directory the renamed object
3010 // will be moved to. Must obtain the TargetParentObject.
3013 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3014 AFS_TRACE_LEVEL_ERROR,
3015 "AFSSetRenameInfo Attempt to move %wZ to %wZ -- not yet supported (NOT_SAME_DEVICE)\n",
3016 &pSrcCcb->DirectoryCB->NameInformation.FileName,
3017 &uniFullTargetName));
3019 try_return( ntStatus = STATUS_NOT_SAME_DEVICE);
3023 pTargetDcb = pTargetParentObject->Fcb;
3029 // So here we have the target directory taken from the targetfile object
3032 pTargetDcb = (AFSFcb *)pTargetFileObj->FsContext;
3034 pTargetDirCcb = (AFSCcb *)pTargetFileObj->FsContext2;
3036 pTargetParentObject = (AFSObjectInfoCB *)pTargetDcb->ObjectInformation;
3039 // Grab the target name which we setup in the IRP_MJ_CREATE handler. By how we set this up
3040 // it is only the target component of the rename operation
3043 uniTargetName = *((PUNICODE_STRING)&pTargetFileObj->FileName);
3047 // The quick check to see if they are not really performing a rename
3048 // Do the names match? Only do this where the parent directories are
3052 if( pTargetParentObject == pSrcParentObject)
3055 if( FsRtlAreNamesEqual( &uniTargetName,
3060 try_return( ntStatus = STATUS_SUCCESS);
3063 bCommonParent = TRUE;
3068 bCommonParent = FALSE;
3072 // We do not allow cross-volume renames to occur
3075 if( pTargetParentObject->VolumeCB != pSrcObject->VolumeCB)
3078 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3079 AFS_TRACE_LEVEL_ERROR,
3080 "AFSSetRenameInfo Attempt to rename directory to different volume %wZ\n",
3081 &pSrcCcb->DirectoryCB->NameInformation.FileName));
3083 try_return( ntStatus = STATUS_NOT_SAME_DEVICE);
3086 ulTargetCRC = AFSGenerateCRC( &uniTargetName,
3089 AFSAcquireExcl( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock,
3092 bReleaseTargetDirLock = TRUE;
3094 if( pTargetParentObject != pSrcParentObject)
3096 AFSAcquireExcl( pSrcParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock,
3099 bReleaseSourceDirLock = TRUE;
3101 pSourceDirLock = pSrcParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock;
3104 AFSLocateCaseSensitiveDirEntry( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
3108 if( pTargetDirEntry == NULL)
3112 // Missed so perform a case insensitive lookup
3115 ulTargetCRC = AFSGenerateCRC( &uniTargetName,
3118 AFSLocateCaseInsensitiveDirEntry( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
3123 if ( !BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
3124 pTargetDirEntry == NULL && RtlIsNameLegalDOS8Dot3( &uniTargetName,
3129 // Try the short name
3131 AFSLocateShortNameDirEntry( pTargetParentObject->Specific.Directory.ShortNameTree,
3137 // Increment our ref count on the dir entry
3140 if( pTargetDirEntry != NULL)
3143 ASSERT( BooleanFlagOn( pTargetDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_PARENT_FID) &&
3144 AFSIsEqualFID( &pTargetParentObject->FileId, &pTargetDirEntry->ObjectInformation->ParentFileId));
3146 lCount = InterlockedIncrement( &pTargetDirEntry->DirOpenReferenceCount);
3148 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3149 AFS_TRACE_LEVEL_VERBOSE,
3150 "AFSSetRenameInfo Increment count on %wZ DE %p Ccb %p Cnt %d\n",
3151 &pTargetDirEntry->NameInformation.FileName,
3156 ASSERT( lCount >= 0);
3158 if( !bReplaceIfExists)
3161 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3162 AFS_TRACE_LEVEL_ERROR,
3163 "AFSSetRenameInfo Attempt to rename directory with target collision %wZ Target %wZ\n",
3164 &pSrcCcb->DirectoryCB->NameInformation.FileName,
3165 &pTargetDirEntry->NameInformation.FileName));
3167 try_return( ntStatus = STATUS_OBJECT_NAME_COLLISION);
3170 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING | AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3171 AFS_TRACE_LEVEL_ERROR,
3172 "AFSSetRenameInfo Target %wZ exists DE %p Count %d, performing delete of target\n",
3173 &pTargetDirEntry->NameInformation.FileName,
3178 // Pull the directory entry from the parent
3181 AFSRemoveDirNodeFromParent( pTargetParentObject,
3185 bTargetEntryExists = TRUE;
3189 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3190 AFS_TRACE_LEVEL_VERBOSE,
3191 "AFSSetRenameInfo Target does NOT exist, normal rename\n"));
3195 // We need to remove the DirEntry from the parent node, update the index
3196 // and reinsert it into the parent tree. Note that for entries with the
3197 // same parent we do not pull the node from the enumeration list
3200 AFSRemoveDirNodeFromParent( pSrcParentObject,
3201 pSrcCcb->DirectoryCB,
3205 // OK, this is a simple rename. Issue the rename
3206 // request to the service.
3209 ntStatus = AFSNotifyRename( pSrcObject,
3210 &pSrcCcb->AuthGroup,
3212 pTargetDcb->ObjectInformation,
3213 pSrcCcb->DirectoryCB,
3217 if( !NT_SUCCESS( ntStatus))
3221 // Attempt to re-insert the directory entry
3224 AFSInsertDirectoryNode( pSrcParentObject,
3225 pSrcCcb->DirectoryCB,
3228 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3229 AFS_TRACE_LEVEL_ERROR,
3230 "AFSSetRenameInfo Failed rename of %wZ to target %wZ Status %08lX\n",
3231 &pSrcCcb->DirectoryCB->NameInformation.FileName,
3235 try_return( ntStatus);
3239 // Set the notification up for the source file
3242 if( pSrcParentObject == pTargetParentObject &&
3243 !bTargetEntryExists)
3246 ulNotificationAction = FILE_ACTION_RENAMED_OLD_NAME;
3251 ulNotificationAction = FILE_ACTION_REMOVED;
3254 if( pSrcObject->FileType == AFS_FILE_TYPE_DIRECTORY)
3257 ulNotifyFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
3262 ulNotifyFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
3265 AFSFsRtlNotifyFullReportChange( pSrcParentObject,
3267 (ULONG)ulNotifyFilter,
3268 (ULONG)ulNotificationAction);
3271 // Update the name in the dir entry.
3274 ntStatus = AFSUpdateDirEntryName( pSrcCcb->DirectoryCB,
3277 if( !NT_SUCCESS( ntStatus))
3281 // Attempt to re-insert the directory entry
3284 AFSInsertDirectoryNode( pSrcParentObject,
3285 pSrcCcb->DirectoryCB,
3288 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3289 AFS_TRACE_LEVEL_ERROR,
3290 "AFSSetRenameInfo Failed update of dir entry %wZ to target %wZ Status %08lX\n",
3291 &pSrcCcb->DirectoryCB->NameInformation.FileName,
3295 try_return( ntStatus);
3299 // Update the object information block, if needed
3302 if( !AFSIsEqualFID( &pSrcObject->FileId,
3306 AFSAcquireExcl( pSrcObject->VolumeCB->ObjectInfoTree.TreeLock,
3310 // Remove the old information entry
3313 AFSRemoveHashEntry( &pSrcObject->VolumeCB->ObjectInfoTree.TreeHead,
3314 &pSrcObject->TreeEntry);
3316 RtlCopyMemory( &pSrcObject->FileId,
3318 sizeof( AFSFileID));
3321 // Insert the entry into the new object table.
3324 pSrcObject->TreeEntry.HashIndex = AFSCreateLowIndex( &pSrcObject->FileId);
3326 if( pSrcObject->VolumeCB->ObjectInfoTree.TreeHead == NULL)
3329 pSrcObject->VolumeCB->ObjectInfoTree.TreeHead = &pSrcObject->TreeEntry;
3334 if ( !NT_SUCCESS( AFSInsertHashEntry( pSrcObject->VolumeCB->ObjectInfoTree.TreeHead,
3335 &pSrcObject->TreeEntry)))
3339 // Lost a race, an ObjectInfo object already exists for this FID.
3340 // Let this copy be garbage collected.
3343 ClearFlag( pSrcObject->Flags, AFS_OBJECT_INSERTED_HASH_TREE);
3347 AFSReleaseResource( pSrcObject->VolumeCB->ObjectInfoTree.TreeLock);
3351 // Update the hash values for the name trees.
3354 pSrcCcb->DirectoryCB->CaseSensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pSrcCcb->DirectoryCB->NameInformation.FileName,
3357 pSrcCcb->DirectoryCB->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pSrcCcb->DirectoryCB->NameInformation.FileName,
3360 if( !BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
3361 pSrcCcb->DirectoryCB->NameInformation.ShortNameLength > 0 &&
3362 !RtlIsNameLegalDOS8Dot3( &pSrcCcb->DirectoryCB->NameInformation.FileName,
3367 uniShortName.Length = pSrcCcb->DirectoryCB->NameInformation.ShortNameLength;
3368 uniShortName.MaximumLength = uniShortName.Length;
3369 uniShortName.Buffer = pSrcCcb->DirectoryCB->NameInformation.ShortName;
3371 pSrcCcb->DirectoryCB->Type.Data.ShortNameTreeEntry.HashIndex = AFSGenerateCRC( &uniShortName,
3374 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3375 AFS_TRACE_LEVEL_VERBOSE,
3376 "AFSSetRenameInfo Initialized short name hash for %wZ longname %wZ\n",
3378 &pSrcCcb->DirectoryCB->NameInformation.FileName));
3383 pSrcCcb->DirectoryCB->Type.Data.ShortNameTreeEntry.HashIndex = 0;
3390 // Update the file index for the object in the new parent
3393 pSrcCcb->DirectoryCB->FileIndex = (ULONG)InterlockedIncrement( &pTargetParentObject->Specific.Directory.DirectoryNodeHdr.ContentIndex);
3397 // Re-insert the directory entry
3400 AFSInsertDirectoryNode( pTargetParentObject,
3401 pSrcCcb->DirectoryCB,
3405 // Update the parent pointer in the source object if they are different
3408 if( pSrcParentObject != pTargetParentObject)
3411 lCount = InterlockedDecrement( &pSrcParentObject->Specific.Directory.ChildOpenHandleCount);
3413 lCount = InterlockedDecrement( &pSrcParentObject->Specific.Directory.ChildOpenReferenceCount);
3415 lCount = InterlockedIncrement( &pTargetParentObject->Specific.Directory.ChildOpenHandleCount);
3417 lCount = InterlockedIncrement( &pTargetParentObject->Specific.Directory.ChildOpenReferenceCount);
3421 // Guaranteed to be in the same volume
3424 AFSAcquireExcl( pSrcParentObject->VolumeCB->ObjectInfoTree.TreeLock,
3427 lCount = AFSObjectInfoIncrement( pTargetParentObject,
3428 AFS_OBJECT_REFERENCE_CHILD);
3430 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
3431 AFS_TRACE_LEVEL_VERBOSE,
3432 "AFSSetRenameInfo Increment count on parent object %p Cnt %d\n",
3433 pTargetParentObject,
3436 lCount = AFSObjectInfoDecrement( pSrcParentObject,
3437 AFS_OBJECT_REFERENCE_CHILD);
3439 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
3440 AFS_TRACE_LEVEL_VERBOSE,
3441 "AFSSetRenameInfo Decrement count on parent object %p Cnt %d\n",
3445 pSrcObject->ParentFileId = pTargetParentObject->FileId;
3447 SetFlag( pSrcObject->Flags, AFS_OBJECT_FLAGS_PARENT_FID);
3449 AFSReleaseResource( pSrcParentObject->VolumeCB->ObjectInfoTree.TreeLock);
3451 ulNotificationAction = FILE_ACTION_ADDED;
3456 ulNotificationAction = FILE_ACTION_RENAMED_NEW_NAME;
3460 // Now update the notification for the target file
3463 AFSFsRtlNotifyFullReportChange( pTargetParentObject,
3465 (ULONG)ulNotifyFilter,
3466 (ULONG)ulNotificationAction);
3469 // If we performed the rename of the target because it existed, we now need to
3470 // delete the tmp target we created above
3473 if( bTargetEntryExists)
3476 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3477 AFS_TRACE_LEVEL_VERBOSE,
3478 "AFSSetRenameInfo Setting DELETE flag in dir entry %p name %wZ\n",
3480 &pTargetDirEntry->NameInformation.FileName));
3482 SetFlag( pTargetDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
3485 // Try and purge the cache map if this is a file
3488 if( pTargetDirEntry->ObjectInformation->FileType == AFS_FILE_TYPE_FILE &&
3489 pTargetDirEntry->ObjectInformation->Fcb != NULL &&
3490 pTargetDirEntry->DirOpenReferenceCount > 1)
3493 pTargetFcb = pTargetDirEntry->ObjectInformation->Fcb;
3496 ASSERT( pTargetDirEntry->DirOpenReferenceCount > 0);
3498 lCount = InterlockedDecrement( &pTargetDirEntry->DirOpenReferenceCount); // The count we added above
3500 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3501 AFS_TRACE_LEVEL_VERBOSE,
3502 "AFSSetRenameInfo Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
3503 &pTargetDirEntry->NameInformation.FileName,
3508 ASSERT( lCount >= 0);
3511 pTargetDirEntry->NameArrayReferenceCount <= 0)
3514 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3515 AFS_TRACE_LEVEL_VERBOSE,
3516 "AFSSetRenameInfo Deleting dir entry %p name %wZ\n",
3518 &pTargetDirEntry->NameInformation.FileName));
3520 AFSDeleteDirEntry( pTargetParentObject,
3524 pTargetDirEntry = NULL;
3526 if ( pTargetFcb != NULL)
3530 // Do not hold TreeLocks across the MmForceSectionClosed() call as
3531 // it can deadlock with Trend Micro's TmPreFlt!TmpQueryFullName
3534 if( bReleaseTargetDirLock)
3536 AFSReleaseResource( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
3538 bReleaseTargetDirLock = FALSE;
3541 if( bReleaseSourceDirLock)
3544 AFSReleaseResource( pSourceDirLock);
3546 bReleaseSourceDirLock = FALSE;
3550 // MmForceSectionClosed() can eventually call back into AFSCleanup
3551 // which will need to acquire Fcb->Resource exclusively. Failure
3552 // to obtain it here before holding the SectionObjectResource will
3553 // permit the locks to be obtained out of order risking a deadlock.
3556 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
3557 AFS_TRACE_LEVEL_VERBOSE,
3558 "AFSSetRenameInfo Acquiring Fcb lock %p EXCL %08lX\n",
3559 &pTargetFcb->NPFcb->Resource,
3560 PsGetCurrentThread()));
3562 AFSAcquireExcl( &pTargetFcb->NPFcb->Resource,
3565 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
3566 AFS_TRACE_LEVEL_VERBOSE,
3567 "AFSSetRenameInfo Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
3568 &pTargetFcb->NPFcb->SectionObjectResource,
3569 PsGetCurrentThread()));
3571 AFSAcquireExcl( &pTargetFcb->NPFcb->SectionObjectResource,
3578 // Close the section in the event it was mapped
3581 if( !MmForceSectionClosed( &pTargetFcb->NPFcb->SectionObjectPointers,
3585 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3586 AFS_TRACE_LEVEL_ERROR,
3587 "AFSSetRenameInfo Failed to delete section for target file %wZ\n",
3591 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
3594 ntStatus = GetExceptionCode();
3598 "EXCEPTION - AFSSetRenameInfo MmForceSectionClosed failed FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
3599 pTargetFcb->ObjectInformation->FileId.Cell,
3600 pTargetFcb->ObjectInformation->FileId.Volume,
3601 pTargetFcb->ObjectInformation->FileId.Vnode,
3602 pTargetFcb->ObjectInformation->FileId.Unique,
3606 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
3607 AFS_TRACE_LEVEL_VERBOSE,
3608 "AFSSetRenameInfo Releasing Fcb SectionObject lock %p EXCL %08lX\n",
3609 &pTargetFcb->NPFcb->SectionObjectResource,
3610 PsGetCurrentThread()));
3612 AFSReleaseResource( &pTargetFcb->NPFcb->SectionObjectResource);
3614 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3615 AFS_TRACE_LEVEL_VERBOSE,
3616 "AFSSetRenameInfo Releasing Fcb lock %p EXCL %08lX\n",
3617 &pTargetFcb->NPFcb->Resource,
3618 PsGetCurrentThread()));
3620 AFSReleaseResource( &pTargetFcb->NPFcb->Resource);
3626 if( !NT_SUCCESS( ntStatus))
3629 if( bTargetEntryExists)
3632 ASSERT( pTargetParentObject != NULL);
3634 AFSInsertDirectoryNode( pTargetParentObject,
3640 if( pTargetDirEntry != NULL)
3643 lCount = InterlockedDecrement( &pTargetDirEntry->DirOpenReferenceCount);
3645 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3646 AFS_TRACE_LEVEL_VERBOSE,
3647 "AFSSetRenameInfo Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
3648 &pTargetDirEntry->NameInformation.FileName,
3653 ASSERT( lCount >= 0);
3656 if( bReleaseTargetDirLock)
3659 AFSReleaseResource( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
3662 if( bReleaseSourceDirLock)
3665 AFSReleaseResource( pSourceDirLock);
3668 if ( bDereferenceTargetParentObject)
3671 ObDereferenceObject( pTargetParentFileObj);
3674 if ( pSrcParentObject != NULL)
3677 AFSReleaseObjectInfo( &pSrcParentObject);
3681 // No need to release pTargetParentObject as it is either a copy of pSrcParentObject
3682 // or (AFSFcb *)pTargetFileObj->FsContext->ObjectInformation
3685 pTargetParentObject = NULL;
3692 AFSSetPositionInfo( IN PIRP Irp,
3693 IN AFSDirectoryCB *DirectoryCB)
3695 UNREFERENCED_PARAMETER(DirectoryCB);
3696 NTSTATUS ntStatus = STATUS_SUCCESS;
3697 PFILE_POSITION_INFORMATION pBuffer;
3698 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
3700 pBuffer = (PFILE_POSITION_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
3702 pIrpSp->FileObject->CurrentByteOffset.QuadPart = pBuffer->CurrentByteOffset.QuadPart;
3708 AFSSetAllocationInfo( IN PIRP Irp,
3709 IN AFSDirectoryCB *DirectoryCB)
3711 UNREFERENCED_PARAMETER(DirectoryCB);
3712 NTSTATUS ntStatus = STATUS_SUCCESS;
3713 PFILE_ALLOCATION_INFORMATION pBuffer;
3714 BOOLEAN bReleasePaging = FALSE;
3715 BOOLEAN bTellCc = FALSE;
3716 BOOLEAN bTellService = FALSE;
3717 BOOLEAN bUserMapped = FALSE;
3718 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
3719 PFILE_OBJECT pFileObject = pIrpSp->FileObject;
3720 AFSFcb *pFcb = NULL;
3721 AFSCcb *pCcb = NULL;
3722 LARGE_INTEGER liSaveAlloc;
3723 LARGE_INTEGER liSaveFileSize;
3724 LARGE_INTEGER liSaveVDL;
3726 pBuffer = (PFILE_ALLOCATION_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
3728 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
3730 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
3733 // save values to put back
3735 liSaveAlloc = pFcb->Header.AllocationSize;
3736 liSaveFileSize = pFcb->Header.FileSize;
3737 liSaveVDL = pFcb->Header.ValidDataLength;
3739 if( pFcb->Header.AllocationSize.QuadPart == pBuffer->AllocationSize.QuadPart ||
3740 pIrpSp->Parameters.SetFile.AdvanceOnly)
3742 return STATUS_SUCCESS ;
3745 if( pFcb->Header.AllocationSize.QuadPart > pBuffer->AllocationSize.QuadPart)
3748 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
3749 AFS_TRACE_LEVEL_VERBOSE,
3750 "AFSSetAllocationInfo Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
3751 &pFcb->NPFcb->SectionObjectResource,
3752 PsGetCurrentThread()));
3754 AFSAcquireExcl( &pFcb->NPFcb->SectionObjectResource,
3760 bUserMapped = !MmCanFileBeTruncated( pFileObject->SectionObjectPointer,
3761 &pBuffer->AllocationSize);
3763 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
3766 bUserMapped = FALSE;
3768 ntStatus = GetExceptionCode();
3772 "EXCEPTION - AFSSetAllocationInfo MmCanFileBeTruncated failed FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
3773 pFcb->ObjectInformation->FileId.Cell,
3774 pFcb->ObjectInformation->FileId.Volume,
3775 pFcb->ObjectInformation->FileId.Vnode,
3776 pFcb->ObjectInformation->FileId.Unique,
3780 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
3781 AFS_TRACE_LEVEL_VERBOSE,
3782 "AFSSetAllocationInfo Releasing Fcb SectionObject lock %p EXCL %08lX\n",
3783 &pFcb->NPFcb->SectionObjectResource,
3784 PsGetCurrentThread()));
3786 AFSReleaseResource( &pFcb->NPFcb->SectionObjectResource);
3789 // Truncating the file
3794 ntStatus = STATUS_USER_MAPPED_FILE ;
3800 // If this is a truncation we need to grab the paging IO resource.
3803 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3804 AFS_TRACE_LEVEL_VERBOSE,
3805 "AFSSetAllocationInfo Acquiring Fcb PagingIo lock %p EXCL %08lX\n",
3806 &pFcb->NPFcb->PagingResource,
3807 PsGetCurrentThread()));
3809 AFSAcquireExcl( &pFcb->NPFcb->PagingResource,
3812 bReleasePaging = TRUE;
3815 // Must drop the Fcb Resource. When changing the file size
3816 // a deadlock can occur with Trend Micro's filter if the file
3817 // size is set to zero.
3820 AFSReleaseResource( &pFcb->NPFcb->Resource);
3822 pFcb->Header.AllocationSize = pBuffer->AllocationSize;
3824 pFcb->ObjectInformation->AllocationSize = pBuffer->AllocationSize;
3827 // Tell Cc that Allocation is moved.
3831 if( pFcb->Header.FileSize.QuadPart > pBuffer->AllocationSize.QuadPart)
3834 // We are pulling the EOF back as well so we need to tell
3837 bTellService = TRUE;
3839 pFcb->Header.FileSize = pBuffer->AllocationSize;
3841 pFcb->ObjectInformation->EndOfFile = pBuffer->AllocationSize;
3849 // Tell Cc if allocation is increased.
3852 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3853 AFS_TRACE_LEVEL_VERBOSE,
3854 "AFSSetAllocationInfo Acquiring Fcb PagingIo lock %p EXCL %08lX\n",
3855 &pFcb->NPFcb->PagingResource,
3856 PsGetCurrentThread()));
3858 AFSAcquireExcl( &pFcb->NPFcb->PagingResource,
3861 bReleasePaging = TRUE;
3864 // Must drop the Fcb Resource. When changing the file size
3865 // a deadlock can occur with Trend Micro's filter if the file
3866 // size is set to zero.
3869 AFSReleaseResource( &pFcb->NPFcb->Resource);
3871 bTellCc = pBuffer->AllocationSize.QuadPart > pFcb->Header.AllocationSize.QuadPart;
3873 pFcb->Header.AllocationSize = pBuffer->AllocationSize;
3875 pFcb->ObjectInformation->AllocationSize = pBuffer->AllocationSize;
3879 // Now Tell the server if we have to
3884 ASSERT( BooleanFlagOn( pFcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_PARENT_FID));
3886 ntStatus = AFSUpdateFileInformation( &pFcb->ObjectInformation->ParentFileId,
3887 pFcb->ObjectInformation,
3891 if (NT_SUCCESS(ntStatus))
3894 // Trim extents if we told the service - the update has done an implicit
3895 // trim at the service.
3899 AFSTrimExtents( pFcb,
3900 &pFcb->Header.FileSize);
3903 KeQuerySystemTime( &pFcb->ObjectInformation->ChangeTime);
3905 SetFlag( pFcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_CHANGE_TIME);
3908 CcIsFileCached( pFileObject))
3910 CcSetFileSizes( pFileObject,
3911 (PCC_FILE_SIZES)&pFcb->Header.AllocationSize);
3915 // Mark the file as modified so as to reflect the change into the last write on close.
3917 SetFlag( pFileObject->Flags, FO_FILE_MODIFIED);
3922 // Put the saved values back
3924 pFcb->Header.ValidDataLength = liSaveVDL;
3925 pFcb->Header.FileSize = liSaveFileSize;
3926 pFcb->Header.AllocationSize = liSaveAlloc;
3927 pFcb->ObjectInformation->EndOfFile = liSaveFileSize;
3928 pFcb->ObjectInformation->AllocationSize = liSaveAlloc;
3934 AFSReleaseResource( &pFcb->NPFcb->PagingResource);
3936 AFSAcquireExcl( &pFcb->NPFcb->Resource,
3944 AFSSetEndOfFileInfo( IN PIRP Irp,
3945 IN AFSDirectoryCB *DirectoryCB)
3947 UNREFERENCED_PARAMETER(DirectoryCB);
3948 NTSTATUS ntStatus = STATUS_SUCCESS;
3949 PFILE_END_OF_FILE_INFORMATION pBuffer;
3950 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
3951 PFILE_OBJECT pFileObject = pIrpSp->FileObject;
3952 LARGE_INTEGER liSaveSize;
3953 LARGE_INTEGER liSaveVDL;
3954 LARGE_INTEGER liSaveAlloc;
3955 BOOLEAN bModified = FALSE;
3956 BOOLEAN bReleasePaging = FALSE;
3957 BOOLEAN bTruncated = FALSE;
3958 BOOLEAN bUserMapped = FALSE;
3959 AFSFcb *pFcb = NULL;
3960 AFSCcb *pCcb = NULL;
3962 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
3964 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
3966 pBuffer = (PFILE_END_OF_FILE_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
3968 liSaveSize = pFcb->Header.FileSize;
3969 liSaveAlloc = pFcb->Header.AllocationSize;
3970 liSaveVDL = pFcb->Header.ValidDataLength;
3972 if( pFcb->Header.FileSize.QuadPart != pBuffer->EndOfFile.QuadPart &&
3973 !pIrpSp->Parameters.SetFile.AdvanceOnly)
3976 if( pBuffer->EndOfFile.QuadPart < pFcb->Header.FileSize.QuadPart)
3979 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
3980 AFS_TRACE_LEVEL_VERBOSE,
3981 "AFSSetEndOfFileInfo Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
3982 &pFcb->NPFcb->SectionObjectResource,
3983 PsGetCurrentThread()));
3985 AFSAcquireExcl( &pFcb->NPFcb->SectionObjectResource,
3991 bUserMapped = !MmCanFileBeTruncated( pFileObject->SectionObjectPointer,
3992 &pBuffer->EndOfFile);
3994 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
3997 bUserMapped = FALSE;
3999 ntStatus = GetExceptionCode();
4003 "EXCEPTION - AFSSetEndOfFileInfo MmCanFileBeTruncated failed FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
4004 pFcb->ObjectInformation->FileId.Cell,
4005 pFcb->ObjectInformation->FileId.Volume,
4006 pFcb->ObjectInformation->FileId.Vnode,
4007 pFcb->ObjectInformation->FileId.Unique,
4011 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
4012 AFS_TRACE_LEVEL_VERBOSE,
4013 "AFSSetEndOfFileInfo Releasing Fcb SectionObject lock %p EXCL %08lX\n",
4014 &pFcb->NPFcb->SectionObjectResource,
4015 PsGetCurrentThread()));
4017 AFSReleaseResource( &pFcb->NPFcb->SectionObjectResource);
4019 // Truncating the file
4023 ntStatus = STATUS_USER_MAPPED_FILE;
4029 // If this is a truncation we need to grab the paging
4032 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
4033 AFS_TRACE_LEVEL_VERBOSE,
4034 "AFSSetEndOfFileInfo Acquiring Fcb PagingIo lock %p EXCL %08lX\n",
4035 &pFcb->NPFcb->PagingResource,
4036 PsGetCurrentThread()));
4038 AFSAcquireExcl( &pFcb->NPFcb->PagingResource,
4041 bReleasePaging = TRUE;
4044 // Must drop the Fcb Resource. When changing the file size
4045 // a deadlock can occur with Trend Micro's filter if the file
4046 // size is set to zero.
4049 AFSReleaseResource( &pFcb->NPFcb->Resource);
4051 pFcb->Header.AllocationSize = pBuffer->EndOfFile;
4053 pFcb->Header.FileSize = pBuffer->EndOfFile;
4055 pFcb->ObjectInformation->EndOfFile = pBuffer->EndOfFile;
4057 pFcb->ObjectInformation->AllocationSize = pBuffer->EndOfFile;
4059 if( pFcb->Header.ValidDataLength.QuadPart > pFcb->Header.FileSize.QuadPart)
4062 pFcb->Header.ValidDataLength = pFcb->Header.FileSize;
4074 // extending the file, move EOF
4078 // If this is a truncation we need to grab the paging
4081 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
4082 AFS_TRACE_LEVEL_VERBOSE,
4083 "AFSSetEndOfFileInfo Acquiring Fcb PagingIo lock %p EXCL %08lX\n",
4084 &pFcb->NPFcb->PagingResource,
4085 PsGetCurrentThread()));
4087 AFSAcquireExcl( &pFcb->NPFcb->PagingResource,
4090 bReleasePaging = TRUE;
4093 // Must drop the Fcb Resource. When changing the file size
4094 // a deadlock can occur with Trend Micro's filter if the file
4095 // size is set to zero.
4098 AFSReleaseResource( &pFcb->NPFcb->Resource);
4100 pFcb->Header.FileSize = pBuffer->EndOfFile;
4102 pFcb->ObjectInformation->EndOfFile = pBuffer->EndOfFile;
4104 if (pFcb->Header.FileSize.QuadPart > pFcb->Header.AllocationSize.QuadPart)
4107 // And Allocation as needed.
4109 pFcb->Header.AllocationSize = pBuffer->EndOfFile;
4111 pFcb->ObjectInformation->AllocationSize = pBuffer->EndOfFile;
4121 KeQuerySystemTime( &pFcb->ObjectInformation->ChangeTime);
4123 SetFlag( pFcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_CHANGE_TIME);
4129 ASSERT( BooleanFlagOn( pFcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_PARENT_FID));
4131 ntStatus = AFSUpdateFileInformation( &pFcb->ObjectInformation->ParentFileId,
4132 pFcb->ObjectInformation,
4135 if( NT_SUCCESS(ntStatus))
4138 // We are now good to go so tell CC.
4140 CcSetFileSizes( pFileObject,
4141 (PCC_FILE_SIZES)&pFcb->Header.AllocationSize);
4144 // And give up those extents
4149 AFSTrimExtents( pFcb,
4150 &pFcb->Header.FileSize);
4154 // Mark the file as modified so as to reflect the change into the last write on close.
4156 SetFlag( pFileObject->Flags, FO_FILE_MODIFIED);
4160 pFcb->Header.ValidDataLength = liSaveVDL;
4161 pFcb->Header.FileSize = liSaveSize;
4162 pFcb->Header.AllocationSize = liSaveAlloc;
4163 pFcb->ObjectInformation->EndOfFile = liSaveSize;
4164 pFcb->ObjectInformation->AllocationSize = liSaveAlloc;
4171 AFSReleaseResource( &pFcb->NPFcb->PagingResource);
4173 AFSAcquireExcl( &pFcb->NPFcb->Resource,
4181 AFSProcessShareSetInfo( IN IRP *Irp,
4186 UNREFERENCED_PARAMETER(Fcb);
4187 NTSTATUS ntStatus = STATUS_SUCCESS;
4188 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
4189 FILE_INFORMATION_CLASS ulFileInformationClass;
4190 void *pPipeInfo = NULL;
4194 ulFileInformationClass = pIrpSp->Parameters.SetFile.FileInformationClass;
4196 AFSDbgTrace(( AFS_SUBSYSTEM_PIPE_PROCESSING,
4197 AFS_TRACE_LEVEL_VERBOSE,
4198 "AFSProcessShareSetInfo On pipe %wZ Class %08lX\n",
4199 &Ccb->DirectoryCB->NameInformation.FileName,
4200 ulFileInformationClass));
4202 pPipeInfo = AFSLockSystemBuffer( Irp,
4203 pIrpSp->Parameters.SetFile.Length);
4205 if( pPipeInfo == NULL)
4208 AFSDbgTrace(( AFS_SUBSYSTEM_PIPE_PROCESSING,
4209 AFS_TRACE_LEVEL_ERROR,
4210 "AFSProcessShareSetInfo Failed to lock buffer on pipe %wZ\n",
4211 &Ccb->DirectoryCB->NameInformation.FileName));
4213 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4217 // Send the request to the service
4220 ntStatus = AFSNotifySetPipeInfo( Ccb,
4221 (ULONG)ulFileInformationClass,
4222 pIrpSp->Parameters.SetFile.Length,
4225 if( !NT_SUCCESS( ntStatus))
4228 AFSDbgTrace(( AFS_SUBSYSTEM_PIPE_PROCESSING,
4229 AFS_TRACE_LEVEL_ERROR,
4230 "AFSProcessShareSetInfo Failed to send request to service on pipe %wZ Status %08lX\n",
4231 &Ccb->DirectoryCB->NameInformation.FileName,
4234 try_return( ntStatus);
4237 AFSDbgTrace(( AFS_SUBSYSTEM_PIPE_PROCESSING,
4238 AFS_TRACE_LEVEL_VERBOSE,
4239 "AFSProcessShareSetInfo Completed request on pipe %wZ Class %08lX\n",
4240 &Ccb->DirectoryCB->NameInformation.FileName,
4241 ulFileInformationClass));
4252 AFSProcessShareQueryInfo( IN IRP *Irp,
4257 UNREFERENCED_PARAMETER(Fcb);
4258 NTSTATUS ntStatus = STATUS_SUCCESS;
4259 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
4260 FILE_INFORMATION_CLASS ulFileInformationClass;
4261 void *pPipeInfo = NULL;
4266 ulFileInformationClass = pIrpSp->Parameters.QueryFile.FileInformationClass;
4268 AFSDbgTrace(( AFS_SUBSYSTEM_PIPE_PROCESSING,
4269 AFS_TRACE_LEVEL_VERBOSE,
4270 "AFSProcessShareQueryInfo On pipe %wZ Class %08lX\n",
4271 &Ccb->DirectoryCB->NameInformation.FileName,
4272 ulFileInformationClass));
4274 pPipeInfo = AFSLockSystemBuffer( Irp,
4275 pIrpSp->Parameters.QueryFile.Length);
4277 if( pPipeInfo == NULL)
4280 AFSDbgTrace(( AFS_SUBSYSTEM_PIPE_PROCESSING,
4281 AFS_TRACE_LEVEL_ERROR,
4282 "AFSProcessShareQueryInfo Failed to lock buffer on pipe %wZ\n",
4283 &Ccb->DirectoryCB->NameInformation.FileName));
4285 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4289 // Send the request to the service
4292 ntStatus = AFSNotifyQueryPipeInfo( Ccb,
4293 (ULONG)ulFileInformationClass,
4294 pIrpSp->Parameters.QueryFile.Length,
4296 (ULONG *)&Irp->IoStatus.Information);
4298 if( !NT_SUCCESS( ntStatus))
4301 AFSDbgTrace(( AFS_SUBSYSTEM_PIPE_PROCESSING,
4302 AFS_TRACE_LEVEL_ERROR,
4303 "AFSProcessShareQueryInfo Failed to send request to service on pipe %wZ Status %08lX\n",
4304 &Ccb->DirectoryCB->NameInformation.FileName,
4307 try_return( ntStatus);
4310 AFSDbgTrace(( AFS_SUBSYSTEM_PIPE_PROCESSING,
4311 AFS_TRACE_LEVEL_VERBOSE,
4312 "AFSProcessShareQueryInfo Completed request on pipe %wZ Class %08lX\n",
4313 &Ccb->DirectoryCB->NameInformation.FileName,
4314 ulFileInformationClass));
4325 AFSProcessPIOCtlQueryInfo( IN IRP *Irp,
4328 IN OUT LONG *Length)
4331 UNREFERENCED_PARAMETER(Fcb);
4332 UNREFERENCED_PARAMETER(Ccb);
4333 NTSTATUS ntStatus = STATUS_SUCCESS;
4334 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
4335 FILE_INFORMATION_CLASS ulFileInformationClass;
4340 ulFileInformationClass = pIrpSp->Parameters.QueryFile.FileInformationClass;
4342 switch( ulFileInformationClass)
4345 case FileBasicInformation:
4348 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4349 AFS_TRACE_LEVEL_VERBOSE,
4350 "AFSProcessPIOCtlQueryInfo (FileBasicInformation)\n"));
4352 if ( *Length >= sizeof( FILE_BASIC_INFORMATION))
4354 PFILE_BASIC_INFORMATION pBasic = (PFILE_BASIC_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
4356 pBasic->CreationTime.QuadPart = 0;
4357 pBasic->LastAccessTime.QuadPart = 0;
4358 pBasic->ChangeTime.QuadPart = 0;
4359 pBasic->LastWriteTime.QuadPart = 0;
4360 pBasic->FileAttributes = FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM;
4362 *Length -= sizeof( FILE_BASIC_INFORMATION);
4366 ntStatus = STATUS_BUFFER_TOO_SMALL;
4372 case FileStandardInformation:
4375 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4376 AFS_TRACE_LEVEL_VERBOSE,
4377 "AFSProcessPIOCtlQueryInfo (FileStandardInformation)\n"));
4379 if ( *Length >= sizeof( FILE_STANDARD_INFORMATION))
4381 PFILE_STANDARD_INFORMATION pStandard = (PFILE_STANDARD_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
4383 pStandard->NumberOfLinks = 1;
4384 pStandard->DeletePending = 0;
4385 pStandard->AllocationSize.QuadPart = 0;
4386 pStandard->EndOfFile.QuadPart = 0;
4387 pStandard->Directory = 0;
4389 *Length -= sizeof( FILE_STANDARD_INFORMATION);
4393 ntStatus = STATUS_BUFFER_TOO_SMALL;
4399 case FileNormalizedNameInformation:
4400 case FileNameInformation:
4403 ULONG ulCopyLength = 0;
4404 AFSFcb *pFcb = NULL;
4405 AFSCcb *pCcb = NULL;
4406 USHORT usFullNameLength = 0;
4407 PFILE_NAME_INFORMATION pNameInfo = (PFILE_NAME_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
4408 UNICODE_STRING uniName;
4410 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4411 AFS_TRACE_LEVEL_VERBOSE,
4412 "AFSProcessPIOCtlQueryInfo (FileNameInformation)\n"));
4414 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
4415 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
4417 if( *Length < FIELD_OFFSET( FILE_NAME_INFORMATION, FileName))
4419 ntStatus = STATUS_BUFFER_TOO_SMALL;
4423 RtlZeroMemory( pNameInfo,
4426 usFullNameLength = sizeof( WCHAR) +
4427 AFSServerName.Length +
4428 pCcb->FullFileName.Length;
4430 if( *Length >= (LONG)(FIELD_OFFSET( FILE_NAME_INFORMATION, FileName) + (LONG)usFullNameLength))
4432 ulCopyLength = (LONG)usFullNameLength;
4436 ulCopyLength = *Length - FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
4437 ntStatus = STATUS_BUFFER_OVERFLOW;
4440 pNameInfo->FileNameLength = (ULONG)usFullNameLength;
4442 *Length -= FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
4444 if( ulCopyLength > 0)
4447 pNameInfo->FileName[ 0] = L'\\';
4448 ulCopyLength -= sizeof( WCHAR);
4450 *Length -= sizeof( WCHAR);
4452 if( ulCopyLength >= AFSServerName.Length)
4455 RtlCopyMemory( &pNameInfo->FileName[ 1],
4456 AFSServerName.Buffer,
4457 AFSServerName.Length);
4459 ulCopyLength -= AFSServerName.Length;
4460 *Length -= AFSServerName.Length;
4462 if( ulCopyLength >= pCcb->FullFileName.Length)
4465 RtlCopyMemory( &pNameInfo->FileName[ 1 + (AFSServerName.Length/sizeof( WCHAR))],
4466 pCcb->FullFileName.Buffer,
4467 pCcb->FullFileName.Length);
4469 ulCopyLength -= pCcb->FullFileName.Length;
4470 *Length -= pCcb->FullFileName.Length;
4472 uniName.Length = (USHORT)pNameInfo->FileNameLength;
4473 uniName.MaximumLength = uniName.Length;
4474 uniName.Buffer = pNameInfo->FileName;
4479 RtlCopyMemory( &pNameInfo->FileName[ 1 + (AFSServerName.Length/sizeof( WCHAR))],
4480 pCcb->FullFileName.Buffer,
4483 *Length -= ulCopyLength;
4485 uniName.Length = (USHORT)(sizeof( WCHAR) + AFSServerName.Length + ulCopyLength);
4486 uniName.MaximumLength = uniName.Length;
4487 uniName.Buffer = pNameInfo->FileName;
4490 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4491 AFS_TRACE_LEVEL_VERBOSE,
4492 "AFSProcessPIOCtlQueryInfo (FileNameInformation) Returning %wZ\n",
4500 case FileInternalInformation:
4503 PFILE_INTERNAL_INFORMATION pInternalInfo = (PFILE_INTERNAL_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
4505 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4506 AFS_TRACE_LEVEL_VERBOSE,
4507 "AFSProcessPIOCtlQueryInfo (FileInternalInformation)\n"));
4509 if( *Length >= sizeof( FILE_INTERNAL_INFORMATION))
4512 pInternalInfo->IndexNumber.HighPart = 0;
4514 pInternalInfo->IndexNumber.LowPart = 0;
4516 *Length -= sizeof( FILE_INTERNAL_INFORMATION);
4521 ntStatus = STATUS_BUFFER_TOO_SMALL;
4527 case FileAllInformation:
4529 ntStatus = STATUS_INVALID_PARAMETER;
4531 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4532 AFS_TRACE_LEVEL_WARNING,
4533 "AFSProcessPIOCtlQueryInfo (FileAllInformation) Not Implemented\n"));
4538 case FileEaInformation:
4540 ntStatus = STATUS_INVALID_PARAMETER;
4542 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4543 AFS_TRACE_LEVEL_WARNING,
4544 "AFSProcessPIOCtlQueryInfo (FileEaInformation) Not Implemented\n"));
4549 case FilePositionInformation:
4551 ntStatus = STATUS_INVALID_PARAMETER;
4553 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4554 AFS_TRACE_LEVEL_WARNING,
4555 "AFSProcessPIOCtlQueryInfo (FilePositionInformation) Not Implemented\n"));
4560 case FileAlternateNameInformation:
4562 ntStatus = STATUS_INVALID_PARAMETER;
4564 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4565 AFS_TRACE_LEVEL_WARNING,
4566 "AFSProcessPIOCtlQueryInfo (FileAlternateNameInformation) Not Implemented\n"));
4571 case FileNetworkOpenInformation:
4573 ntStatus = STATUS_INVALID_PARAMETER;
4575 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4576 AFS_TRACE_LEVEL_WARNING,
4577 "AFSProcessPIOCtlQueryInfo (FileNetworkOpenInformation) Not Implemented\n"));
4582 case FileStreamInformation:
4584 ntStatus = STATUS_INVALID_PARAMETER;
4586 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4587 AFS_TRACE_LEVEL_WARNING,
4588 "AFSProcessPIOCtlQueryInfo (FileStreamInformation) Not Implemented\n"));
4593 case FileAttributeTagInformation:
4595 ntStatus = STATUS_INVALID_PARAMETER;
4597 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4598 AFS_TRACE_LEVEL_WARNING,
4599 "AFSProcessPIOCtlQueryInfo (FileAttributeTagInformation) Not Implemented\n"));
4604 case FileRemoteProtocolInformation:
4606 ntStatus = STATUS_INVALID_PARAMETER;
4608 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4609 AFS_TRACE_LEVEL_WARNING,
4610 "AFSProcessPIOCtlQueryInfo (FileRemoteProtocolInformation) Not Implemented\n"));
4615 case FileNetworkPhysicalNameInformation:
4617 ntStatus = STATUS_INVALID_PARAMETER;
4619 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4620 AFS_TRACE_LEVEL_WARNING,
4621 "AFSProcessPIOCtlQueryInfo (FileNetworkPhysicalNameInformation) Not Implemented\n"));
4628 ntStatus = STATUS_INVALID_PARAMETER;
4630 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4631 AFS_TRACE_LEVEL_WARNING,
4632 "AFSProcessPIOCtlQueryInfo Not handling request %08lX\n",
4633 ulFileInformationClass));
4640 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4641 AFS_TRACE_LEVEL_VERBOSE,
4642 "AFSProcessPIOCtlQueryInfo ntStatus %08lX\n",