2 * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC.
3 * Copyright (c) 2009, 2010, 2011 Your File System, Inc.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * - Redistributions of source code must retain the above copyright notice,
11 * this list of conditions and the following disclaimer.
12 * - Redistributions in binary form must reproduce the above copyright
14 * this list of conditions and the following disclaimer in the
16 * and/or other materials provided with the distribution.
17 * - Neither the names of Kernel Drivers, LLC and Your File System, Inc.
18 * nor the names of their contributors may be used to endorse or promote
19 * products derived from this software without specific prior written
20 * permission from Kernel Drivers, LLC and Your File System, Inc.
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
24 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
25 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
26 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 // File: AFSFileInfo.cpp
39 #include "AFSCommon.h"
42 // Function: AFSQueryFileInfo
46 // This function is the dispatch handler for the IRP_MJ_QUERY_FILE_INFORMATION request
50 // A status is returned for the function
54 AFSQueryFileInfo( IN PDEVICE_OBJECT LibDeviceObject,
58 UNREFERENCED_PARAMETER(LibDeviceObject);
59 NTSTATUS ntStatus = STATUS_SUCCESS;
60 IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
63 BOOLEAN bReleaseMain = FALSE;
65 FILE_INFORMATION_CLASS stFileInformationClass;
73 // Determine the type of request this request is
76 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
78 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
83 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
84 AFS_TRACE_LEVEL_ERROR,
85 "AFSQueryFileInfo Attempted access (%p) when pFcb == NULL\n",
88 try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST);
91 lLength = (LONG)pIrpSp->Parameters.QueryFile.Length;
92 stFileInformationClass = pIrpSp->Parameters.QueryFile.FileInformationClass;
93 pBuffer = Irp->AssociatedIrp.SystemBuffer;
95 if ( BooleanFlagOn( pFcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY))
98 RtlZeroMemory( &stAuthGroup,
101 AFSRetrieveAuthGroupFnc( (ULONGLONG)PsGetCurrentProcessId(),
102 (ULONGLONG)PsGetCurrentThreadId(),
105 ntStatus = AFSVerifyEntry( &stAuthGroup,
108 if ( NT_SUCCESS( ntStatus))
111 ClearFlag( pFcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY);
116 ntStatus = STATUS_SUCCESS;
121 // Grab the main shared right off the bat
124 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
125 AFS_TRACE_LEVEL_VERBOSE,
126 "AFSQueryFileInfo Acquiring Fcb lock %p SHARED %08lX\n",
127 &pFcb->NPFcb->Resource,
128 PsGetCurrentThread()));
130 AFSAcquireShared( &pFcb->NPFcb->Resource,
136 // Don't allow requests against IOCtl nodes
139 if( pFcb->Header.NodeTypeCode == AFS_SPECIAL_SHARE_FCB)
142 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
143 AFS_TRACE_LEVEL_VERBOSE,
144 "AFSQueryFileInfo Processing request against SpecialShare Fcb\n"));
146 ntStatus = AFSProcessShareQueryInfo( Irp,
150 try_return( ntStatus);
152 else if( pFcb->Header.NodeTypeCode == AFS_IOCTL_FCB)
154 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
155 AFS_TRACE_LEVEL_VERBOSE,
156 "AFSQueryFileInfo request against PIOCtl Fcb\n"));
158 ntStatus = AFSProcessPIOCtlQueryInfo( Irp,
163 try_return( ntStatus);
166 else if( pFcb->Header.NodeTypeCode == AFS_INVALID_FCB)
168 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
169 AFS_TRACE_LEVEL_VERBOSE,
170 "AFSQueryFileInfo request against Invalid Fcb\n"));
172 try_return( ntStatus = STATUS_ACCESS_DENIED);
176 // Process the request
179 switch( stFileInformationClass)
182 case FileAllInformation:
185 PFILE_ALL_INFORMATION pAllInfo;
188 // For the all information class we'll typecast a local
189 // pointer to the output buffer and then call the
190 // individual routines to fill in the buffer.
193 pAllInfo = (PFILE_ALL_INFORMATION)pBuffer;
195 ntStatus = AFSQueryBasicInfo( Irp,
197 &pAllInfo->BasicInformation,
200 if( !NT_SUCCESS( ntStatus))
203 try_return( ntStatus);
206 ntStatus = AFSQueryStandardInfo( Irp,
208 &pAllInfo->StandardInformation,
211 if( !NT_SUCCESS( ntStatus))
214 try_return( ntStatus);
217 ntStatus = AFSQueryInternalInfo( Irp,
219 &pAllInfo->InternalInformation,
222 if( !NT_SUCCESS( ntStatus))
225 try_return( ntStatus);
228 ntStatus = AFSQueryEaInfo( Irp,
230 &pAllInfo->EaInformation,
233 if( !NT_SUCCESS( ntStatus))
236 try_return( ntStatus);
239 ntStatus = AFSQueryAccess( Irp,
241 &pAllInfo->AccessInformation,
244 if( !NT_SUCCESS( ntStatus))
247 try_return( ntStatus);
250 ntStatus = AFSQueryPositionInfo( Irp,
252 &pAllInfo->PositionInformation,
255 if( !NT_SUCCESS( ntStatus))
258 try_return( ntStatus);
261 ntStatus = AFSQueryMode( Irp,
263 &pAllInfo->ModeInformation,
266 if( !NT_SUCCESS( ntStatus))
269 try_return( ntStatus);
272 ntStatus = AFSQueryAlignment( Irp,
274 &pAllInfo->AlignmentInformation,
277 if( !NT_SUCCESS( ntStatus))
280 try_return( ntStatus);
283 ntStatus = AFSQueryNameInfo( Irp,
285 &pAllInfo->NameInformation,
288 if( !NT_SUCCESS( ntStatus))
291 try_return( ntStatus);
297 case FileBasicInformation:
300 ntStatus = AFSQueryBasicInfo( Irp,
302 (PFILE_BASIC_INFORMATION)pBuffer,
308 case FileStandardInformation:
311 ntStatus = AFSQueryStandardInfo( Irp,
313 (PFILE_STANDARD_INFORMATION)pBuffer,
319 case FileInternalInformation:
322 ntStatus = AFSQueryInternalInfo( Irp,
324 (PFILE_INTERNAL_INFORMATION)pBuffer,
330 case FileEaInformation:
333 ntStatus = AFSQueryEaInfo( Irp,
335 (PFILE_EA_INFORMATION)pBuffer,
341 case FilePositionInformation:
344 ntStatus = AFSQueryPositionInfo( Irp,
346 (PFILE_POSITION_INFORMATION)pBuffer,
352 case FileNormalizedNameInformation:
353 case FileNameInformation:
356 ntStatus = AFSQueryNameInfo( Irp,
358 (PFILE_NAME_INFORMATION)pBuffer,
364 case FileAlternateNameInformation:
367 ntStatus = AFSQueryShortNameInfo( Irp,
369 (PFILE_NAME_INFORMATION)pBuffer,
375 case FileNetworkOpenInformation:
378 ntStatus = AFSQueryNetworkInfo( Irp,
380 (PFILE_NETWORK_OPEN_INFORMATION)pBuffer,
386 case FileStreamInformation:
389 ntStatus = AFSQueryStreamInfo( Irp,
391 (FILE_STREAM_INFORMATION *)pBuffer,
398 case FileAttributeTagInformation:
401 ntStatus = AFSQueryAttribTagInfo( Irp,
403 (FILE_ATTRIBUTE_TAG_INFORMATION *)pBuffer,
409 case FileRemoteProtocolInformation:
412 ntStatus = AFSQueryRemoteProtocolInfo( Irp,
414 (FILE_REMOTE_PROTOCOL_INFORMATION *)pBuffer,
420 case FileNetworkPhysicalNameInformation:
423 ntStatus = AFSQueryPhysicalNameInfo( Irp,
425 (FILE_NETWORK_PHYSICAL_NAME_INFORMATION *)pBuffer,
433 ntStatus = STATUS_INVALID_PARAMETER;
440 Irp->IoStatus.Information = pIrpSp->Parameters.QueryFile.Length - lLength;
445 AFSReleaseResource( &pFcb->NPFcb->Resource);
448 if( !NT_SUCCESS( ntStatus) &&
449 ntStatus != STATUS_INVALID_PARAMETER &&
450 ntStatus != STATUS_BUFFER_OVERFLOW)
454 pCcb->DirectoryCB != NULL)
457 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
458 AFS_TRACE_LEVEL_ERROR,
459 "AFSQueryFileInfo Failed to process request for %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
460 &pCcb->DirectoryCB->NameInformation.FileName,
461 pFcb->ObjectInformation->FileId.Cell,
462 pFcb->ObjectInformation->FileId.Volume,
463 pFcb->ObjectInformation->FileId.Vnode,
464 pFcb->ObjectInformation->FileId.Unique,
469 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
474 "EXCEPTION - AFSQueryFileInfo\n"));
476 AFSDumpTraceFilesFnc();
478 ntStatus = STATUS_UNSUCCESSFUL;
483 AFSReleaseResource( &pFcb->NPFcb->Resource);
487 AFSCompleteRequest( Irp,
494 // Function: AFSSetFileInfo
498 // This function is the dispatch handler for the IRP_MJ_SET_FILE_INFORMATION request
502 // A status is returned for the function
506 AFSSetFileInfo( IN PDEVICE_OBJECT LibDeviceObject,
510 UNREFERENCED_PARAMETER(LibDeviceObject);
511 NTSTATUS ntStatus = STATUS_SUCCESS;
512 IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
515 FILE_INFORMATION_CLASS FileInformationClass;
516 BOOLEAN bCanQueueRequest = FALSE;
517 PFILE_OBJECT pFileObject = NULL;
518 BOOLEAN bReleaseMain = FALSE;
519 BOOLEAN bUpdateFileInfo = FALSE;
520 AFSFileID stParentFileId;
525 pFileObject = pIrpSp->FileObject;
527 pFcb = (AFSFcb *)pFileObject->FsContext;
528 pCcb = (AFSCcb *)pFileObject->FsContext2;
533 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
534 AFS_TRACE_LEVEL_ERROR,
535 "AFSSetFileInfo Attempted access (%p) when pFcb == NULL\n",
538 try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST);
541 bCanQueueRequest = !(IoIsOperationSynchronous( Irp) | (KeGetCurrentIrql() != PASSIVE_LEVEL));
542 FileInformationClass = pIrpSp->Parameters.SetFile.FileInformationClass;
548 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
549 AFS_TRACE_LEVEL_VERBOSE,
550 "AFSSetFileInfo Acquiring Fcb lock %p EXCL %08lX\n",
551 &pFcb->NPFcb->Resource,
552 PsGetCurrentThread()));
554 AFSAcquireExcl( &pFcb->NPFcb->Resource,
560 // Don't allow requests against IOCtl nodes
563 if( pFcb->Header.NodeTypeCode == AFS_IOCTL_FCB)
566 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
567 AFS_TRACE_LEVEL_ERROR,
568 "AFSSetFileInfo Failing request against PIOCtl Fcb\n"));
570 try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST);
572 else if( pFcb->Header.NodeTypeCode == AFS_SPECIAL_SHARE_FCB)
575 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
576 AFS_TRACE_LEVEL_VERBOSE,
577 "AFSSetFileInfo Processing request against SpecialShare Fcb\n"));
579 ntStatus = AFSProcessShareSetInfo( Irp,
583 try_return( ntStatus);
586 if( BooleanFlagOn( pFcb->ObjectInformation->VolumeCB->VolumeInformation.FileSystemAttributes, FILE_READ_ONLY_VOLUME))
589 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
590 AFS_TRACE_LEVEL_ERROR,
591 "AFSSetFileInfo Request failed due to read only volume\n",
594 try_return( ntStatus = STATUS_MEDIA_WRITE_PROTECTED);
597 if( pFcb->Header.NodeTypeCode == AFS_INVALID_FCB &&
598 FileInformationClass != FileDispositionInformation)
600 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
601 AFS_TRACE_LEVEL_VERBOSE,
602 "AFSSetFileInfo request against Invalid Fcb\n"));
604 try_return( ntStatus = STATUS_ACCESS_DENIED);
608 // Ensure rename operations are synchronous
611 if( FileInformationClass == FileRenameInformation)
614 bCanQueueRequest = FALSE;
618 // Store away the parent fid
621 RtlZeroMemory( &stParentFileId,
624 if( BooleanFlagOn( pFcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
627 stParentFileId = pFcb->ObjectInformation->ParentFileId;
631 // Process the request
634 switch( FileInformationClass)
637 case FileBasicInformation:
640 bUpdateFileInfo = TRUE;
642 ntStatus = AFSSetBasicInfo( Irp,
648 case FileDispositionInformation:
651 ntStatus = AFSSetDispositionInfo( Irp,
657 case FileRenameInformation:
660 ntStatus = AFSSetRenameInfo( Irp);
665 case FilePositionInformation:
668 ntStatus = AFSSetPositionInfo( Irp,
674 case FileLinkInformation:
677 ntStatus = AFSSetFileLinkInfo( Irp);
682 case FileAllocationInformation:
685 ntStatus = AFSSetAllocationInfo( Irp,
691 case FileEndOfFileInformation:
694 ntStatus = AFSSetEndOfFileInfo( Irp,
702 ntStatus = STATUS_INVALID_PARAMETER;
712 AFSReleaseResource( &pFcb->NPFcb->Resource);
715 if( NT_SUCCESS( ntStatus) &&
719 ntStatus = AFSUpdateFileInformation( &stParentFileId,
720 pFcb->ObjectInformation,
723 if( !NT_SUCCESS( ntStatus))
726 AFSAcquireExcl( &pFcb->NPFcb->Resource,
730 // Unwind the update and fail the request
733 AFSUnwindFileInfo( pFcb,
736 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
737 AFS_TRACE_LEVEL_ERROR,
738 "AFSSetFileInfo Failed to send file info update to service request for %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
739 &pCcb->DirectoryCB->NameInformation.FileName,
740 pFcb->ObjectInformation->FileId.Cell,
741 pFcb->ObjectInformation->FileId.Volume,
742 pFcb->ObjectInformation->FileId.Vnode,
743 pFcb->ObjectInformation->FileId.Unique,
746 AFSReleaseResource( &pFcb->NPFcb->Resource);
750 if( !NT_SUCCESS( ntStatus))
754 pCcb->DirectoryCB != NULL)
757 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
758 AFS_TRACE_LEVEL_ERROR,
759 "AFSSetFileInfo Failed to process request for %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
760 &pCcb->DirectoryCB->NameInformation.FileName,
761 pFcb->ObjectInformation->FileId.Cell,
762 pFcb->ObjectInformation->FileId.Volume,
763 pFcb->ObjectInformation->FileId.Vnode,
764 pFcb->ObjectInformation->FileId.Unique,
769 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
774 "EXCEPTION - AFSSetFileInfo\n"));
776 AFSDumpTraceFilesFnc();
778 ntStatus = STATUS_UNSUCCESSFUL;
783 AFSReleaseResource( &pFcb->NPFcb->Resource);
787 AFSCompleteRequest( Irp,
794 // Function: AFSQueryBasicInfo
798 // This function is the handler for the query basic information request
802 // A status is returned for the function
806 AFSQueryBasicInfo( IN PIRP Irp,
807 IN AFSDirectoryCB *DirectoryCB,
808 IN OUT PFILE_BASIC_INFORMATION Buffer,
811 NTSTATUS ntStatus = STATUS_SUCCESS;
812 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
813 ULONG ulFileAttribs = 0;
816 IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
817 AFSFileInfoCB stFileInfo;
818 AFSDirectoryCB *pParentDirectoryCB = NULL;
819 UNICODE_STRING uniParentPath;
821 if( *Length >= sizeof( FILE_BASIC_INFORMATION))
824 RtlZeroMemory( Buffer,
827 ulFileAttribs = DirectoryCB->ObjectInformation->FileAttributes;
829 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
830 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
832 if( DirectoryCB->ObjectInformation->FileType == AFS_FILE_TYPE_SYMLINK)
835 pParentDirectoryCB = AFSGetParentEntry( pCcb->NameArray);
837 AFSRetrieveParentPath( &pCcb->FullFileName,
840 RtlZeroMemory( &stFileInfo,
841 sizeof( AFSFileInfoCB));
844 // Can't hold the Fcb while evaluating the path, leads to lock inversion
847 AFSReleaseResource( &pFcb->NPFcb->Resource);
850 // Its a reparse point regardless of whether the file attributes
851 // can be retrieved for the target.
854 if ( ulFileAttribs == FILE_ATTRIBUTE_NORMAL)
857 ulFileAttribs = FILE_ATTRIBUTE_REPARSE_POINT;
862 ulFileAttribs |= FILE_ATTRIBUTE_REPARSE_POINT;
865 if( NT_SUCCESS( AFSRetrieveFileAttributes( pParentDirectoryCB,
873 if ( stFileInfo.FileAttributes & FILE_ATTRIBUTE_DIRECTORY)
876 ulFileAttribs |= FILE_ATTRIBUTE_DIRECTORY;
880 AFSAcquireShared( &pFcb->NPFcb->Resource,
885 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
886 AFS_TRACE_LEVEL_VERBOSE_2,
887 "AFSQueryBasicInfo %wZ Type 0x%x Attrib 0x%x -> 0x%x\n",
888 &pCcb->DirectoryCB->NameInformation.FileName,
889 pFcb->ObjectInformation->FileType,
890 pFcb->ObjectInformation->FileAttributes,
893 Buffer->CreationTime = DirectoryCB->ObjectInformation->CreationTime;
894 Buffer->LastAccessTime = DirectoryCB->ObjectInformation->LastAccessTime;
895 Buffer->LastWriteTime = DirectoryCB->ObjectInformation->LastWriteTime;
896 Buffer->ChangeTime = DirectoryCB->ObjectInformation->ChangeTime;
897 Buffer->FileAttributes = ulFileAttribs;
899 if( DirectoryCB->NameInformation.FileName.Buffer[ 0] == L'.' &&
900 BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_HIDE_DOT_NAMES))
903 if ( Buffer->FileAttributes != FILE_ATTRIBUTE_NORMAL)
905 Buffer->FileAttributes |= FILE_ATTRIBUTE_HIDDEN;
909 Buffer->FileAttributes = FILE_ATTRIBUTE_HIDDEN;
913 *Length -= sizeof( FILE_BASIC_INFORMATION);
918 ntStatus = STATUS_BUFFER_TOO_SMALL;
925 AFSQueryStandardInfo( IN PIRP Irp,
926 IN AFSDirectoryCB *DirectoryCB,
927 IN OUT PFILE_STANDARD_INFORMATION Buffer,
931 NTSTATUS ntStatus = STATUS_SUCCESS;
934 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
935 AFSFileInfoCB stFileInfo;
936 AFSDirectoryCB *pParentDirectoryCB = NULL;
937 UNICODE_STRING uniParentPath;
938 ULONG ulFileAttribs = 0;
940 if( *Length >= sizeof( FILE_STANDARD_INFORMATION))
943 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
944 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
946 RtlZeroMemory( Buffer,
949 Buffer->NumberOfLinks = 1;
950 Buffer->DeletePending = BooleanFlagOn( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
952 Buffer->AllocationSize.QuadPart = (ULONGLONG)((DirectoryCB->ObjectInformation->AllocationSize.QuadPart/PAGE_SIZE) + 1) * PAGE_SIZE;
954 Buffer->EndOfFile = DirectoryCB->ObjectInformation->EndOfFile;
956 ulFileAttribs = DirectoryCB->ObjectInformation->FileAttributes;
958 if( DirectoryCB->ObjectInformation->FileType == AFS_FILE_TYPE_SYMLINK)
961 pParentDirectoryCB = AFSGetParentEntry( pCcb->NameArray);
963 AFSRetrieveParentPath( &pCcb->FullFileName,
966 RtlZeroMemory( &stFileInfo,
967 sizeof( AFSFileInfoCB));
970 // Can't hold the Fcb while evaluating the path, leads to lock inversion
973 AFSReleaseResource( &pFcb->NPFcb->Resource);
976 // Its a reparse point regardless of whether or not the
977 // file attributes can be retrieved.
980 if ( ulFileAttribs == FILE_ATTRIBUTE_NORMAL)
983 ulFileAttribs = FILE_ATTRIBUTE_REPARSE_POINT;
988 ulFileAttribs |= FILE_ATTRIBUTE_REPARSE_POINT;
991 if( NT_SUCCESS( AFSRetrieveFileAttributes( pParentDirectoryCB,
999 if ( stFileInfo.FileAttributes & FILE_ATTRIBUTE_DIRECTORY)
1002 ulFileAttribs |= FILE_ATTRIBUTE_DIRECTORY;
1006 AFSAcquireShared( &pFcb->NPFcb->Resource,
1010 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1011 AFS_TRACE_LEVEL_VERBOSE_2,
1012 "AFSQueryStandardInfo %wZ Type 0x%x Attrib 0x%x -> 0x%x\n",
1013 &pCcb->DirectoryCB->NameInformation.FileName,
1014 pFcb->ObjectInformation->FileType,
1015 pFcb->ObjectInformation->FileAttributes,
1018 Buffer->Directory = BooleanFlagOn( ulFileAttribs, FILE_ATTRIBUTE_DIRECTORY);
1020 *Length -= sizeof( FILE_STANDARD_INFORMATION);
1025 ntStatus = STATUS_BUFFER_TOO_SMALL;
1032 AFSQueryInternalInfo( IN PIRP Irp,
1034 IN OUT PFILE_INTERNAL_INFORMATION Buffer,
1035 IN OUT PLONG Length)
1038 UNREFERENCED_PARAMETER(Irp);
1039 NTSTATUS ntStatus = STATUS_SUCCESS;
1041 if( *Length >= sizeof( FILE_INTERNAL_INFORMATION))
1044 Buffer->IndexNumber.HighPart = Fcb->ObjectInformation->FileId.Vnode;
1046 Buffer->IndexNumber.LowPart = Fcb->ObjectInformation->FileId.Unique;
1048 *Length -= sizeof( FILE_INTERNAL_INFORMATION);
1053 ntStatus = STATUS_BUFFER_TOO_SMALL;
1060 AFSQueryEaInfo( IN PIRP Irp,
1061 IN AFSDirectoryCB *DirectoryCB,
1062 IN OUT PFILE_EA_INFORMATION Buffer,
1063 IN OUT PLONG Length)
1066 UNREFERENCED_PARAMETER(Irp);
1067 UNREFERENCED_PARAMETER(DirectoryCB);
1068 NTSTATUS ntStatus = STATUS_SUCCESS;
1070 RtlZeroMemory( Buffer,
1073 if( *Length >= sizeof( FILE_EA_INFORMATION))
1078 *Length -= sizeof( FILE_EA_INFORMATION);
1083 ntStatus = STATUS_BUFFER_TOO_SMALL;
1090 AFSQueryPositionInfo( IN PIRP Irp,
1092 IN OUT PFILE_POSITION_INFORMATION Buffer,
1093 IN OUT PLONG Length)
1096 UNREFERENCED_PARAMETER(Fcb);
1097 NTSTATUS ntStatus = STATUS_SUCCESS;
1098 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1100 if( *Length >= sizeof( FILE_POSITION_INFORMATION))
1103 RtlZeroMemory( Buffer,
1106 Buffer->CurrentByteOffset.QuadPart = pIrpSp->FileObject->CurrentByteOffset.QuadPart;
1108 *Length -= sizeof( FILE_POSITION_INFORMATION);
1113 ntStatus = STATUS_BUFFER_TOO_SMALL;
1120 AFSQueryAccess( IN PIRP Irp,
1122 IN OUT PFILE_ACCESS_INFORMATION Buffer,
1123 IN OUT PLONG Length)
1126 UNREFERENCED_PARAMETER(Irp);
1127 UNREFERENCED_PARAMETER(Fcb);
1128 NTSTATUS ntStatus = STATUS_SUCCESS;
1130 if( *Length >= sizeof( FILE_ACCESS_INFORMATION))
1133 RtlZeroMemory( Buffer,
1136 Buffer->AccessFlags = 0;
1138 *Length -= sizeof( FILE_ACCESS_INFORMATION);
1143 ntStatus = STATUS_BUFFER_TOO_SMALL;
1150 AFSQueryMode( IN PIRP Irp,
1152 IN OUT PFILE_MODE_INFORMATION Buffer,
1153 IN OUT PLONG Length)
1156 UNREFERENCED_PARAMETER(Irp);
1157 UNREFERENCED_PARAMETER(Fcb);
1158 NTSTATUS ntStatus = STATUS_SUCCESS;
1160 if( *Length >= sizeof( FILE_MODE_INFORMATION))
1163 RtlZeroMemory( Buffer,
1168 *Length -= sizeof( FILE_MODE_INFORMATION);
1173 ntStatus = STATUS_BUFFER_TOO_SMALL;
1180 AFSQueryAlignment( IN PIRP Irp,
1182 IN OUT PFILE_ALIGNMENT_INFORMATION Buffer,
1183 IN OUT PLONG Length)
1186 UNREFERENCED_PARAMETER(Irp);
1187 UNREFERENCED_PARAMETER(Fcb);
1188 NTSTATUS ntStatus = STATUS_SUCCESS;
1190 if( *Length >= sizeof( FILE_ALIGNMENT_INFORMATION))
1193 RtlZeroMemory( Buffer,
1196 Buffer->AlignmentRequirement = 1;
1198 *Length -= sizeof( FILE_ALIGNMENT_INFORMATION);
1203 ntStatus = STATUS_BUFFER_TOO_SMALL;
1210 AFSQueryNameInfo( IN PIRP Irp,
1211 IN AFSDirectoryCB *DirectoryCB,
1212 IN OUT PFILE_NAME_INFORMATION Buffer,
1213 IN OUT PLONG Length)
1216 UNREFERENCED_PARAMETER(DirectoryCB);
1217 NTSTATUS ntStatus = STATUS_SUCCESS;
1218 ULONG ulCopyLength = 0;
1219 ULONG cchCopied = 0;
1220 AFSFcb *pFcb = NULL;
1221 AFSCcb *pCcb = NULL;
1222 IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1223 BOOLEAN bAddLeadingSlash = FALSE;
1224 BOOLEAN bAddTrailingSlash = FALSE;
1225 USHORT usFullNameLength = 0;
1227 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
1229 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
1231 if( *Length >= FIELD_OFFSET( FILE_NAME_INFORMATION, FileName))
1234 RtlZeroMemory( Buffer,
1237 if( pCcb->FullFileName.Length == 0 ||
1238 pCcb->FullFileName.Buffer[ 0] != L'\\')
1240 bAddLeadingSlash = TRUE;
1243 if( pFcb->ObjectInformation->FileType == AFS_FILE_TYPE_DIRECTORY &&
1244 pCcb->FullFileName.Length > 0 &&
1245 pCcb->FullFileName.Buffer[ (pCcb->FullFileName.Length/sizeof( WCHAR)) - 1] != L'\\')
1247 bAddTrailingSlash = TRUE;
1250 usFullNameLength = sizeof( WCHAR) +
1251 AFSServerName.Length +
1252 pCcb->FullFileName.Length;
1254 if( bAddLeadingSlash)
1256 usFullNameLength += sizeof( WCHAR);
1259 if( bAddTrailingSlash)
1261 usFullNameLength += sizeof( WCHAR);
1264 if( *Length >= (LONG)(FIELD_OFFSET( FILE_NAME_INFORMATION, FileName) + (LONG)usFullNameLength))
1267 ulCopyLength = (LONG)usFullNameLength;
1272 ulCopyLength = *Length - FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
1274 ntStatus = STATUS_BUFFER_OVERFLOW;
1277 Buffer->FileNameLength = (ULONG)usFullNameLength;
1279 *Length -= FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
1281 if( ulCopyLength > 0)
1284 Buffer->FileName[ 0] = L'\\';
1285 ulCopyLength -= sizeof( WCHAR);
1287 *Length -= sizeof( WCHAR);
1290 if( ulCopyLength >= AFSServerName.Length)
1293 RtlCopyMemory( &Buffer->FileName[ 1],
1294 AFSServerName.Buffer,
1295 AFSServerName.Length);
1297 ulCopyLength -= AFSServerName.Length;
1298 *Length -= AFSServerName.Length;
1299 cchCopied += AFSServerName.Length/sizeof( WCHAR);
1301 if ( ulCopyLength > 0 &&
1305 Buffer->FileName[ cchCopied] = L'\\';
1307 ulCopyLength -= sizeof( WCHAR);
1308 *Length -= sizeof( WCHAR);
1312 if( ulCopyLength >= pCcb->FullFileName.Length)
1315 RtlCopyMemory( &Buffer->FileName[ cchCopied],
1316 pCcb->FullFileName.Buffer,
1317 pCcb->FullFileName.Length);
1319 ulCopyLength -= pCcb->FullFileName.Length;
1320 *Length -= pCcb->FullFileName.Length;
1321 cchCopied += pCcb->FullFileName.Length/sizeof( WCHAR);
1323 if( ulCopyLength > 0 &&
1326 Buffer->FileName[ cchCopied] = L'\\';
1328 *Length -= sizeof( WCHAR);
1334 RtlCopyMemory( &Buffer->FileName[ cchCopied],
1335 pCcb->FullFileName.Buffer,
1338 *Length -= ulCopyLength;
1346 ntStatus = STATUS_BUFFER_TOO_SMALL;
1353 AFSQueryShortNameInfo( IN PIRP Irp,
1354 IN AFSDirectoryCB *DirectoryCB,
1355 IN OUT PFILE_NAME_INFORMATION Buffer,
1356 IN OUT PLONG Length)
1359 UNREFERENCED_PARAMETER(Irp);
1360 NTSTATUS ntStatus = STATUS_BUFFER_TOO_SMALL;
1361 ULONG ulCopyLength = 0;
1363 RtlZeroMemory( Buffer,
1366 if( DirectoryCB->NameInformation.ShortNameLength == 0)
1370 // The short name IS the long name
1373 if( *Length >= (LONG)FIELD_OFFSET( FILE_NAME_INFORMATION, FileName))
1376 if( *Length >= (LONG)(FIELD_OFFSET( FILE_NAME_INFORMATION, FileName) + (LONG)DirectoryCB->NameInformation.FileName.Length))
1379 ulCopyLength = (LONG)DirectoryCB->NameInformation.FileName.Length;
1381 ntStatus = STATUS_SUCCESS;
1386 ulCopyLength = *Length - FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
1388 ntStatus = STATUS_BUFFER_OVERFLOW;
1391 Buffer->FileNameLength = DirectoryCB->NameInformation.FileName.Length;
1393 *Length -= FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
1395 if( ulCopyLength > 0)
1398 RtlCopyMemory( Buffer->FileName,
1399 DirectoryCB->NameInformation.FileName.Buffer,
1402 *Length -= ulCopyLength;
1409 if( *Length >= (LONG)FIELD_OFFSET( FILE_NAME_INFORMATION, FileName))
1412 if( *Length >= (LONG)(FIELD_OFFSET( FILE_NAME_INFORMATION, FileName) + (LONG)DirectoryCB->NameInformation.FileName.Length))
1415 ulCopyLength = (LONG)DirectoryCB->NameInformation.ShortNameLength;
1417 ntStatus = STATUS_SUCCESS;
1422 ulCopyLength = *Length - FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
1424 ntStatus = STATUS_BUFFER_OVERFLOW;
1427 Buffer->FileNameLength = DirectoryCB->NameInformation.ShortNameLength;
1429 *Length -= FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
1431 if( ulCopyLength > 0)
1434 RtlCopyMemory( Buffer->FileName,
1435 DirectoryCB->NameInformation.ShortName,
1436 Buffer->FileNameLength);
1438 *Length -= ulCopyLength;
1447 AFSQueryNetworkInfo( IN PIRP Irp,
1448 IN AFSDirectoryCB *DirectoryCB,
1449 IN OUT PFILE_NETWORK_OPEN_INFORMATION Buffer,
1450 IN OUT PLONG Length)
1453 NTSTATUS ntStatus = STATUS_SUCCESS;
1454 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1455 AFSFcb *pFcb = NULL;
1456 AFSCcb *pCcb = NULL;
1457 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1458 AFSFileInfoCB stFileInfo;
1459 AFSDirectoryCB *pParentDirectoryCB = NULL;
1460 UNICODE_STRING uniParentPath;
1461 ULONG ulFileAttribs = 0;
1463 RtlZeroMemory( Buffer,
1466 if( *Length >= sizeof( FILE_NETWORK_OPEN_INFORMATION))
1469 ulFileAttribs = DirectoryCB->ObjectInformation->FileAttributes;
1471 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
1472 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
1474 if( DirectoryCB->ObjectInformation->FileType == AFS_FILE_TYPE_SYMLINK)
1477 pParentDirectoryCB = AFSGetParentEntry( pCcb->NameArray);
1479 AFSRetrieveParentPath( &pCcb->FullFileName,
1482 RtlZeroMemory( &stFileInfo,
1483 sizeof( AFSFileInfoCB));
1486 // Can't hold the Fcb while evaluating the path, leads to lock inversion
1489 AFSReleaseResource( &pFcb->NPFcb->Resource);
1492 // Its a reparse point regardless of whether the file attributes
1493 // can be retrieved for the target.
1496 if ( ulFileAttribs == FILE_ATTRIBUTE_NORMAL)
1499 ulFileAttribs = FILE_ATTRIBUTE_REPARSE_POINT;
1504 ulFileAttribs |= FILE_ATTRIBUTE_REPARSE_POINT;
1507 if( NT_SUCCESS( AFSRetrieveFileAttributes( pParentDirectoryCB,
1515 if ( stFileInfo.FileAttributes & FILE_ATTRIBUTE_DIRECTORY)
1518 ulFileAttribs |= FILE_ATTRIBUTE_DIRECTORY;
1522 AFSAcquireShared( &pFcb->NPFcb->Resource,
1526 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1527 AFS_TRACE_LEVEL_VERBOSE_2,
1528 "AFSQueryNetworkInfo %wZ Type 0x%x Attrib 0x%x -> 0x%x\n",
1529 &pCcb->DirectoryCB->NameInformation.FileName,
1530 pFcb->ObjectInformation->FileType,
1531 pFcb->ObjectInformation->FileAttributes,
1534 Buffer->CreationTime.QuadPart = DirectoryCB->ObjectInformation->CreationTime.QuadPart;
1535 Buffer->LastAccessTime.QuadPart = DirectoryCB->ObjectInformation->LastAccessTime.QuadPart;
1536 Buffer->LastWriteTime.QuadPart = DirectoryCB->ObjectInformation->LastWriteTime.QuadPart;
1537 Buffer->ChangeTime.QuadPart = DirectoryCB->ObjectInformation->ChangeTime.QuadPart;
1539 Buffer->AllocationSize.QuadPart = DirectoryCB->ObjectInformation->AllocationSize.QuadPart;
1540 Buffer->EndOfFile.QuadPart = DirectoryCB->ObjectInformation->EndOfFile.QuadPart;
1542 Buffer->FileAttributes = ulFileAttribs;
1544 if( DirectoryCB->NameInformation.FileName.Buffer[ 0] == L'.' &&
1545 BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_HIDE_DOT_NAMES))
1548 if ( Buffer->FileAttributes != FILE_ATTRIBUTE_NORMAL)
1551 Buffer->FileAttributes |= FILE_ATTRIBUTE_HIDDEN;
1556 Buffer->FileAttributes = FILE_ATTRIBUTE_HIDDEN;
1560 *Length -= sizeof( FILE_NETWORK_OPEN_INFORMATION);
1565 ntStatus = STATUS_BUFFER_TOO_SMALL;
1572 AFSQueryStreamInfo( IN PIRP Irp,
1573 IN AFSDirectoryCB *DirectoryCB,
1574 IN OUT FILE_STREAM_INFORMATION *Buffer,
1575 IN OUT PLONG Length)
1578 UNREFERENCED_PARAMETER(Irp);
1579 NTSTATUS ntStatus = STATUS_BUFFER_TOO_SMALL;
1580 ULONG ulCopyLength = 0;
1582 if( *Length >= FIELD_OFFSET( FILE_STREAM_INFORMATION, StreamName))
1585 RtlZeroMemory( Buffer,
1588 Buffer->NextEntryOffset = 0;
1591 if( !BooleanFlagOn( DirectoryCB->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_DIRECTORY))
1594 if( *Length >= (LONG)(FIELD_OFFSET( FILE_STREAM_INFORMATION, StreamName) + 14)) // ::$DATA
1599 ntStatus = STATUS_SUCCESS;
1604 ulCopyLength = *Length - FIELD_OFFSET( FILE_STREAM_INFORMATION, StreamName);
1606 ntStatus = STATUS_BUFFER_OVERFLOW;
1609 Buffer->StreamNameLength = 14; // ::$DATA
1611 Buffer->StreamSize.QuadPart = DirectoryCB->ObjectInformation->EndOfFile.QuadPart;
1613 Buffer->StreamAllocationSize.QuadPart = DirectoryCB->ObjectInformation->AllocationSize.QuadPart;
1615 *Length -= FIELD_OFFSET( FILE_STREAM_INFORMATION, StreamName);
1617 if( ulCopyLength > 0)
1620 RtlCopyMemory( Buffer->StreamName,
1624 *Length -= ulCopyLength;
1630 Buffer->StreamNameLength = 0; // No stream for a directory
1632 // The response size is zero
1634 ntStatus = STATUS_SUCCESS;
1642 AFSQueryAttribTagInfo( IN PIRP Irp,
1643 IN AFSDirectoryCB *DirectoryCB,
1644 IN OUT FILE_ATTRIBUTE_TAG_INFORMATION *Buffer,
1645 IN OUT PLONG Length)
1648 NTSTATUS ntStatus = STATUS_BUFFER_TOO_SMALL;
1649 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1650 AFSFcb *pFcb = NULL;
1651 AFSCcb *pCcb = NULL;
1652 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1653 AFSFileInfoCB stFileInfo;
1654 AFSDirectoryCB *pParentDirectoryCB = NULL;
1655 UNICODE_STRING uniParentPath;
1656 ULONG ulFileAttribs = 0;
1658 if( *Length >= sizeof( FILE_ATTRIBUTE_TAG_INFORMATION))
1661 RtlZeroMemory( Buffer,
1664 ulFileAttribs = DirectoryCB->ObjectInformation->FileAttributes;
1666 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
1667 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
1669 if( DirectoryCB->ObjectInformation->FileType == AFS_FILE_TYPE_SYMLINK)
1672 pParentDirectoryCB = AFSGetParentEntry( pCcb->NameArray);
1674 AFSRetrieveParentPath( &pCcb->FullFileName,
1677 RtlZeroMemory( &stFileInfo,
1678 sizeof( AFSFileInfoCB));
1681 // Can't hold the Fcb while evaluating the path, leads to lock inversion
1684 AFSReleaseResource( &pFcb->NPFcb->Resource);
1687 // Its a reparse point regardless of whether the file attributes
1688 // can be retrieved for the target.
1691 if ( ulFileAttribs == FILE_ATTRIBUTE_NORMAL)
1694 ulFileAttribs = FILE_ATTRIBUTE_REPARSE_POINT;
1699 ulFileAttribs |= FILE_ATTRIBUTE_REPARSE_POINT;
1702 if( NT_SUCCESS( AFSRetrieveFileAttributes( pParentDirectoryCB,
1710 if ( stFileInfo.FileAttributes & FILE_ATTRIBUTE_DIRECTORY)
1713 ulFileAttribs |= FILE_ATTRIBUTE_DIRECTORY;
1717 AFSAcquireShared( &pFcb->NPFcb->Resource,
1721 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1722 AFS_TRACE_LEVEL_VERBOSE_2,
1723 "AFSAttribTagInfo %wZ Type 0x%x Attrib 0x%x -> 0x%x\n",
1724 &pCcb->DirectoryCB->NameInformation.FileName,
1725 pFcb->ObjectInformation->FileType,
1726 pFcb->ObjectInformation->FileAttributes,
1729 Buffer->FileAttributes = ulFileAttribs;
1731 if( DirectoryCB->NameInformation.FileName.Buffer[ 0] == L'.' &&
1732 BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_HIDE_DOT_NAMES))
1735 if ( Buffer->FileAttributes != FILE_ATTRIBUTE_NORMAL)
1738 Buffer->FileAttributes |= FILE_ATTRIBUTE_HIDDEN;
1743 Buffer->FileAttributes = FILE_ATTRIBUTE_HIDDEN;
1747 if ( DirectoryCB->ObjectInformation->FileType == AFS_FILE_TYPE_MOUNTPOINT)
1750 Buffer->ReparseTag = IO_REPARSE_TAG_SURROGATE|IO_REPARSE_TAG_OPENAFS_DFS;
1752 else if( BooleanFlagOn( DirectoryCB->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_REPARSE_POINT))
1755 Buffer->ReparseTag = IO_REPARSE_TAG_SYMLINK;
1758 *Length -= sizeof( FILE_ATTRIBUTE_TAG_INFORMATION);
1760 ntStatus = STATUS_SUCCESS;
1767 AFSQueryRemoteProtocolInfo( IN PIRP Irp,
1768 IN AFSDirectoryCB *DirectoryCB,
1769 IN OUT FILE_REMOTE_PROTOCOL_INFORMATION *Buffer,
1770 IN OUT PLONG Length)
1773 UNREFERENCED_PARAMETER(Irp);
1774 UNREFERENCED_PARAMETER(DirectoryCB);
1775 NTSTATUS ntStatus = STATUS_BUFFER_TOO_SMALL;
1777 if( *Length >= sizeof( FILE_REMOTE_PROTOCOL_INFORMATION))
1780 RtlZeroMemory( Buffer,
1783 Buffer->StructureVersion = 1;
1785 Buffer->StructureSize = sizeof(FILE_REMOTE_PROTOCOL_INFORMATION);
1787 Buffer->Protocol = WNNC_NET_OPENAFS;
1789 Buffer->ProtocolMajorVersion = 3;
1791 Buffer->ProtocolMinorVersion = 0;
1793 Buffer->ProtocolRevision = 0;
1795 *Length -= sizeof( FILE_REMOTE_PROTOCOL_INFORMATION);
1797 ntStatus = STATUS_SUCCESS;
1804 AFSQueryPhysicalNameInfo( IN PIRP Irp,
1805 IN AFSDirectoryCB *DirectoryCB,
1806 IN OUT PFILE_NETWORK_PHYSICAL_NAME_INFORMATION Buffer,
1807 IN OUT PLONG Length)
1810 UNREFERENCED_PARAMETER(DirectoryCB);
1811 NTSTATUS ntStatus = STATUS_SUCCESS;
1812 ULONG ulCopyLength = 0;
1813 ULONG cchCopied = 0;
1814 AFSFcb *pFcb = NULL;
1815 AFSCcb *pCcb = NULL;
1816 IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1817 BOOLEAN bAddLeadingSlash = FALSE;
1818 USHORT usFullNameLength = 0;
1820 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
1822 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
1824 if( *Length >= FIELD_OFFSET( FILE_NETWORK_PHYSICAL_NAME_INFORMATION, FileName))
1827 RtlZeroMemory( Buffer,
1830 if( pCcb->FullFileName.Length == 0 ||
1831 pCcb->FullFileName.Buffer[ 0] != L'\\')
1833 bAddLeadingSlash = TRUE;
1836 usFullNameLength = pCcb->FullFileName.Length;
1838 if( bAddLeadingSlash)
1840 usFullNameLength += sizeof( WCHAR);
1843 if( *Length >= (LONG)(FIELD_OFFSET( FILE_NETWORK_PHYSICAL_NAME_INFORMATION, FileName) + (LONG)usFullNameLength))
1845 ulCopyLength = (LONG)usFullNameLength;
1850 ulCopyLength = *Length - FIELD_OFFSET( FILE_NETWORK_PHYSICAL_NAME_INFORMATION, FileName);
1852 ntStatus = STATUS_BUFFER_OVERFLOW;
1855 Buffer->FileNameLength = (ULONG)usFullNameLength;
1857 *Length -= FIELD_OFFSET( FILE_NETWORK_PHYSICAL_NAME_INFORMATION, FileName);
1859 if( ulCopyLength > 0)
1862 if( bAddLeadingSlash)
1865 Buffer->FileName[ cchCopied] = L'\\';
1867 ulCopyLength -= sizeof( WCHAR);
1868 *Length -= sizeof( WCHAR);
1872 if( ulCopyLength >= pCcb->FullFileName.Length)
1875 RtlCopyMemory( &Buffer->FileName[ cchCopied],
1876 pCcb->FullFileName.Buffer,
1877 pCcb->FullFileName.Length);
1879 ulCopyLength -= pCcb->FullFileName.Length;
1880 *Length -= pCcb->FullFileName.Length;
1881 cchCopied += pCcb->FullFileName.Length/sizeof( WCHAR);
1886 RtlCopyMemory( &Buffer->FileName[ cchCopied],
1887 pCcb->FullFileName.Buffer,
1890 *Length -= ulCopyLength;
1897 ntStatus = STATUS_BUFFER_TOO_SMALL;
1904 AFSSetBasicInfo( IN PIRP Irp,
1905 IN AFSDirectoryCB *DirectoryCB)
1907 NTSTATUS ntStatus = STATUS_SUCCESS;
1908 PFILE_BASIC_INFORMATION pBuffer;
1909 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1910 ULONG ulNotifyFilter = 0;
1911 AFSCcb *pCcb = NULL;
1916 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
1918 pBuffer = (PFILE_BASIC_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
1920 pCcb->FileUnwindInfo.FileAttributes = (ULONG)-1;
1922 if( pBuffer->FileAttributes != (ULONGLONG)0)
1925 if( DirectoryCB->ObjectInformation->Fcb->Header.NodeTypeCode == AFS_FILE_FCB &&
1926 BooleanFlagOn( pBuffer->FileAttributes, FILE_ATTRIBUTE_DIRECTORY))
1929 try_return( ntStatus = STATUS_INVALID_PARAMETER);
1932 if( DirectoryCB->ObjectInformation->Fcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB)
1935 pBuffer->FileAttributes |= FILE_ATTRIBUTE_DIRECTORY;
1938 pCcb->FileUnwindInfo.FileAttributes = DirectoryCB->ObjectInformation->FileAttributes;
1940 DirectoryCB->ObjectInformation->FileAttributes = pBuffer->FileAttributes;
1942 ulNotifyFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
1944 SetFlag( DirectoryCB->ObjectInformation->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED);
1947 pCcb->FileUnwindInfo.CreationTime.QuadPart = (ULONGLONG)-1;
1949 if( pBuffer->CreationTime.QuadPart != (ULONGLONG)-1 &&
1950 pBuffer->CreationTime.QuadPart != (ULONGLONG)0)
1953 pCcb->FileUnwindInfo.CreationTime.QuadPart = DirectoryCB->ObjectInformation->CreationTime.QuadPart;
1955 DirectoryCB->ObjectInformation->CreationTime.QuadPart = pBuffer->CreationTime.QuadPart;
1957 ulNotifyFilter |= FILE_NOTIFY_CHANGE_CREATION;
1959 SetFlag( DirectoryCB->ObjectInformation->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_CREATE_TIME);
1962 pCcb->FileUnwindInfo.LastAccessTime.QuadPart = (ULONGLONG)-1;
1964 if( pBuffer->LastAccessTime.QuadPart != (ULONGLONG)-1 &&
1965 pBuffer->LastAccessTime.QuadPart != (ULONGLONG)0)
1968 pCcb->FileUnwindInfo.LastAccessTime.QuadPart = DirectoryCB->ObjectInformation->LastAccessTime.QuadPart;
1970 DirectoryCB->ObjectInformation->LastAccessTime.QuadPart = pBuffer->LastAccessTime.QuadPart;
1972 ulNotifyFilter |= FILE_NOTIFY_CHANGE_LAST_ACCESS;
1974 SetFlag( DirectoryCB->ObjectInformation->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_ACCESS_TIME);
1977 pCcb->FileUnwindInfo.LastWriteTime.QuadPart = (ULONGLONG)-1;
1979 if( pBuffer->LastWriteTime.QuadPart != (ULONGLONG)-1 &&
1980 pBuffer->LastWriteTime.QuadPart != (ULONGLONG)0)
1983 pCcb->FileUnwindInfo.LastWriteTime.QuadPart = DirectoryCB->ObjectInformation->LastWriteTime.QuadPart;
1985 DirectoryCB->ObjectInformation->LastWriteTime.QuadPart = pBuffer->LastWriteTime.QuadPart;
1987 ulNotifyFilter |= FILE_NOTIFY_CHANGE_LAST_WRITE;
1989 SetFlag( DirectoryCB->ObjectInformation->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_LAST_WRITE_TIME);
1992 pCcb->FileUnwindInfo.ChangeTime.QuadPart = (ULONGLONG)-1;
1994 if( pBuffer->ChangeTime.QuadPart != (ULONGLONG)-1 &&
1995 pBuffer->ChangeTime.QuadPart != (ULONGLONG)0)
1998 pCcb->FileUnwindInfo.ChangeTime.QuadPart = DirectoryCB->ObjectInformation->ChangeTime.QuadPart;
2000 DirectoryCB->ObjectInformation->ChangeTime.QuadPart = pBuffer->ChangeTime.QuadPart;
2002 ulNotifyFilter |= FILE_NOTIFY_CHANGE_LAST_ACCESS;
2004 SetFlag( DirectoryCB->ObjectInformation->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_CHANGE_TIME);
2007 if( ulNotifyFilter > 0)
2010 if( BooleanFlagOn( DirectoryCB->ObjectInformation->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
2013 AFSObjectInfoCB * pParentObjectInfo = AFSFindObjectInfo( DirectoryCB->ObjectInformation->VolumeCB,
2014 &DirectoryCB->ObjectInformation->ParentFileId,
2017 if ( pParentObjectInfo != NULL)
2019 AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
2021 (ULONG)ulNotifyFilter,
2022 (ULONG)FILE_ACTION_MODIFIED);
2024 AFSReleaseObjectInfo( &pParentObjectInfo);
2038 AFSSetDispositionInfo( IN PIRP Irp,
2039 IN AFSDirectoryCB *DirectoryCB)
2041 NTSTATUS ntStatus = STATUS_SUCCESS;
2042 PFILE_DISPOSITION_INFORMATION pBuffer;
2043 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2044 AFSFcb *pFcb = NULL;
2045 AFSCcb *pCcb = NULL;
2050 pBuffer = (PFILE_DISPOSITION_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
2052 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
2054 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
2057 // Can't delete the root
2060 if( pFcb->Header.NodeTypeCode == AFS_ROOT_FCB)
2063 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2064 AFS_TRACE_LEVEL_ERROR,
2065 "AFSSetDispositionInfo Attempt to delete root entry\n"));
2067 try_return( ntStatus = STATUS_CANNOT_DELETE);
2071 // If the file is read only then do not allow the delete
2074 if( BooleanFlagOn( DirectoryCB->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_READONLY))
2077 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2078 AFS_TRACE_LEVEL_ERROR,
2079 "AFSSetDispositionInfo Attempt to delete read only entry %wZ\n",
2080 &DirectoryCB->NameInformation.FileName));
2082 try_return( ntStatus = STATUS_CANNOT_DELETE);
2085 if( pBuffer->DeleteFile)
2089 // Check if the caller can delete the file
2092 ntStatus = AFSNotifyDelete( DirectoryCB,
2096 if( !NT_SUCCESS( ntStatus))
2099 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2100 AFS_TRACE_LEVEL_ERROR,
2101 "AFSSetDispositionInfo Cannot delete entry %wZ Status %08lX\n",
2102 &DirectoryCB->NameInformation.FileName,
2105 try_return( ntStatus);
2108 if( pFcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB)
2112 // Reduce the Link count in the object information block
2113 // to correspond with the deletion of the directory entry.
2116 pFcb->ObjectInformation->Links--;
2119 // Check if this is a directory that there are not currently other opens
2122 if( pFcb->ObjectInformation->Specific.Directory.ChildOpenHandleCount > 0)
2125 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2126 AFS_TRACE_LEVEL_ERROR,
2127 "AFSSetDispositionInfo Attempt to delete directory %wZ with open %u handles\n",
2128 &DirectoryCB->NameInformation.FileName,
2129 pFcb->ObjectInformation->Specific.Directory.ChildOpenHandleCount));
2131 try_return( ntStatus = STATUS_DIRECTORY_NOT_EMPTY);
2135 // Make sure the directory is enumerated before checking to see if it is empty.
2138 if( !BooleanFlagOn( pFcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
2141 AFSAcquireExcl( pFcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
2144 if( !BooleanFlagOn( pFcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
2147 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2148 AFS_TRACE_LEVEL_VERBOSE,
2149 "AFSSetDispositionInfo Enumerating parent FID %08lX-%08lX-%08lX-%08lX\n",
2150 pFcb->ObjectInformation->FileId.Cell,
2151 pFcb->ObjectInformation->FileId.Volume,
2152 pFcb->ObjectInformation->FileId.Vnode,
2153 pFcb->ObjectInformation->FileId.Unique));
2155 ntStatus = AFSEnumerateDirectory( &pCcb->AuthGroup,
2156 pFcb->ObjectInformation,
2159 if( !NT_SUCCESS( ntStatus))
2162 AFSReleaseResource( pFcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
2164 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2165 AFS_TRACE_LEVEL_ERROR,
2166 "AFSSetDispositionInfo Failed to enumerate parent FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
2167 pFcb->ObjectInformation->FileId.Cell,
2168 pFcb->ObjectInformation->FileId.Volume,
2169 pFcb->ObjectInformation->FileId.Vnode,
2170 pFcb->ObjectInformation->FileId.Unique,
2173 try_return( ntStatus);
2177 AFSReleaseResource( pFcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
2180 if( !AFSIsDirectoryEmptyForDelete( pFcb))
2183 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2184 AFS_TRACE_LEVEL_ERROR,
2185 "AFSSetDispositionInfo Attempt to delete non-empty directory %wZ\n",
2186 &DirectoryCB->NameInformation.FileName));
2188 try_return( ntStatus = STATUS_DIRECTORY_NOT_EMPTY);
2191 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2192 AFS_TRACE_LEVEL_VERBOSE,
2193 "AFSSetDispositionInfo Setting PENDING_DELETE on DirEntry %p Name %wZ\n",
2195 &DirectoryCB->NameInformation.FileName));
2197 SetFlag( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
2199 else if( pFcb->Header.NodeTypeCode == AFS_FILE_FCB)
2203 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
2204 AFS_TRACE_LEVEL_VERBOSE,
2205 "AFSSetDispositionInfo Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
2206 &pFcb->NPFcb->SectionObjectResource,
2207 PsGetCurrentThread()));
2209 AFSAcquireExcl( &pFcb->NPFcb->SectionObjectResource,
2216 // Attempt to flush any outstanding data
2219 bMmFlushed = MmFlushImageSection( &pFcb->NPFcb->SectionObjectPointers,
2226 // Set PENDING_DELETE before CcPurgeCacheSection to avoid a
2227 // deadlock with Trend Micro's Enterprise anti-virus product
2228 // which attempts to open the file which is being deleted.
2231 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2232 AFS_TRACE_LEVEL_VERBOSE,
2233 "AFSSetDispositionInfo Setting PENDING_DELETE on DirEntry %p Name %wZ\n",
2235 &DirectoryCB->NameInformation.FileName));
2237 SetFlag( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
2240 // Purge the cache as well
2243 if( pFcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
2246 if ( !CcPurgeCacheSection( &pFcb->NPFcb->SectionObjectPointers,
2252 SetFlag( pFcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
2257 __except( EXCEPTION_EXECUTE_HANDLER)
2262 ntStatus = GetExceptionCode();
2266 "EXCEPTION - AFSSetDispositionInfo MmFlushImageSection failed FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
2267 pFcb->ObjectInformation->FileId.Cell,
2268 pFcb->ObjectInformation->FileId.Volume,
2269 pFcb->ObjectInformation->FileId.Vnode,
2270 pFcb->ObjectInformation->FileId.Unique,
2274 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
2275 AFS_TRACE_LEVEL_VERBOSE,
2276 "AFSSetDispositionInfo Releasing Fcb SectionObject lock %p EXCL %08lX\n",
2277 &pFcb->NPFcb->SectionObjectResource,
2278 PsGetCurrentThread()));
2280 AFSReleaseResource( &pFcb->NPFcb->SectionObjectResource);
2285 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2286 AFS_TRACE_LEVEL_ERROR,
2287 "AFSSetDispositionInfo Failed to flush image section for delete Entry %wZ\n",
2288 &DirectoryCB->NameInformation.FileName));
2290 try_return( ntStatus = STATUS_CANNOT_DELETE);
2293 else if( pFcb->Header.NodeTypeCode == AFS_SYMBOLIC_LINK_FCB ||
2294 pFcb->Header.NodeTypeCode == AFS_MOUNT_POINT_FCB ||
2295 pFcb->Header.NodeTypeCode == AFS_DFS_LINK_FCB ||
2296 pFcb->Header.NodeTypeCode == AFS_INVALID_FCB)
2299 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2300 AFS_TRACE_LEVEL_VERBOSE,
2301 "AFSSetDispositionInfo Setting PENDING_DELETE on DirEntry %p Name %wZ\n",
2303 &DirectoryCB->NameInformation.FileName));
2305 SetFlag( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
2311 ClearFlag( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
2315 // OK, should be good to go, set the flag in the file object
2318 pIrpSp->FileObject->DeletePending = pBuffer->DeleteFile;
2329 AFSSetFileLinkInfo( IN PIRP Irp)
2332 NTSTATUS ntStatus = STATUS_SUCCESS;
2333 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
2334 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2335 PFILE_LINK_INFORMATION pFileLinkInfo = NULL;
2336 PFILE_OBJECT pSrcFileObj = NULL;
2337 PFILE_OBJECT pTargetFileObj = pIrpSp->Parameters.SetFile.FileObject;
2338 AFSFcb *pSrcFcb = NULL, *pTargetDcb = NULL;
2339 AFSCcb *pSrcCcb = NULL, *pTargetDirCcb = NULL;
2340 AFSObjectInfoCB *pSrcObject = NULL;
2341 AFSObjectInfoCB *pSrcParentObject = NULL, *pTargetParentObject = NULL;
2342 UNICODE_STRING uniSourceName, uniTargetName;
2343 UNICODE_STRING uniFullTargetName, uniTargetParentName;
2344 BOOLEAN bCommonParent = FALSE;
2345 AFSDirectoryCB *pTargetDirEntry = NULL;
2346 AFSDirectoryCB *pNewTargetDirEntry = NULL;
2348 BOOLEAN bTargetEntryExists = FALSE;
2350 BOOLEAN bReleaseTargetDirLock = FALSE;
2351 ULONG ulNotificationAction = 0, ulNotifyFilter = 0;
2356 pSrcFileObj = pIrpSp->FileObject;
2358 pSrcFcb = (AFSFcb *)pSrcFileObj->FsContext;
2359 pSrcCcb = (AFSCcb *)pSrcFileObj->FsContext2;
2361 pSrcObject = pSrcFcb->ObjectInformation;
2363 if ( BooleanFlagOn( pSrcObject->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
2366 pSrcParentObject = AFSFindObjectInfo( pSrcObject->VolumeCB,
2367 &pSrcObject->ParentFileId,
2371 if( pSrcParentObject == NULL)
2374 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2375 AFS_TRACE_LEVEL_ERROR,
2376 "AFSSetFileLinkInfo Unable to resolve SrcParentObject (INVALID_PARAMETER)\n"));
2380 try_return( ntStatus = STATUS_INVALID_PARAMETER);
2383 pFileLinkInfo = (PFILE_LINK_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
2386 // Perform some basic checks to ensure FS integrity
2389 if( pSrcFcb->Header.NodeTypeCode != AFS_FILE_FCB)
2392 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2393 AFS_TRACE_LEVEL_ERROR,
2394 "AFSSetFileLinkInfo Attempt to non-file (INVALID_PARAMETER)\n"));
2396 try_return( ntStatus = STATUS_INVALID_PARAMETER);
2399 if( pTargetFileObj == NULL)
2402 if ( pFileLinkInfo->RootDirectory)
2406 // The target directory is provided by HANDLE
2407 // RootDirectory is only set when the target directory is not the same
2408 // as the source directory.
2410 // AFS only supports hard links within a single directory.
2412 // The IOManager should translate any Handle to a FileObject for us.
2413 // However, the failure to receive a FileObject is treated as a fatal
2417 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2418 AFS_TRACE_LEVEL_ERROR,
2419 "AFSSetFileLinkInfo Attempt to link %wZ to alternate directory by handle INVALID_PARAMETER\n",
2420 &pSrcCcb->DirectoryCB->NameInformation.FileName));
2422 try_return( ntStatus = STATUS_INVALID_PARAMETER);
2427 uniFullTargetName.Length = (USHORT)pFileLinkInfo->FileNameLength;
2429 uniFullTargetName.Buffer = (PWSTR)&pFileLinkInfo->FileName;
2431 AFSRetrieveFinalComponent( &uniFullTargetName,
2434 AFSRetrieveParentPath( &uniFullTargetName,
2435 &uniTargetParentName);
2437 if ( uniTargetParentName.Length == 0)
2441 // This is a simple rename. Here the target directory is the same as the source parent directory
2442 // and the name is retrieved from the system buffer information
2445 pTargetParentObject = pSrcParentObject;
2450 // uniTargetParentName contains the directory the renamed object
2451 // will be moved to. Must obtain the TargetParentObject.
2454 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2455 AFS_TRACE_LEVEL_ERROR,
2456 "AFSSetFileLinkInfo Attempt to link %wZ to alternate directory %wZ (NOT_SAME_DEVICE)\n",
2457 &pSrcCcb->DirectoryCB->NameInformation.FileName,
2458 &uniFullTargetName));
2460 try_return( ntStatus = STATUS_NOT_SAME_DEVICE);
2464 pTargetDcb = pTargetParentObject->Fcb;
2470 // So here we have the target directory taken from the targetfile object
2473 pTargetDcb = (AFSFcb *)pTargetFileObj->FsContext;
2475 pTargetDirCcb = (AFSCcb *)pTargetFileObj->FsContext2;
2477 pTargetParentObject = (AFSObjectInfoCB *)pTargetDcb->ObjectInformation;
2480 // Grab the target name which we setup in the IRP_MJ_CREATE handler. By how we set this up
2481 // it is only the target component of the rename operation
2484 uniTargetName = *((PUNICODE_STRING)&pTargetFileObj->FileName);
2488 // The quick check to see if they are self linking.
2489 // Do the names match? Only do this where the parent directories are
2493 if( pTargetParentObject == pSrcParentObject)
2496 if( FsRtlAreNamesEqual( &uniTargetName,
2501 try_return( ntStatus = STATUS_SUCCESS);
2504 bCommonParent = TRUE;
2510 // We do not allow cross-volume hard links
2513 if( pTargetParentObject->VolumeCB != pSrcObject->VolumeCB)
2516 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2517 AFS_TRACE_LEVEL_ERROR,
2518 "AFSSetFileLinkInfo Attempt to link to different volume %wZ\n",
2519 &pSrcCcb->DirectoryCB->NameInformation.FileName));
2521 try_return( ntStatus = STATUS_NOT_SAME_DEVICE);
2525 ulTargetCRC = AFSGenerateCRC( &uniTargetName,
2528 AFSAcquireExcl( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock,
2531 bReleaseTargetDirLock = TRUE;
2533 AFSLocateCaseSensitiveDirEntry( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
2537 if( pTargetDirEntry == NULL)
2541 // Missed so perform a case insensitive lookup
2544 ulTargetCRC = AFSGenerateCRC( &uniTargetName,
2547 AFSLocateCaseInsensitiveDirEntry( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
2552 if ( !BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
2553 pTargetDirEntry == NULL && RtlIsNameLegalDOS8Dot3( &uniTargetName,
2558 // Try the short name
2560 AFSLocateShortNameDirEntry( pTargetParentObject->Specific.Directory.ShortNameTree,
2566 // Increment our ref count on the dir entry
2569 if( pTargetDirEntry != NULL)
2572 ASSERT( BooleanFlagOn( pTargetDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_PARENT_FID) &&
2573 AFSIsEqualFID( &pTargetParentObject->FileId, &pTargetDirEntry->ObjectInformation->ParentFileId));
2575 lCount = InterlockedIncrement( &pTargetDirEntry->DirOpenReferenceCount);
2577 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2578 AFS_TRACE_LEVEL_VERBOSE,
2579 "AFSSetFileLinkInfo Increment count on %wZ DE %p Ccb %p Cnt %d\n",
2580 &pTargetDirEntry->NameInformation.FileName,
2585 ASSERT( lCount >= 0);
2587 if( !pFileLinkInfo->ReplaceIfExists)
2590 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2591 AFS_TRACE_LEVEL_ERROR,
2592 "AFSSetFileLinkInfo Attempt to link with target collision %wZ Target %wZ\n",
2593 &pSrcCcb->DirectoryCB->NameInformation.FileName,
2594 &pTargetDirEntry->NameInformation.FileName));
2596 try_return( ntStatus = STATUS_OBJECT_NAME_COLLISION);
2599 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING | AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2600 AFS_TRACE_LEVEL_ERROR,
2601 "AFSSetFileLinkInfo Target %wZ exists DE %p Count %d, performing delete of target\n",
2602 &pTargetDirEntry->NameInformation.FileName,
2607 // Pull the directory entry from the parent
2610 AFSRemoveDirNodeFromParent( pTargetParentObject,
2614 bTargetEntryExists = TRUE;
2618 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2619 AFS_TRACE_LEVEL_VERBOSE,
2620 "AFSSetFileLinkInfo Target does NOT exist, normal linking\n"));
2624 // OK, this is a simple rename. Issue the rename
2625 // request to the service.
2628 ntStatus = AFSNotifyHardLink( pSrcObject,
2629 &pSrcCcb->AuthGroup,
2631 pTargetDcb->ObjectInformation,
2632 pSrcCcb->DirectoryCB,
2634 pFileLinkInfo->ReplaceIfExists,
2635 &pNewTargetDirEntry);
2637 if( ntStatus != STATUS_REPARSE &&
2638 !NT_SUCCESS( ntStatus))
2641 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2642 AFS_TRACE_LEVEL_ERROR,
2643 "AFSSetFileLinkInfo Failed link of %wZ to target %wZ Status %08lX\n",
2644 &pSrcCcb->DirectoryCB->NameInformation.FileName,
2648 try_return( ntStatus);
2651 if ( ntStatus != STATUS_REPARSE)
2654 AFSInsertDirectoryNode( pTargetDcb->ObjectInformation,
2660 // Send notification for the target link file
2663 if( bTargetEntryExists || pNewTargetDirEntry)
2666 ulNotificationAction = FILE_ACTION_MODIFIED;
2671 ulNotificationAction = FILE_ACTION_ADDED;
2674 AFSFsRtlNotifyFullReportChange( pTargetParentObject,
2676 (ULONG)ulNotifyFilter,
2677 (ULONG)ulNotificationAction);
2681 if( !NT_SUCCESS( ntStatus))
2684 if( bTargetEntryExists)
2687 AFSInsertDirectoryNode( pTargetParentObject,
2693 if( pTargetDirEntry != NULL)
2697 // Release DirOpenReferenceCount obtained above
2700 lCount = InterlockedDecrement( &pTargetDirEntry->DirOpenReferenceCount);
2702 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2703 AFS_TRACE_LEVEL_VERBOSE,
2704 "AFSSetFileLinkInfo Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
2705 &pTargetDirEntry->NameInformation.FileName,
2710 ASSERT( lCount >= 0);
2713 if( pNewTargetDirEntry != NULL)
2717 // Release DirOpenReferenceCount obtained from AFSNotifyHardLink
2720 lCount = InterlockedDecrement( &pNewTargetDirEntry->DirOpenReferenceCount);
2722 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2723 AFS_TRACE_LEVEL_VERBOSE,
2724 "AFSSetFileLinkInfo Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
2725 &pNewTargetDirEntry->NameInformation.FileName,
2730 ASSERT( lCount >= 0);
2733 if( bReleaseTargetDirLock)
2736 AFSReleaseResource( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
2739 if ( pSrcParentObject != NULL)
2742 AFSReleaseObjectInfo( &pSrcParentObject);
2746 // No need to release pTargetParentObject as it is either a copy of pSrcParentObject
2747 // or (AFSFcb *)pTargetFileObj->FsContext->ObjectInformation
2750 pTargetParentObject = NULL;
2757 AFSSetRenameInfo( IN PIRP Irp)
2760 NTSTATUS ntStatus = STATUS_SUCCESS;
2761 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
2762 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2763 AFSFcb *pSrcFcb = NULL, *pTargetDcb = NULL, *pTargetFcb = NULL;
2764 AFSCcb *pSrcCcb = NULL, *pTargetDirCcb = NULL;
2765 PFILE_OBJECT pSrcFileObj = pIrpSp->FileObject;
2766 PFILE_OBJECT pTargetFileObj = pIrpSp->Parameters.SetFile.FileObject;
2767 PFILE_OBJECT pTargetParentFileObj = NULL;
2768 PFILE_RENAME_INFORMATION pRenameInfo = NULL;
2769 UNICODE_STRING uniTargetName, uniSourceName, uniTargetParentName;
2770 BOOLEAN bReplaceIfExists = FALSE;
2771 UNICODE_STRING uniShortName;
2772 AFSDirectoryCB *pTargetDirEntry = NULL;
2773 ULONG ulTargetCRC = 0;
2774 BOOLEAN bTargetEntryExists = FALSE;
2775 AFSObjectInfoCB *pSrcObject = NULL;
2776 AFSObjectInfoCB *pSrcParentObject = NULL, *pTargetParentObject = NULL;
2778 ULONG ulNotificationAction = 0, ulNotifyFilter = 0;
2779 UNICODE_STRING uniFullTargetName;
2780 BOOLEAN bCommonParent = FALSE;
2781 BOOLEAN bReleaseTargetDirLock = FALSE;
2782 BOOLEAN bReleaseSourceDirLock = FALSE;
2783 BOOLEAN bDereferenceTargetParentObject = FALSE;
2784 PERESOURCE pSourceDirLock = NULL;
2790 bReplaceIfExists = pIrpSp->Parameters.SetFile.ReplaceIfExists;
2792 pRenameInfo = (PFILE_RENAME_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
2794 pSrcFcb = (AFSFcb *)pSrcFileObj->FsContext;
2795 pSrcCcb = (AFSCcb *)pSrcFileObj->FsContext2;
2797 pSrcObject = pSrcFcb->ObjectInformation;
2799 if ( BooleanFlagOn( pSrcObject->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
2802 pSrcParentObject = AFSFindObjectInfo( pSrcObject->VolumeCB,
2803 &pSrcObject->ParentFileId,
2807 if( pSrcParentObject == NULL)
2810 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2811 AFS_TRACE_LEVEL_ERROR,
2812 "AFSSetRenameInfo Unable to resolve SrcParentObject (INVALID_PARAMETER)\n"));
2816 try_return( ntStatus = STATUS_INVALID_PARAMETER);
2820 // Perform some basic checks to ensure FS integrity
2823 if( pSrcFcb->Header.NodeTypeCode == AFS_ROOT_FCB)
2827 // Can't rename the root directory
2830 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2831 AFS_TRACE_LEVEL_ERROR,
2832 "AFSSetRenameInfo Attempt to rename root entry\n"));
2834 try_return( ntStatus = STATUS_INVALID_PARAMETER);
2837 if( pSrcFcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB)
2841 // If there are any open children then fail the rename
2844 if( pSrcObject->Specific.Directory.ChildOpenHandleCount > 0)
2847 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2848 AFS_TRACE_LEVEL_ERROR,
2849 "AFSSetRenameInfo Attempt to rename directory with open children %wZ\n",
2850 &pSrcCcb->DirectoryCB->NameInformation.FileName));
2852 try_return( ntStatus = STATUS_ACCESS_DENIED);
2858 // Extract off the final component name from the Fcb
2861 uniSourceName.Length = (USHORT)pSrcCcb->DirectoryCB->NameInformation.FileName.Length;
2862 uniSourceName.MaximumLength = uniSourceName.Length;
2864 uniSourceName.Buffer = pSrcCcb->DirectoryCB->NameInformation.FileName.Buffer;
2867 // Resolve the target fileobject
2870 if( pTargetFileObj == NULL)
2873 if ( pRenameInfo->RootDirectory)
2876 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2877 AFS_TRACE_LEVEL_ERROR,
2878 "AFSSetRenameInfo Handle provided but no FileObject ntStatus INVALID_PARAMETER\n"));
2880 try_return( ntStatus = STATUS_INVALID_PARAMETER);
2885 uniFullTargetName.Length = (USHORT)pRenameInfo->FileNameLength;
2887 uniFullTargetName.Buffer = (PWSTR)&pRenameInfo->FileName;
2889 AFSRetrieveFinalComponent( &uniFullTargetName,
2892 AFSRetrieveParentPath( &uniFullTargetName,
2893 &uniTargetParentName);
2895 if ( uniTargetParentName.Length == 0)
2899 // This is a simple rename. Here the target directory is the same as the source parent directory
2900 // and the name is retrieved from the system buffer information
2903 pTargetParentObject = pSrcParentObject;
2908 // uniTargetParentName contains the directory the renamed object
2909 // will be moved to. Must obtain the TargetParentObject.
2912 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2913 AFS_TRACE_LEVEL_ERROR,
2914 "AFSSetRenameInfo Attempt to move %wZ to %wZ -- not yet supported (NOT_SAME_DEVICE)\n",
2915 &pSrcCcb->DirectoryCB->NameInformation.FileName,
2916 &uniFullTargetName));
2918 try_return( ntStatus = STATUS_NOT_SAME_DEVICE);
2922 pTargetDcb = pTargetParentObject->Fcb;
2928 // So here we have the target directory taken from the targetfile object
2931 pTargetDcb = (AFSFcb *)pTargetFileObj->FsContext;
2933 pTargetDirCcb = (AFSCcb *)pTargetFileObj->FsContext2;
2935 pTargetParentObject = (AFSObjectInfoCB *)pTargetDcb->ObjectInformation;
2938 // Grab the target name which we setup in the IRP_MJ_CREATE handler. By how we set this up
2939 // it is only the target component of the rename operation
2942 uniTargetName = *((PUNICODE_STRING)&pTargetFileObj->FileName);
2946 // The quick check to see if they are not really performing a rename
2947 // Do the names match? Only do this where the parent directories are
2951 if( pTargetParentObject == pSrcParentObject)
2954 if( FsRtlAreNamesEqual( &uniTargetName,
2959 try_return( ntStatus = STATUS_SUCCESS);
2962 bCommonParent = TRUE;
2967 bCommonParent = FALSE;
2971 // We do not allow cross-volume renames to occur
2974 if( pTargetParentObject->VolumeCB != pSrcObject->VolumeCB)
2977 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2978 AFS_TRACE_LEVEL_ERROR,
2979 "AFSSetRenameInfo Attempt to rename directory to different volume %wZ\n",
2980 &pSrcCcb->DirectoryCB->NameInformation.FileName));
2982 try_return( ntStatus = STATUS_NOT_SAME_DEVICE);
2985 ulTargetCRC = AFSGenerateCRC( &uniTargetName,
2988 AFSAcquireExcl( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock,
2991 bReleaseTargetDirLock = TRUE;
2993 if( pTargetParentObject != pSrcParentObject)
2995 AFSAcquireExcl( pSrcParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock,
2998 bReleaseSourceDirLock = TRUE;
3000 pSourceDirLock = pSrcParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock;
3003 AFSLocateCaseSensitiveDirEntry( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
3007 if( pTargetDirEntry == NULL)
3011 // Missed so perform a case insensitive lookup
3014 ulTargetCRC = AFSGenerateCRC( &uniTargetName,
3017 AFSLocateCaseInsensitiveDirEntry( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
3022 if ( !BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
3023 pTargetDirEntry == NULL && RtlIsNameLegalDOS8Dot3( &uniTargetName,
3028 // Try the short name
3030 AFSLocateShortNameDirEntry( pTargetParentObject->Specific.Directory.ShortNameTree,
3036 // Increment our ref count on the dir entry
3039 if( pTargetDirEntry != NULL)
3042 ASSERT( BooleanFlagOn( pTargetDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_PARENT_FID) &&
3043 AFSIsEqualFID( &pTargetParentObject->FileId, &pTargetDirEntry->ObjectInformation->ParentFileId));
3045 lCount = InterlockedIncrement( &pTargetDirEntry->DirOpenReferenceCount);
3047 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3048 AFS_TRACE_LEVEL_VERBOSE,
3049 "AFSSetRenameInfo Increment count on %wZ DE %p Ccb %p Cnt %d\n",
3050 &pTargetDirEntry->NameInformation.FileName,
3055 ASSERT( lCount >= 0);
3057 if( !bReplaceIfExists)
3060 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3061 AFS_TRACE_LEVEL_ERROR,
3062 "AFSSetRenameInfo Attempt to rename directory with target collision %wZ Target %wZ\n",
3063 &pSrcCcb->DirectoryCB->NameInformation.FileName,
3064 &pTargetDirEntry->NameInformation.FileName));
3066 try_return( ntStatus = STATUS_OBJECT_NAME_COLLISION);
3069 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING | AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3070 AFS_TRACE_LEVEL_ERROR,
3071 "AFSSetRenameInfo Target %wZ exists DE %p Count %d, performing delete of target\n",
3072 &pTargetDirEntry->NameInformation.FileName,
3077 // Pull the directory entry from the parent
3080 AFSRemoveDirNodeFromParent( pTargetParentObject,
3084 bTargetEntryExists = TRUE;
3088 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3089 AFS_TRACE_LEVEL_VERBOSE,
3090 "AFSSetRenameInfo Target does NOT exist, normal rename\n"));
3094 // We need to remove the DirEntry from the parent node, update the index
3095 // and reinsert it into the parent tree. Note that for entries with the
3096 // same parent we do not pull the node from the enumeration list
3099 AFSRemoveDirNodeFromParent( pSrcParentObject,
3100 pSrcCcb->DirectoryCB,
3104 // OK, this is a simple rename. Issue the rename
3105 // request to the service.
3108 ntStatus = AFSNotifyRename( pSrcObject,
3109 &pSrcCcb->AuthGroup,
3111 pTargetDcb->ObjectInformation,
3112 pSrcCcb->DirectoryCB,
3116 if( !NT_SUCCESS( ntStatus))
3120 // Attempt to re-insert the directory entry
3123 AFSInsertDirectoryNode( pSrcParentObject,
3124 pSrcCcb->DirectoryCB,
3127 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3128 AFS_TRACE_LEVEL_ERROR,
3129 "AFSSetRenameInfo Failed rename of %wZ to target %wZ Status %08lX\n",
3130 &pSrcCcb->DirectoryCB->NameInformation.FileName,
3134 try_return( ntStatus);
3138 // Set the notification up for the source file
3141 if( pSrcParentObject == pTargetParentObject &&
3142 !bTargetEntryExists)
3145 ulNotificationAction = FILE_ACTION_RENAMED_OLD_NAME;
3150 ulNotificationAction = FILE_ACTION_REMOVED;
3153 if( pSrcObject->FileType == AFS_FILE_TYPE_DIRECTORY)
3156 ulNotifyFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
3161 ulNotifyFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
3164 AFSFsRtlNotifyFullReportChange( pSrcParentObject,
3166 (ULONG)ulNotifyFilter,
3167 (ULONG)ulNotificationAction);
3170 // Update the name in the dir entry.
3173 ntStatus = AFSUpdateDirEntryName( pSrcCcb->DirectoryCB,
3176 if( !NT_SUCCESS( ntStatus))
3180 // Attempt to re-insert the directory entry
3183 AFSInsertDirectoryNode( pSrcParentObject,
3184 pSrcCcb->DirectoryCB,
3187 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3188 AFS_TRACE_LEVEL_ERROR,
3189 "AFSSetRenameInfo Failed update of dir entry %wZ to target %wZ Status %08lX\n",
3190 &pSrcCcb->DirectoryCB->NameInformation.FileName,
3194 try_return( ntStatus);
3198 // Update the object information block, if needed
3201 if( !AFSIsEqualFID( &pSrcObject->FileId,
3205 AFSAcquireExcl( pSrcObject->VolumeCB->ObjectInfoTree.TreeLock,
3209 // Remove the old information entry
3212 AFSRemoveHashEntry( &pSrcObject->VolumeCB->ObjectInfoTree.TreeHead,
3213 &pSrcObject->TreeEntry);
3215 RtlCopyMemory( &pSrcObject->FileId,
3217 sizeof( AFSFileID));
3220 // Insert the entry into the new object table.
3223 pSrcObject->TreeEntry.HashIndex = AFSCreateLowIndex( &pSrcObject->FileId);
3225 if( pSrcObject->VolumeCB->ObjectInfoTree.TreeHead == NULL)
3228 pSrcObject->VolumeCB->ObjectInfoTree.TreeHead = &pSrcObject->TreeEntry;
3233 if ( !NT_SUCCESS( AFSInsertHashEntry( pSrcObject->VolumeCB->ObjectInfoTree.TreeHead,
3234 &pSrcObject->TreeEntry)))
3238 // Lost a race, an ObjectInfo object already exists for this FID.
3239 // Let this copy be garbage collected.
3242 ClearFlag( pSrcObject->Flags, AFS_OBJECT_INSERTED_HASH_TREE);
3246 AFSReleaseResource( pSrcObject->VolumeCB->ObjectInfoTree.TreeLock);
3250 // Update the hash values for the name trees.
3253 pSrcCcb->DirectoryCB->CaseSensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pSrcCcb->DirectoryCB->NameInformation.FileName,
3256 pSrcCcb->DirectoryCB->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pSrcCcb->DirectoryCB->NameInformation.FileName,
3259 if( !BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
3260 pSrcCcb->DirectoryCB->NameInformation.ShortNameLength > 0 &&
3261 !RtlIsNameLegalDOS8Dot3( &pSrcCcb->DirectoryCB->NameInformation.FileName,
3266 uniShortName.Length = pSrcCcb->DirectoryCB->NameInformation.ShortNameLength;
3267 uniShortName.MaximumLength = uniShortName.Length;
3268 uniShortName.Buffer = pSrcCcb->DirectoryCB->NameInformation.ShortName;
3270 pSrcCcb->DirectoryCB->Type.Data.ShortNameTreeEntry.HashIndex = AFSGenerateCRC( &uniShortName,
3273 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3274 AFS_TRACE_LEVEL_VERBOSE,
3275 "AFSSetRenameInfo Initialized short name hash for %wZ longname %wZ\n",
3277 &pSrcCcb->DirectoryCB->NameInformation.FileName));
3282 pSrcCcb->DirectoryCB->Type.Data.ShortNameTreeEntry.HashIndex = 0;
3289 // Update the file index for the object in the new parent
3292 pSrcCcb->DirectoryCB->FileIndex = (ULONG)InterlockedIncrement( &pTargetParentObject->Specific.Directory.DirectoryNodeHdr.ContentIndex);
3296 // Re-insert the directory entry
3299 AFSInsertDirectoryNode( pTargetParentObject,
3300 pSrcCcb->DirectoryCB,
3304 // Update the parent pointer in the source object if they are different
3307 if( pSrcParentObject != pTargetParentObject)
3310 lCount = InterlockedDecrement( &pSrcParentObject->Specific.Directory.ChildOpenHandleCount);
3312 lCount = InterlockedDecrement( &pSrcParentObject->Specific.Directory.ChildOpenReferenceCount);
3314 lCount = InterlockedIncrement( &pTargetParentObject->Specific.Directory.ChildOpenHandleCount);
3316 lCount = InterlockedIncrement( &pTargetParentObject->Specific.Directory.ChildOpenReferenceCount);
3320 // Guaranteed to be in the same volume
3323 AFSAcquireExcl( pSrcParentObject->VolumeCB->ObjectInfoTree.TreeLock,
3326 lCount = AFSObjectInfoIncrement( pTargetParentObject,
3327 AFS_OBJECT_REFERENCE_CHILD);
3329 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
3330 AFS_TRACE_LEVEL_VERBOSE,
3331 "AFSSetRenameInfo Increment count on parent object %p Cnt %d\n",
3332 pTargetParentObject,
3335 lCount = AFSObjectInfoDecrement( pSrcParentObject,
3336 AFS_OBJECT_REFERENCE_CHILD);
3338 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
3339 AFS_TRACE_LEVEL_VERBOSE,
3340 "AFSSetRenameInfo Decrement count on parent object %p Cnt %d\n",
3344 pSrcObject->ParentFileId = pTargetParentObject->FileId;
3346 SetFlag( pSrcObject->Flags, AFS_OBJECT_FLAGS_PARENT_FID);
3348 AFSReleaseResource( pSrcParentObject->VolumeCB->ObjectInfoTree.TreeLock);
3350 ulNotificationAction = FILE_ACTION_ADDED;
3355 ulNotificationAction = FILE_ACTION_RENAMED_NEW_NAME;
3359 // Now update the notification for the target file
3362 AFSFsRtlNotifyFullReportChange( pTargetParentObject,
3364 (ULONG)ulNotifyFilter,
3365 (ULONG)ulNotificationAction);
3368 // If we performed the rename of the target because it existed, we now need to
3369 // delete the tmp target we created above
3372 if( bTargetEntryExists)
3375 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3376 AFS_TRACE_LEVEL_VERBOSE,
3377 "AFSSetRenameInfo Setting DELETE flag in dir entry %p name %wZ\n",
3379 &pTargetDirEntry->NameInformation.FileName));
3381 SetFlag( pTargetDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
3384 // Try and purge the cache map if this is a file
3387 if( pTargetDirEntry->ObjectInformation->FileType == AFS_FILE_TYPE_FILE &&
3388 pTargetDirEntry->ObjectInformation->Fcb != NULL &&
3389 pTargetDirEntry->DirOpenReferenceCount > 1)
3392 pTargetFcb = pTargetDirEntry->ObjectInformation->Fcb;
3395 ASSERT( pTargetDirEntry->DirOpenReferenceCount > 0);
3397 lCount = InterlockedDecrement( &pTargetDirEntry->DirOpenReferenceCount); // The count we added above
3399 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3400 AFS_TRACE_LEVEL_VERBOSE,
3401 "AFSSetRenameInfo Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
3402 &pTargetDirEntry->NameInformation.FileName,
3407 ASSERT( lCount >= 0);
3410 pTargetDirEntry->NameArrayReferenceCount <= 0)
3413 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3414 AFS_TRACE_LEVEL_VERBOSE,
3415 "AFSSetRenameInfo Deleting dir entry %p name %wZ\n",
3417 &pTargetDirEntry->NameInformation.FileName));
3419 AFSDeleteDirEntry( pTargetParentObject,
3423 pTargetDirEntry = NULL;
3425 if ( pTargetFcb != NULL)
3429 // Do not hold TreeLocks across the MmForceSectionClosed() call as
3430 // it can deadlock with Trend Micro's TmPreFlt!TmpQueryFullName
3433 if( bReleaseTargetDirLock)
3435 AFSReleaseResource( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
3437 bReleaseTargetDirLock = FALSE;
3440 if( bReleaseSourceDirLock)
3443 AFSReleaseResource( pSourceDirLock);
3445 bReleaseSourceDirLock = FALSE;
3449 // MmForceSectionClosed() can eventually call back into AFSCleanup
3450 // which will need to acquire Fcb->Resource exclusively. Failure
3451 // to obtain it here before holding the SectionObjectResource will
3452 // permit the locks to be obtained out of order risking a deadlock.
3455 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3456 AFS_TRACE_LEVEL_VERBOSE,
3457 "AFSSetRenameInfo Acquiring Fcb lock %p EXCL %08lX\n",
3458 &pTargetFcb->NPFcb->Resource,
3459 PsGetCurrentThread()));
3461 AFSAcquireExcl( &pTargetFcb->NPFcb->Resource,
3464 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3465 AFS_TRACE_LEVEL_VERBOSE,
3466 "AFSSetRenameInfo Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
3467 &pTargetFcb->NPFcb->SectionObjectResource,
3468 PsGetCurrentThread()));
3470 AFSAcquireExcl( &pTargetFcb->NPFcb->SectionObjectResource,
3477 // Close the section in the event it was mapped
3480 if( !MmForceSectionClosed( &pTargetFcb->NPFcb->SectionObjectPointers,
3484 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3485 AFS_TRACE_LEVEL_ERROR,
3486 "AFSSetRenameInfo Failed to delete section for target file %wZ\n",
3490 __except( EXCEPTION_EXECUTE_HANDLER)
3493 ntStatus = GetExceptionCode();
3497 "EXCEPTION - AFSSetRenameInfo MmForceSectionClosed failed FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
3498 pTargetFcb->ObjectInformation->FileId.Cell,
3499 pTargetFcb->ObjectInformation->FileId.Volume,
3500 pTargetFcb->ObjectInformation->FileId.Vnode,
3501 pTargetFcb->ObjectInformation->FileId.Unique,
3505 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3506 AFS_TRACE_LEVEL_VERBOSE,
3507 "AFSSetRenameInfo Releasing Fcb SectionObject lock %p EXCL %08lX\n",
3508 &pTargetFcb->NPFcb->SectionObjectResource,
3509 PsGetCurrentThread()));
3511 AFSReleaseResource( &pTargetFcb->NPFcb->SectionObjectResource);
3513 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3514 AFS_TRACE_LEVEL_VERBOSE,
3515 "AFSSetRenameInfo Releasing Fcb lock %p EXCL %08lX\n",
3516 &pTargetFcb->NPFcb->Resource,
3517 PsGetCurrentThread()));
3519 AFSReleaseResource( &pTargetFcb->NPFcb->Resource);
3525 if( !NT_SUCCESS( ntStatus))
3528 if( bTargetEntryExists)
3531 ASSERT( pTargetParentObject != NULL);
3533 AFSInsertDirectoryNode( pTargetParentObject,
3539 if( pTargetDirEntry != NULL)
3542 lCount = InterlockedDecrement( &pTargetDirEntry->DirOpenReferenceCount);
3544 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3545 AFS_TRACE_LEVEL_VERBOSE,
3546 "AFSSetRenameInfo Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
3547 &pTargetDirEntry->NameInformation.FileName,
3552 ASSERT( lCount >= 0);
3555 if( bReleaseTargetDirLock)
3558 AFSReleaseResource( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
3561 if( bReleaseSourceDirLock)
3564 AFSReleaseResource( pSourceDirLock);
3567 if ( bDereferenceTargetParentObject)
3570 ObDereferenceObject( pTargetParentFileObj);
3573 if ( pSrcParentObject != NULL)
3576 AFSReleaseObjectInfo( &pSrcParentObject);
3580 // No need to release pTargetParentObject as it is either a copy of pSrcParentObject
3581 // or (AFSFcb *)pTargetFileObj->FsContext->ObjectInformation
3584 pTargetParentObject = NULL;
3591 AFSSetPositionInfo( IN PIRP Irp,
3592 IN AFSDirectoryCB *DirectoryCB)
3594 UNREFERENCED_PARAMETER(DirectoryCB);
3595 NTSTATUS ntStatus = STATUS_SUCCESS;
3596 PFILE_POSITION_INFORMATION pBuffer;
3597 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
3599 pBuffer = (PFILE_POSITION_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
3601 pIrpSp->FileObject->CurrentByteOffset.QuadPart = pBuffer->CurrentByteOffset.QuadPart;
3607 AFSSetAllocationInfo( IN PIRP Irp,
3608 IN AFSDirectoryCB *DirectoryCB)
3610 UNREFERENCED_PARAMETER(DirectoryCB);
3611 NTSTATUS ntStatus = STATUS_SUCCESS;
3612 PFILE_ALLOCATION_INFORMATION pBuffer;
3613 BOOLEAN bReleasePaging = FALSE;
3614 BOOLEAN bTellCc = FALSE;
3615 BOOLEAN bTellService = FALSE;
3616 BOOLEAN bUserMapped = FALSE;
3617 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
3618 PFILE_OBJECT pFileObject = pIrpSp->FileObject;
3619 AFSFcb *pFcb = NULL;
3620 AFSCcb *pCcb = NULL;
3621 LARGE_INTEGER liSaveAlloc;
3622 LARGE_INTEGER liSaveFileSize;
3623 LARGE_INTEGER liSaveVDL;
3625 pBuffer = (PFILE_ALLOCATION_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
3627 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
3629 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
3632 // save values to put back
3634 liSaveAlloc = pFcb->Header.AllocationSize;
3635 liSaveFileSize = pFcb->Header.FileSize;
3636 liSaveVDL = pFcb->Header.ValidDataLength;
3638 if( pFcb->Header.AllocationSize.QuadPart == pBuffer->AllocationSize.QuadPart ||
3639 pIrpSp->Parameters.SetFile.AdvanceOnly)
3641 return STATUS_SUCCESS ;
3644 if( pFcb->Header.AllocationSize.QuadPart > pBuffer->AllocationSize.QuadPart)
3647 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3648 AFS_TRACE_LEVEL_VERBOSE,
3649 "AFSSetAllocationInfo Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
3650 &pFcb->NPFcb->SectionObjectResource,
3651 PsGetCurrentThread()));
3653 AFSAcquireExcl( &pFcb->NPFcb->SectionObjectResource,
3659 bUserMapped = !MmCanFileBeTruncated( pFileObject->SectionObjectPointer,
3660 &pBuffer->AllocationSize);
3662 __except( EXCEPTION_EXECUTE_HANDLER)
3665 bUserMapped = FALSE;
3667 ntStatus = GetExceptionCode();
3671 "EXCEPTION - AFSSetAllocationInfo MmCanFileBeTruncated failed FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
3672 pFcb->ObjectInformation->FileId.Cell,
3673 pFcb->ObjectInformation->FileId.Volume,
3674 pFcb->ObjectInformation->FileId.Vnode,
3675 pFcb->ObjectInformation->FileId.Unique,
3679 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3680 AFS_TRACE_LEVEL_VERBOSE,
3681 "AFSSetAllocationInfo Releasing Fcb SectionObject lock %p EXCL %08lX\n",
3682 &pFcb->NPFcb->SectionObjectResource,
3683 PsGetCurrentThread()));
3685 AFSReleaseResource( &pFcb->NPFcb->SectionObjectResource);
3688 // Truncating the file
3693 ntStatus = STATUS_USER_MAPPED_FILE ;
3699 // If this is a truncation we need to grab the paging IO resource.
3702 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3703 AFS_TRACE_LEVEL_VERBOSE,
3704 "AFSSetAllocationInfo Acquiring Fcb PagingIo lock %p EXCL %08lX\n",
3705 &pFcb->NPFcb->PagingResource,
3706 PsGetCurrentThread()));
3708 AFSAcquireExcl( &pFcb->NPFcb->PagingResource,
3711 bReleasePaging = TRUE;
3714 // Must drop the Fcb Resource. When changing the file size
3715 // a deadlock can occur with Trend Micro's filter if the file
3716 // size is set to zero.
3719 AFSReleaseResource( &pFcb->NPFcb->Resource);
3721 pFcb->Header.AllocationSize = pBuffer->AllocationSize;
3723 pFcb->ObjectInformation->AllocationSize = pBuffer->AllocationSize;
3726 // Tell Cc that Allocation is moved.
3730 if( pFcb->Header.FileSize.QuadPart > pBuffer->AllocationSize.QuadPart)
3733 // We are pulling the EOF back as well so we need to tell
3736 bTellService = TRUE;
3738 pFcb->Header.FileSize = pBuffer->AllocationSize;
3740 pFcb->ObjectInformation->EndOfFile = pBuffer->AllocationSize;
3748 // Tell Cc if allocation is increased.
3751 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3752 AFS_TRACE_LEVEL_VERBOSE,
3753 "AFSSetAllocationInfo Acquiring Fcb PagingIo lock %p EXCL %08lX\n",
3754 &pFcb->NPFcb->PagingResource,
3755 PsGetCurrentThread()));
3757 AFSAcquireExcl( &pFcb->NPFcb->PagingResource,
3760 bReleasePaging = TRUE;
3763 // Must drop the Fcb Resource. When changing the file size
3764 // a deadlock can occur with Trend Micro's filter if the file
3765 // size is set to zero.
3768 AFSReleaseResource( &pFcb->NPFcb->Resource);
3770 bTellCc = pBuffer->AllocationSize.QuadPart > pFcb->Header.AllocationSize.QuadPart;
3772 pFcb->Header.AllocationSize = pBuffer->AllocationSize;
3774 pFcb->ObjectInformation->AllocationSize = pBuffer->AllocationSize;
3778 // Now Tell the server if we have to
3783 ASSERT( BooleanFlagOn( pFcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_PARENT_FID));
3785 ntStatus = AFSUpdateFileInformation( &pFcb->ObjectInformation->ParentFileId,
3786 pFcb->ObjectInformation,
3790 if (NT_SUCCESS(ntStatus))
3793 // Trim extents if we told the service - the update has done an implicit
3794 // trim at the service.
3798 AFSTrimExtents( pFcb,
3799 &pFcb->Header.FileSize);
3802 KeQuerySystemTime( &pFcb->ObjectInformation->ChangeTime);
3804 SetFlag( pFcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_CHANGE_TIME);
3807 CcIsFileCached( pFileObject))
3809 CcSetFileSizes( pFileObject,
3810 (PCC_FILE_SIZES)&pFcb->Header.AllocationSize);
3816 // Put the saved values back
3818 pFcb->Header.ValidDataLength = liSaveVDL;
3819 pFcb->Header.FileSize = liSaveFileSize;
3820 pFcb->Header.AllocationSize = liSaveAlloc;
3821 pFcb->ObjectInformation->EndOfFile = liSaveFileSize;
3822 pFcb->ObjectInformation->AllocationSize = liSaveAlloc;
3828 AFSReleaseResource( &pFcb->NPFcb->PagingResource);
3830 AFSAcquireExcl( &pFcb->NPFcb->Resource,
3838 AFSSetEndOfFileInfo( IN PIRP Irp,
3839 IN AFSDirectoryCB *DirectoryCB)
3841 UNREFERENCED_PARAMETER(DirectoryCB);
3842 NTSTATUS ntStatus = STATUS_SUCCESS;
3843 PFILE_END_OF_FILE_INFORMATION pBuffer;
3844 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
3845 PFILE_OBJECT pFileObject = pIrpSp->FileObject;
3846 LARGE_INTEGER liSaveSize;
3847 LARGE_INTEGER liSaveVDL;
3848 LARGE_INTEGER liSaveAlloc;
3849 BOOLEAN bModified = FALSE;
3850 BOOLEAN bReleasePaging = FALSE;
3851 BOOLEAN bTruncated = FALSE;
3852 BOOLEAN bUserMapped = FALSE;
3853 AFSFcb *pFcb = NULL;
3854 AFSCcb *pCcb = NULL;
3856 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
3858 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
3860 pBuffer = (PFILE_END_OF_FILE_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
3862 liSaveSize = pFcb->Header.FileSize;
3863 liSaveAlloc = pFcb->Header.AllocationSize;
3864 liSaveVDL = pFcb->Header.ValidDataLength;
3866 if( pFcb->Header.FileSize.QuadPart != pBuffer->EndOfFile.QuadPart &&
3867 !pIrpSp->Parameters.SetFile.AdvanceOnly)
3870 if( pBuffer->EndOfFile.QuadPart < pFcb->Header.FileSize.QuadPart)
3873 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3874 AFS_TRACE_LEVEL_VERBOSE,
3875 "AFSSetEndOfFileInfo Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
3876 &pFcb->NPFcb->SectionObjectResource,
3877 PsGetCurrentThread()));
3879 AFSAcquireExcl( &pFcb->NPFcb->SectionObjectResource,
3885 bUserMapped = !MmCanFileBeTruncated( pFileObject->SectionObjectPointer,
3886 &pBuffer->EndOfFile);
3888 __except( EXCEPTION_EXECUTE_HANDLER)
3891 bUserMapped = FALSE;
3893 ntStatus = GetExceptionCode();
3897 "EXCEPTION - AFSSetEndOfFileInfo MmCanFileBeTruncated failed FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
3898 pFcb->ObjectInformation->FileId.Cell,
3899 pFcb->ObjectInformation->FileId.Volume,
3900 pFcb->ObjectInformation->FileId.Vnode,
3901 pFcb->ObjectInformation->FileId.Unique,
3905 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3906 AFS_TRACE_LEVEL_VERBOSE,
3907 "AFSSetEndOfFileInfo Releasing Fcb SectionObject lock %p EXCL %08lX\n",
3908 &pFcb->NPFcb->SectionObjectResource,
3909 PsGetCurrentThread()));
3911 AFSReleaseResource( &pFcb->NPFcb->SectionObjectResource);
3913 // Truncating the file
3917 ntStatus = STATUS_USER_MAPPED_FILE;
3923 // If this is a truncation we need to grab the paging
3926 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3927 AFS_TRACE_LEVEL_VERBOSE,
3928 "AFSSetAllocationInfo Acquiring Fcb PagingIo lock %p EXCL %08lX\n",
3929 &pFcb->NPFcb->PagingResource,
3930 PsGetCurrentThread()));
3932 AFSAcquireExcl( &pFcb->NPFcb->PagingResource,
3935 bReleasePaging = TRUE;
3938 // Must drop the Fcb Resource. When changing the file size
3939 // a deadlock can occur with Trend Micro's filter if the file
3940 // size is set to zero.
3943 AFSReleaseResource( &pFcb->NPFcb->Resource);
3945 pFcb->Header.AllocationSize = pBuffer->EndOfFile;
3947 pFcb->Header.FileSize = pBuffer->EndOfFile;
3949 pFcb->ObjectInformation->EndOfFile = pBuffer->EndOfFile;
3951 pFcb->ObjectInformation->AllocationSize = pBuffer->EndOfFile;
3953 if( pFcb->Header.ValidDataLength.QuadPart > pFcb->Header.FileSize.QuadPart)
3956 pFcb->Header.ValidDataLength = pFcb->Header.FileSize;
3968 // extending the file, move EOF
3972 // If this is a truncation we need to grab the paging
3975 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3976 AFS_TRACE_LEVEL_VERBOSE,
3977 "AFSSetAllocationInfo Acquiring Fcb PagingIo lock %p EXCL %08lX\n",
3978 &pFcb->NPFcb->PagingResource,
3979 PsGetCurrentThread()));
3981 AFSAcquireExcl( &pFcb->NPFcb->PagingResource,
3984 bReleasePaging = TRUE;
3987 // Must drop the Fcb Resource. When changing the file size
3988 // a deadlock can occur with Trend Micro's filter if the file
3989 // size is set to zero.
3992 AFSReleaseResource( &pFcb->NPFcb->Resource);
3994 pFcb->Header.FileSize = pBuffer->EndOfFile;
3996 pFcb->ObjectInformation->EndOfFile = pBuffer->EndOfFile;
3998 if (pFcb->Header.FileSize.QuadPart > pFcb->Header.AllocationSize.QuadPart)
4001 // And Allocation as needed.
4003 pFcb->Header.AllocationSize = pBuffer->EndOfFile;
4005 pFcb->ObjectInformation->AllocationSize = pBuffer->EndOfFile;
4015 KeQuerySystemTime( &pFcb->ObjectInformation->ChangeTime);
4017 SetFlag( pFcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_CHANGE_TIME);
4023 ASSERT( BooleanFlagOn( pFcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_PARENT_FID));
4025 ntStatus = AFSUpdateFileInformation( &pFcb->ObjectInformation->ParentFileId,
4026 pFcb->ObjectInformation,
4029 if( NT_SUCCESS(ntStatus))
4032 // We are now good to go so tell CC.
4034 CcSetFileSizes( pFileObject,
4035 (PCC_FILE_SIZES)&pFcb->Header.AllocationSize);
4038 // And give up those extents
4043 AFSTrimExtents( pFcb,
4044 &pFcb->Header.FileSize);
4049 pFcb->Header.ValidDataLength = liSaveVDL;
4050 pFcb->Header.FileSize = liSaveSize;
4051 pFcb->Header.AllocationSize = liSaveAlloc;
4052 pFcb->ObjectInformation->EndOfFile = liSaveSize;
4053 pFcb->ObjectInformation->AllocationSize = liSaveAlloc;
4060 AFSReleaseResource( &pFcb->NPFcb->PagingResource);
4062 AFSAcquireExcl( &pFcb->NPFcb->Resource,
4070 AFSProcessShareSetInfo( IN IRP *Irp,
4075 UNREFERENCED_PARAMETER(Fcb);
4076 NTSTATUS ntStatus = STATUS_SUCCESS;
4077 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
4078 FILE_INFORMATION_CLASS ulFileInformationClass;
4079 void *pPipeInfo = NULL;
4083 ulFileInformationClass = pIrpSp->Parameters.SetFile.FileInformationClass;
4085 AFSDbgTrace(( AFS_SUBSYSTEM_PIPE_PROCESSING,
4086 AFS_TRACE_LEVEL_VERBOSE,
4087 "AFSProcessShareSetInfo On pipe %wZ Class %08lX\n",
4088 &Ccb->DirectoryCB->NameInformation.FileName,
4089 ulFileInformationClass));
4091 pPipeInfo = AFSLockSystemBuffer( Irp,
4092 pIrpSp->Parameters.SetFile.Length);
4094 if( pPipeInfo == NULL)
4097 AFSDbgTrace(( AFS_SUBSYSTEM_PIPE_PROCESSING,
4098 AFS_TRACE_LEVEL_ERROR,
4099 "AFSProcessShareSetInfo Failed to lock buffer on pipe %wZ\n",
4100 &Ccb->DirectoryCB->NameInformation.FileName));
4102 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4106 // Send the request to the service
4109 ntStatus = AFSNotifySetPipeInfo( Ccb,
4110 (ULONG)ulFileInformationClass,
4111 pIrpSp->Parameters.SetFile.Length,
4114 if( !NT_SUCCESS( ntStatus))
4117 AFSDbgTrace(( AFS_SUBSYSTEM_PIPE_PROCESSING,
4118 AFS_TRACE_LEVEL_ERROR,
4119 "AFSProcessShareSetInfo Failed to send request to service on pipe %wZ Status %08lX\n",
4120 &Ccb->DirectoryCB->NameInformation.FileName,
4123 try_return( ntStatus);
4126 AFSDbgTrace(( AFS_SUBSYSTEM_PIPE_PROCESSING,
4127 AFS_TRACE_LEVEL_VERBOSE,
4128 "AFSProcessShareSetInfo Completed request on pipe %wZ Class %08lX\n",
4129 &Ccb->DirectoryCB->NameInformation.FileName,
4130 ulFileInformationClass));
4141 AFSProcessShareQueryInfo( IN IRP *Irp,
4146 UNREFERENCED_PARAMETER(Fcb);
4147 NTSTATUS ntStatus = STATUS_SUCCESS;
4148 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
4149 FILE_INFORMATION_CLASS ulFileInformationClass;
4150 void *pPipeInfo = NULL;
4155 ulFileInformationClass = pIrpSp->Parameters.QueryFile.FileInformationClass;
4157 AFSDbgTrace(( AFS_SUBSYSTEM_PIPE_PROCESSING,
4158 AFS_TRACE_LEVEL_VERBOSE,
4159 "AFSProcessShareQueryInfo On pipe %wZ Class %08lX\n",
4160 &Ccb->DirectoryCB->NameInformation.FileName,
4161 ulFileInformationClass));
4163 pPipeInfo = AFSLockSystemBuffer( Irp,
4164 pIrpSp->Parameters.QueryFile.Length);
4166 if( pPipeInfo == NULL)
4169 AFSDbgTrace(( AFS_SUBSYSTEM_PIPE_PROCESSING,
4170 AFS_TRACE_LEVEL_ERROR,
4171 "AFSProcessShareQueryInfo Failed to lock buffer on pipe %wZ\n",
4172 &Ccb->DirectoryCB->NameInformation.FileName));
4174 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4178 // Send the request to the service
4181 ntStatus = AFSNotifyQueryPipeInfo( Ccb,
4182 (ULONG)ulFileInformationClass,
4183 pIrpSp->Parameters.QueryFile.Length,
4185 (ULONG *)&Irp->IoStatus.Information);
4187 if( !NT_SUCCESS( ntStatus))
4190 AFSDbgTrace(( AFS_SUBSYSTEM_PIPE_PROCESSING,
4191 AFS_TRACE_LEVEL_ERROR,
4192 "AFSProcessShareQueryInfo Failed to send request to service on pipe %wZ Status %08lX\n",
4193 &Ccb->DirectoryCB->NameInformation.FileName,
4196 try_return( ntStatus);
4199 AFSDbgTrace(( AFS_SUBSYSTEM_PIPE_PROCESSING,
4200 AFS_TRACE_LEVEL_VERBOSE,
4201 "AFSProcessShareQueryInfo Completed request on pipe %wZ Class %08lX\n",
4202 &Ccb->DirectoryCB->NameInformation.FileName,
4203 ulFileInformationClass));
4214 AFSProcessPIOCtlQueryInfo( IN IRP *Irp,
4217 IN OUT LONG *Length)
4220 UNREFERENCED_PARAMETER(Fcb);
4221 UNREFERENCED_PARAMETER(Ccb);
4222 NTSTATUS ntStatus = STATUS_SUCCESS;
4223 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
4224 FILE_INFORMATION_CLASS ulFileInformationClass;
4229 ulFileInformationClass = pIrpSp->Parameters.QueryFile.FileInformationClass;
4231 switch( ulFileInformationClass)
4234 case FileBasicInformation:
4237 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4238 AFS_TRACE_LEVEL_VERBOSE,
4239 "AFSProcessPIOCtlQueryInfo (FileBasicInformation)\n"));
4241 if ( *Length >= sizeof( FILE_BASIC_INFORMATION))
4243 PFILE_BASIC_INFORMATION pBasic = (PFILE_BASIC_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
4245 pBasic->CreationTime.QuadPart = 0;
4246 pBasic->LastAccessTime.QuadPart = 0;
4247 pBasic->ChangeTime.QuadPart = 0;
4248 pBasic->LastWriteTime.QuadPart = 0;
4249 pBasic->FileAttributes = FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM;
4251 *Length -= sizeof( FILE_BASIC_INFORMATION);
4255 ntStatus = STATUS_BUFFER_TOO_SMALL;
4261 case FileStandardInformation:
4264 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4265 AFS_TRACE_LEVEL_VERBOSE,
4266 "AFSProcessPIOCtlQueryInfo (FileStandardInformation)\n"));
4268 if ( *Length >= sizeof( FILE_STANDARD_INFORMATION))
4270 PFILE_STANDARD_INFORMATION pStandard = (PFILE_STANDARD_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
4272 pStandard->NumberOfLinks = 1;
4273 pStandard->DeletePending = 0;
4274 pStandard->AllocationSize.QuadPart = 0;
4275 pStandard->EndOfFile.QuadPart = 0;
4276 pStandard->Directory = 0;
4278 *Length -= sizeof( FILE_STANDARD_INFORMATION);
4282 ntStatus = STATUS_BUFFER_TOO_SMALL;
4288 case FileNormalizedNameInformation:
4289 case FileNameInformation:
4292 ULONG ulCopyLength = 0;
4293 AFSFcb *pFcb = NULL;
4294 AFSCcb *pCcb = NULL;
4295 USHORT usFullNameLength = 0;
4296 PFILE_NAME_INFORMATION pNameInfo = (PFILE_NAME_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
4297 UNICODE_STRING uniName;
4299 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4300 AFS_TRACE_LEVEL_VERBOSE,
4301 "AFSProcessPIOCtlQueryInfo (FileNameInformation)\n"));
4303 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
4304 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
4306 if( *Length < FIELD_OFFSET( FILE_NAME_INFORMATION, FileName))
4308 ntStatus = STATUS_BUFFER_TOO_SMALL;
4312 RtlZeroMemory( pNameInfo,
4315 usFullNameLength = sizeof( WCHAR) +
4316 AFSServerName.Length +
4317 pCcb->FullFileName.Length;
4319 if( *Length >= (LONG)(FIELD_OFFSET( FILE_NAME_INFORMATION, FileName) + (LONG)usFullNameLength))
4321 ulCopyLength = (LONG)usFullNameLength;
4325 ulCopyLength = *Length - FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
4326 ntStatus = STATUS_BUFFER_OVERFLOW;
4329 pNameInfo->FileNameLength = (ULONG)usFullNameLength;
4331 *Length -= FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
4333 if( ulCopyLength > 0)
4336 pNameInfo->FileName[ 0] = L'\\';
4337 ulCopyLength -= sizeof( WCHAR);
4339 *Length -= sizeof( WCHAR);
4341 if( ulCopyLength >= AFSServerName.Length)
4344 RtlCopyMemory( &pNameInfo->FileName[ 1],
4345 AFSServerName.Buffer,
4346 AFSServerName.Length);
4348 ulCopyLength -= AFSServerName.Length;
4349 *Length -= AFSServerName.Length;
4351 if( ulCopyLength >= pCcb->FullFileName.Length)
4354 RtlCopyMemory( &pNameInfo->FileName[ 1 + (AFSServerName.Length/sizeof( WCHAR))],
4355 pCcb->FullFileName.Buffer,
4356 pCcb->FullFileName.Length);
4358 ulCopyLength -= pCcb->FullFileName.Length;
4359 *Length -= pCcb->FullFileName.Length;
4361 uniName.Length = (USHORT)pNameInfo->FileNameLength;
4362 uniName.MaximumLength = uniName.Length;
4363 uniName.Buffer = pNameInfo->FileName;
4368 RtlCopyMemory( &pNameInfo->FileName[ 1 + (AFSServerName.Length/sizeof( WCHAR))],
4369 pCcb->FullFileName.Buffer,
4372 *Length -= ulCopyLength;
4374 uniName.Length = (USHORT)(sizeof( WCHAR) + AFSServerName.Length + ulCopyLength);
4375 uniName.MaximumLength = uniName.Length;
4376 uniName.Buffer = pNameInfo->FileName;
4379 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4380 AFS_TRACE_LEVEL_VERBOSE,
4381 "AFSProcessPIOCtlQueryInfo (FileNameInformation) Returning %wZ\n",
4389 case FileInternalInformation:
4392 PFILE_INTERNAL_INFORMATION pInternalInfo = (PFILE_INTERNAL_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
4394 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4395 AFS_TRACE_LEVEL_VERBOSE,
4396 "AFSProcessPIOCtlQueryInfo (FileInternalInformation)\n"));
4398 if( *Length >= sizeof( FILE_INTERNAL_INFORMATION))
4401 pInternalInfo->IndexNumber.HighPart = 0;
4403 pInternalInfo->IndexNumber.LowPart = 0;
4405 *Length -= sizeof( FILE_INTERNAL_INFORMATION);
4410 ntStatus = STATUS_BUFFER_TOO_SMALL;
4416 case FileAllInformation:
4418 ntStatus = STATUS_INVALID_PARAMETER;
4420 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4421 AFS_TRACE_LEVEL_WARNING,
4422 "AFSProcessPIOCtlQueryInfo (FileAllInformation) Not Implemented\n"));
4427 case FileEaInformation:
4429 ntStatus = STATUS_INVALID_PARAMETER;
4431 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4432 AFS_TRACE_LEVEL_WARNING,
4433 "AFSProcessPIOCtlQueryInfo (FileEaInformation) Not Implemented\n"));
4438 case FilePositionInformation:
4440 ntStatus = STATUS_INVALID_PARAMETER;
4442 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4443 AFS_TRACE_LEVEL_WARNING,
4444 "AFSProcessPIOCtlQueryInfo (FilePositionInformation) Not Implemented\n"));
4449 case FileAlternateNameInformation:
4451 ntStatus = STATUS_INVALID_PARAMETER;
4453 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4454 AFS_TRACE_LEVEL_WARNING,
4455 "AFSProcessPIOCtlQueryInfo (FileAlternateNameInformation) Not Implemented\n"));
4460 case FileNetworkOpenInformation:
4462 ntStatus = STATUS_INVALID_PARAMETER;
4464 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4465 AFS_TRACE_LEVEL_WARNING,
4466 "AFSProcessPIOCtlQueryInfo (FileNetworkOpenInformation) Not Implemented\n"));
4471 case FileStreamInformation:
4473 ntStatus = STATUS_INVALID_PARAMETER;
4475 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4476 AFS_TRACE_LEVEL_WARNING,
4477 "AFSProcessPIOCtlQueryInfo (FileStreamInformation) Not Implemented\n"));
4482 case FileAttributeTagInformation:
4484 ntStatus = STATUS_INVALID_PARAMETER;
4486 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4487 AFS_TRACE_LEVEL_WARNING,
4488 "AFSProcessPIOCtlQueryInfo (FileAttributeTagInformation) Not Implemented\n"));
4493 case FileRemoteProtocolInformation:
4495 ntStatus = STATUS_INVALID_PARAMETER;
4497 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4498 AFS_TRACE_LEVEL_WARNING,
4499 "AFSProcessPIOCtlQueryInfo (FileRemoteProtocolInformation) Not Implemented\n"));
4504 case FileNetworkPhysicalNameInformation:
4506 ntStatus = STATUS_INVALID_PARAMETER;
4508 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4509 AFS_TRACE_LEVEL_WARNING,
4510 "AFSProcessPIOCtlQueryInfo (FileNetworkPhysicalNameInformation) Not Implemented\n"));
4517 ntStatus = STATUS_INVALID_PARAMETER;
4519 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4520 AFS_TRACE_LEVEL_WARNING,
4521 "AFSProcessPIOCtlQueryInfo Not handling request %08lX\n",
4522 ulFileInformationClass));
4529 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4530 AFS_TRACE_LEVEL_VERBOSE,
4531 "AFSProcessPIOCtlQueryInfo ntStatus %08lX\n",