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 NTSTATUS ntStatus = STATUS_SUCCESS;
59 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
60 ULONG ulRequestType = 0;
61 IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
64 PFILE_OBJECT pFileObject;
65 BOOLEAN bReleaseMain = FALSE;
67 FILE_INFORMATION_CLASS stFileInformationClass;
74 // Determine the type of request this request is
77 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
79 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
84 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
85 AFS_TRACE_LEVEL_ERROR,
86 "AFSQueryFileInfo Attempted access (%08lX) when pFcb == NULL\n",
89 try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST);
92 lLength = (LONG)pIrpSp->Parameters.QueryFile.Length;
93 stFileInformationClass = pIrpSp->Parameters.QueryFile.FileInformationClass;
94 pBuffer = Irp->AssociatedIrp.SystemBuffer;
97 // Grab the main shared right off the bat
100 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
101 AFS_TRACE_LEVEL_VERBOSE,
102 "AFSQueryFileInfo Acquiring Fcb lock %08lX SHARED %08lX\n",
103 &pFcb->NPFcb->Resource,
104 PsGetCurrentThread());
106 AFSAcquireShared( &pFcb->NPFcb->Resource,
112 // Don't allow requests against IOCtl nodes
115 if( pFcb->Header.NodeTypeCode == AFS_SPECIAL_SHARE_FCB)
118 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
119 AFS_TRACE_LEVEL_VERBOSE,
120 "AFSQueryFileInfo Processing request against SpecialShare Fcb\n");
122 ntStatus = AFSProcessShareQueryInfo( Irp,
126 try_return( ntStatus);
128 else if( pFcb->Header.NodeTypeCode == AFS_IOCTL_FCB)
130 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
131 AFS_TRACE_LEVEL_VERBOSE,
132 "AFSQueryFileInfo request against PIOCtl Fcb\n");
134 ntStatus = AFSProcessPIOCtlQueryInfo( Irp,
139 try_return( ntStatus);
142 else if( pFcb->Header.NodeTypeCode == AFS_INVALID_FCB)
144 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
145 AFS_TRACE_LEVEL_VERBOSE,
146 "AFSQueryFileInfo request against Invalid Fcb\n");
148 try_return( ntStatus = STATUS_ACCESS_DENIED);
152 // Process the request
155 switch( stFileInformationClass)
158 case FileAllInformation:
161 PFILE_ALL_INFORMATION pAllInfo;
164 // For the all information class we'll typecast a local
165 // pointer to the output buffer and then call the
166 // individual routines to fill in the buffer.
169 pAllInfo = (PFILE_ALL_INFORMATION)pBuffer;
171 ntStatus = AFSQueryBasicInfo( Irp,
173 &pAllInfo->BasicInformation,
176 if( !NT_SUCCESS( ntStatus))
179 try_return( ntStatus);
182 ntStatus = AFSQueryStandardInfo( Irp,
184 &pAllInfo->StandardInformation,
187 if( !NT_SUCCESS( ntStatus))
190 try_return( ntStatus);
193 ntStatus = AFSQueryInternalInfo( Irp,
195 &pAllInfo->InternalInformation,
198 if( !NT_SUCCESS( ntStatus))
201 try_return( ntStatus);
204 ntStatus = AFSQueryEaInfo( Irp,
206 &pAllInfo->EaInformation,
209 if( !NT_SUCCESS( ntStatus))
212 try_return( ntStatus);
215 ntStatus = AFSQueryAccess( Irp,
217 &pAllInfo->AccessInformation,
220 if( !NT_SUCCESS( ntStatus))
223 try_return( ntStatus);
226 ntStatus = AFSQueryPositionInfo( Irp,
228 &pAllInfo->PositionInformation,
231 if( !NT_SUCCESS( ntStatus))
234 try_return( ntStatus);
237 ntStatus = AFSQueryMode( Irp,
239 &pAllInfo->ModeInformation,
242 if( !NT_SUCCESS( ntStatus))
245 try_return( ntStatus);
248 ntStatus = AFSQueryAlignment( Irp,
250 &pAllInfo->AlignmentInformation,
253 if( !NT_SUCCESS( ntStatus))
256 try_return( ntStatus);
259 ntStatus = AFSQueryNameInfo( Irp,
261 &pAllInfo->NameInformation,
264 if( !NT_SUCCESS( ntStatus))
267 try_return( ntStatus);
273 case FileBasicInformation:
276 ntStatus = AFSQueryBasicInfo( Irp,
278 (PFILE_BASIC_INFORMATION)pBuffer,
284 case FileStandardInformation:
287 ntStatus = AFSQueryStandardInfo( Irp,
289 (PFILE_STANDARD_INFORMATION)pBuffer,
295 case FileInternalInformation:
298 ntStatus = AFSQueryInternalInfo( Irp,
300 (PFILE_INTERNAL_INFORMATION)pBuffer,
306 case FileEaInformation:
309 ntStatus = AFSQueryEaInfo( Irp,
311 (PFILE_EA_INFORMATION)pBuffer,
317 case FilePositionInformation:
320 ntStatus = AFSQueryPositionInfo( Irp,
322 (PFILE_POSITION_INFORMATION)pBuffer,
328 case FileNormalizedNameInformation:
329 case FileNameInformation:
332 ntStatus = AFSQueryNameInfo( Irp,
334 (PFILE_NAME_INFORMATION)pBuffer,
340 case FileAlternateNameInformation:
343 ntStatus = AFSQueryShortNameInfo( Irp,
345 (PFILE_NAME_INFORMATION)pBuffer,
351 case FileNetworkOpenInformation:
354 ntStatus = AFSQueryNetworkInfo( Irp,
356 (PFILE_NETWORK_OPEN_INFORMATION)pBuffer,
362 case FileStreamInformation:
365 ntStatus = AFSQueryStreamInfo( Irp,
367 (FILE_STREAM_INFORMATION *)pBuffer,
374 case FileAttributeTagInformation:
377 ntStatus = AFSQueryAttribTagInfo( Irp,
379 (FILE_ATTRIBUTE_TAG_INFORMATION *)pBuffer,
385 case FileRemoteProtocolInformation:
388 ntStatus = AFSQueryRemoteProtocolInfo( Irp,
390 (FILE_REMOTE_PROTOCOL_INFORMATION *)pBuffer,
396 case FileNetworkPhysicalNameInformation:
399 ntStatus = AFSQueryPhysicalNameInfo( Irp,
401 (FILE_NETWORK_PHYSICAL_NAME_INFORMATION *)pBuffer,
409 ntStatus = STATUS_INVALID_PARAMETER;
416 Irp->IoStatus.Information = pIrpSp->Parameters.QueryFile.Length - lLength;
421 AFSReleaseResource( &pFcb->NPFcb->Resource);
424 if( !NT_SUCCESS( ntStatus) &&
425 ntStatus != STATUS_INVALID_PARAMETER &&
426 ntStatus != STATUS_BUFFER_OVERFLOW)
430 pCcb->DirectoryCB != NULL)
433 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
434 AFS_TRACE_LEVEL_ERROR,
435 "AFSQueryFileInfo Failed to process request for %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
436 &pCcb->DirectoryCB->NameInformation.FileName,
437 pCcb->DirectoryCB->ObjectInformation->FileId.Cell,
438 pCcb->DirectoryCB->ObjectInformation->FileId.Volume,
439 pCcb->DirectoryCB->ObjectInformation->FileId.Vnode,
440 pCcb->DirectoryCB->ObjectInformation->FileId.Unique,
445 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
450 "EXCEPTION - AFSQueryFileInfo\n");
452 AFSDumpTraceFilesFnc();
454 ntStatus = STATUS_UNSUCCESSFUL;
459 AFSReleaseResource( &pFcb->NPFcb->Resource);
463 AFSCompleteRequest( Irp,
470 // Function: AFSSetFileInfo
474 // This function is the dispatch handler for the IRP_MJ_SET_FILE_INFORMATION request
478 // A status is returned for the function
482 AFSSetFileInfo( IN PDEVICE_OBJECT LibDeviceObject,
486 NTSTATUS ntStatus = STATUS_SUCCESS;
487 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
488 IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
491 BOOLEAN bCompleteRequest = TRUE;
492 FILE_INFORMATION_CLASS FileInformationClass;
493 BOOLEAN bCanQueueRequest = FALSE;
494 PFILE_OBJECT pFileObject = NULL;
495 BOOLEAN bReleaseMain = FALSE;
496 BOOLEAN bUpdateFileInfo = FALSE;
497 AFSFileID stParentFileId;
502 pFileObject = pIrpSp->FileObject;
504 pFcb = (AFSFcb *)pFileObject->FsContext;
505 pCcb = (AFSCcb *)pFileObject->FsContext2;
510 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
511 AFS_TRACE_LEVEL_ERROR,
512 "AFSSetFileInfo Attempted access (%08lX) when pFcb == NULL\n",
515 try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST);
518 bCanQueueRequest = !(IoIsOperationSynchronous( Irp) | (KeGetCurrentIrql() != PASSIVE_LEVEL));
519 FileInformationClass = pIrpSp->Parameters.SetFile.FileInformationClass;
525 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
526 AFS_TRACE_LEVEL_VERBOSE,
527 "AFSSetFileInfo Acquiring Fcb lock %08lX EXCL %08lX\n",
528 &pFcb->NPFcb->Resource,
529 PsGetCurrentThread());
531 AFSAcquireExcl( &pFcb->NPFcb->Resource,
537 // Don't allow requests against IOCtl nodes
540 if( pFcb->Header.NodeTypeCode == AFS_IOCTL_FCB)
543 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
544 AFS_TRACE_LEVEL_ERROR,
545 "AFSSetFileInfo Failing request against PIOCtl Fcb\n");
547 try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST);
549 else if( pFcb->Header.NodeTypeCode == AFS_SPECIAL_SHARE_FCB)
552 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
553 AFS_TRACE_LEVEL_VERBOSE,
554 "AFSSetFileInfo Processing request against SpecialShare Fcb\n");
556 ntStatus = AFSProcessShareSetInfo( Irp,
560 try_return( ntStatus);
563 if( BooleanFlagOn( pFcb->ObjectInformation->VolumeCB->VolumeInformation.Characteristics, FILE_READ_ONLY_DEVICE))
566 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
567 AFS_TRACE_LEVEL_ERROR,
568 "AFSSetFileInfo Request failed due to read only volume\n",
571 try_return( ntStatus = STATUS_MEDIA_WRITE_PROTECTED);
574 if( pFcb->Header.NodeTypeCode == AFS_INVALID_FCB &&
575 FileInformationClass != FileDispositionInformation)
577 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
578 AFS_TRACE_LEVEL_VERBOSE,
579 "AFSSetFileInfo request against Invalid Fcb\n");
581 try_return( ntStatus = STATUS_ACCESS_DENIED);
585 // Ensure rename operations are synchronous
588 if( FileInformationClass == FileRenameInformation)
591 bCanQueueRequest = FALSE;
595 // Store away the parent fid
598 RtlZeroMemory( &stParentFileId,
601 if( pFcb->ObjectInformation->ParentObjectInformation != NULL)
603 stParentFileId = pFcb->ObjectInformation->ParentObjectInformation->FileId;
607 // Process the request
610 switch( FileInformationClass)
613 case FileBasicInformation:
616 bUpdateFileInfo = TRUE;
618 ntStatus = AFSSetBasicInfo( Irp,
624 case FileDispositionInformation:
627 ntStatus = AFSSetDispositionInfo( Irp,
633 case FileRenameInformation:
636 ntStatus = AFSSetRenameInfo( Irp);
641 case FilePositionInformation:
644 ntStatus = AFSSetPositionInfo( Irp,
650 case FileLinkInformation:
653 ntStatus = STATUS_INVALID_DEVICE_REQUEST;
658 case FileAllocationInformation:
661 ntStatus = AFSSetAllocationInfo( Irp,
667 case FileEndOfFileInformation:
670 ntStatus = AFSSetEndOfFileInfo( Irp,
678 ntStatus = STATUS_INVALID_PARAMETER;
688 AFSReleaseResource( &pFcb->NPFcb->Resource);
691 if( NT_SUCCESS( ntStatus) &&
695 ntStatus = AFSUpdateFileInformation( &stParentFileId,
696 pFcb->ObjectInformation,
699 if( !NT_SUCCESS( ntStatus))
702 AFSAcquireExcl( &pFcb->NPFcb->Resource,
706 // Unwind the update and fail the request
709 AFSUnwindFileInfo( pFcb,
712 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
713 AFS_TRACE_LEVEL_ERROR,
714 "AFSSetFileInfo Failed to send file info update to service request for %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
715 &pCcb->DirectoryCB->NameInformation.FileName,
716 pCcb->DirectoryCB->ObjectInformation->FileId.Cell,
717 pCcb->DirectoryCB->ObjectInformation->FileId.Volume,
718 pCcb->DirectoryCB->ObjectInformation->FileId.Vnode,
719 pCcb->DirectoryCB->ObjectInformation->FileId.Unique,
722 AFSReleaseResource( &pFcb->NPFcb->Resource);
726 if( !NT_SUCCESS( ntStatus))
730 pCcb->DirectoryCB != NULL)
733 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
734 AFS_TRACE_LEVEL_ERROR,
735 "AFSSetFileInfo Failed to process request for %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
736 &pCcb->DirectoryCB->NameInformation.FileName,
737 pCcb->DirectoryCB->ObjectInformation->FileId.Cell,
738 pCcb->DirectoryCB->ObjectInformation->FileId.Volume,
739 pCcb->DirectoryCB->ObjectInformation->FileId.Vnode,
740 pCcb->DirectoryCB->ObjectInformation->FileId.Unique,
745 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
750 "EXCEPTION - AFSSetFileInfo\n");
752 AFSDumpTraceFilesFnc();
754 ntStatus = STATUS_UNSUCCESSFUL;
759 AFSReleaseResource( &pFcb->NPFcb->Resource);
763 AFSCompleteRequest( Irp,
770 // Function: AFSQueryBasicInfo
774 // This function is the handler for the query basic information request
778 // A status is returned for the function
782 AFSQueryBasicInfo( IN PIRP Irp,
783 IN AFSDirectoryCB *DirectoryCB,
784 IN OUT PFILE_BASIC_INFORMATION Buffer,
787 NTSTATUS ntStatus = STATUS_SUCCESS;
788 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
789 ULONG ulFileAttribs = 0;
792 IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
793 AFSFileInfoCB stFileInfo;
794 AFSDirectoryCB *pParentDirectoryCB = NULL;
795 UNICODE_STRING uniParentPath;
797 if( *Length >= sizeof( FILE_BASIC_INFORMATION))
800 RtlZeroMemory( Buffer,
803 ulFileAttribs = DirectoryCB->ObjectInformation->FileAttributes;
805 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
806 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
808 if( DirectoryCB->ObjectInformation->FileType == AFS_FILE_TYPE_SYMLINK)
811 pParentDirectoryCB = AFSGetParentEntry( pCcb->NameArray);
813 AFSRetrieveParentPath( &pCcb->FullFileName,
816 RtlZeroMemory( &stFileInfo,
817 sizeof( AFSFileInfoCB));
820 // Can't hold the Fcb while evaluating the path, leads to lock inversion
823 AFSReleaseResource( &pFcb->NPFcb->Resource);
825 if( NT_SUCCESS( AFSRetrieveFileAttributes( pParentDirectoryCB,
832 ulFileAttribs = stFileInfo.FileAttributes;
834 ulFileAttribs |= FILE_ATTRIBUTE_REPARSE_POINT;
837 AFSAcquireShared( &pFcb->NPFcb->Resource,
842 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
843 AFS_TRACE_LEVEL_VERBOSE_2,
844 "AFSQueryBasicInfo %wZ Type 0x%x Attrib 0x%x -> 0x%x\n",
845 &pCcb->DirectoryCB->NameInformation.FileName,
846 pCcb->DirectoryCB->ObjectInformation->FileType,
847 pCcb->DirectoryCB->ObjectInformation->FileAttributes,
850 Buffer->CreationTime = DirectoryCB->ObjectInformation->CreationTime;
851 Buffer->LastAccessTime = DirectoryCB->ObjectInformation->LastAccessTime;
852 Buffer->LastWriteTime = DirectoryCB->ObjectInformation->LastWriteTime;
853 Buffer->ChangeTime = DirectoryCB->ObjectInformation->ChangeTime;
854 Buffer->FileAttributes = ulFileAttribs;
856 if( DirectoryCB->NameInformation.FileName.Buffer[ 0] == L'.' &&
857 BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_HIDE_DOT_NAMES))
860 if ( Buffer->FileAttributes != FILE_ATTRIBUTE_NORMAL)
862 Buffer->FileAttributes |= FILE_ATTRIBUTE_HIDDEN;
866 Buffer->FileAttributes = FILE_ATTRIBUTE_HIDDEN;
870 *Length -= sizeof( FILE_BASIC_INFORMATION);
875 ntStatus = STATUS_BUFFER_TOO_SMALL;
882 AFSQueryStandardInfo( IN PIRP Irp,
883 IN AFSDirectoryCB *DirectoryCB,
884 IN OUT PFILE_STANDARD_INFORMATION Buffer,
888 NTSTATUS ntStatus = STATUS_SUCCESS;
891 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
892 AFSFileInfoCB stFileInfo;
893 AFSDirectoryCB *pParentDirectoryCB = NULL;
894 UNICODE_STRING uniParentPath;
895 ULONG ulFileAttribs = 0;
897 if( *Length >= sizeof( FILE_STANDARD_INFORMATION))
900 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
901 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
903 RtlZeroMemory( Buffer,
906 Buffer->NumberOfLinks = 1;
907 Buffer->DeletePending = BooleanFlagOn( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
909 Buffer->AllocationSize.QuadPart = (ULONGLONG)((DirectoryCB->ObjectInformation->AllocationSize.QuadPart/PAGE_SIZE) + 1) * PAGE_SIZE;
911 Buffer->EndOfFile = DirectoryCB->ObjectInformation->EndOfFile;
913 ulFileAttribs = DirectoryCB->ObjectInformation->FileAttributes;
915 if( DirectoryCB->ObjectInformation->FileType == AFS_FILE_TYPE_SYMLINK)
918 pParentDirectoryCB = AFSGetParentEntry( pCcb->NameArray);
920 AFSRetrieveParentPath( &pCcb->FullFileName,
923 RtlZeroMemory( &stFileInfo,
924 sizeof( AFSFileInfoCB));
927 // Can't hold the Fcb while evaluating the path, leads to lock inversion
930 AFSReleaseResource( &pFcb->NPFcb->Resource);
932 if( NT_SUCCESS( AFSRetrieveFileAttributes( pParentDirectoryCB,
939 ulFileAttribs = stFileInfo.FileAttributes;
942 AFSAcquireShared( &pFcb->NPFcb->Resource,
946 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
947 AFS_TRACE_LEVEL_VERBOSE_2,
948 "AFSQueryStandardInfo %wZ Type 0x%x Attrib 0x%x -> 0x%x\n",
949 &pCcb->DirectoryCB->NameInformation.FileName,
950 pCcb->DirectoryCB->ObjectInformation->FileType,
951 pCcb->DirectoryCB->ObjectInformation->FileAttributes,
954 Buffer->Directory = BooleanFlagOn( ulFileAttribs, FILE_ATTRIBUTE_DIRECTORY);
956 *Length -= sizeof( FILE_STANDARD_INFORMATION);
961 ntStatus = STATUS_BUFFER_TOO_SMALL;
968 AFSQueryInternalInfo( IN PIRP Irp,
970 IN OUT PFILE_INTERNAL_INFORMATION Buffer,
974 NTSTATUS ntStatus = STATUS_SUCCESS;
976 if( *Length >= sizeof( FILE_INTERNAL_INFORMATION))
979 Buffer->IndexNumber.HighPart = Fcb->ObjectInformation->FileId.Volume;
981 Buffer->IndexNumber.LowPart = Fcb->ObjectInformation->FileId.Vnode;
983 *Length -= sizeof( FILE_INTERNAL_INFORMATION);
988 ntStatus = STATUS_BUFFER_TOO_SMALL;
995 AFSQueryEaInfo( IN PIRP Irp,
996 IN AFSDirectoryCB *DirectoryCB,
997 IN OUT PFILE_EA_INFORMATION Buffer,
1001 NTSTATUS ntStatus = STATUS_SUCCESS;
1003 RtlZeroMemory( Buffer,
1006 if( *Length >= sizeof( FILE_EA_INFORMATION))
1011 *Length -= sizeof( FILE_EA_INFORMATION);
1016 ntStatus = STATUS_BUFFER_TOO_SMALL;
1023 AFSQueryPositionInfo( IN PIRP Irp,
1025 IN OUT PFILE_POSITION_INFORMATION Buffer,
1026 IN OUT PLONG Length)
1029 NTSTATUS ntStatus = STATUS_SUCCESS;
1030 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1032 if( *Length >= sizeof( FILE_POSITION_INFORMATION))
1035 RtlZeroMemory( Buffer,
1038 Buffer->CurrentByteOffset.QuadPart = pIrpSp->FileObject->CurrentByteOffset.QuadPart;
1040 *Length -= sizeof( FILE_POSITION_INFORMATION);
1045 ntStatus = STATUS_BUFFER_TOO_SMALL;
1052 AFSQueryAccess( IN PIRP Irp,
1054 IN OUT PFILE_ACCESS_INFORMATION Buffer,
1055 IN OUT PLONG Length)
1058 NTSTATUS ntStatus = STATUS_SUCCESS;
1060 if( *Length >= sizeof( FILE_ACCESS_INFORMATION))
1063 RtlZeroMemory( Buffer,
1066 Buffer->AccessFlags = 0;
1068 *Length -= sizeof( FILE_ACCESS_INFORMATION);
1073 ntStatus = STATUS_BUFFER_TOO_SMALL;
1080 AFSQueryMode( IN PIRP Irp,
1082 IN OUT PFILE_MODE_INFORMATION Buffer,
1083 IN OUT PLONG Length)
1086 NTSTATUS ntStatus = STATUS_SUCCESS;
1088 if( *Length >= sizeof( FILE_MODE_INFORMATION))
1091 RtlZeroMemory( Buffer,
1096 *Length -= sizeof( FILE_MODE_INFORMATION);
1101 ntStatus = STATUS_BUFFER_TOO_SMALL;
1108 AFSQueryAlignment( IN PIRP Irp,
1110 IN OUT PFILE_ALIGNMENT_INFORMATION Buffer,
1111 IN OUT PLONG Length)
1114 NTSTATUS ntStatus = STATUS_SUCCESS;
1116 if( *Length >= sizeof( FILE_ALIGNMENT_INFORMATION))
1119 RtlZeroMemory( Buffer,
1122 Buffer->AlignmentRequirement = 1;
1124 *Length -= sizeof( FILE_ALIGNMENT_INFORMATION);
1129 ntStatus = STATUS_BUFFER_TOO_SMALL;
1136 AFSQueryNameInfo( IN PIRP Irp,
1137 IN AFSDirectoryCB *DirectoryCB,
1138 IN OUT PFILE_NAME_INFORMATION Buffer,
1139 IN OUT PLONG Length)
1142 NTSTATUS ntStatus = STATUS_SUCCESS;
1143 ULONG ulCopyLength = 0;
1144 ULONG cchCopied = 0;
1145 AFSFcb *pFcb = NULL;
1146 AFSCcb *pCcb = NULL;
1147 IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1148 BOOLEAN bAddLeadingSlash = FALSE;
1149 BOOLEAN bAddTrailingSlash = FALSE;
1150 USHORT usFullNameLength = 0;
1152 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
1154 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
1156 if( *Length >= FIELD_OFFSET( FILE_NAME_INFORMATION, FileName))
1159 RtlZeroMemory( Buffer,
1162 if( pCcb->FullFileName.Length == 0 ||
1163 pCcb->FullFileName.Buffer[ 0] != L'\\')
1165 bAddLeadingSlash = TRUE;
1168 if( pFcb->ObjectInformation->FileType == AFS_FILE_TYPE_DIRECTORY &&
1169 pCcb->FullFileName.Length > 0 &&
1170 pCcb->FullFileName.Buffer[ (pCcb->FullFileName.Length/sizeof( WCHAR)) - 1] != L'\\')
1172 bAddTrailingSlash = TRUE;
1175 usFullNameLength = sizeof( WCHAR) +
1176 AFSServerName.Length +
1177 pCcb->FullFileName.Length;
1179 if( bAddLeadingSlash)
1181 usFullNameLength += sizeof( WCHAR);
1184 if( bAddTrailingSlash)
1186 usFullNameLength += sizeof( WCHAR);
1189 if( *Length >= (LONG)(FIELD_OFFSET( FILE_NAME_INFORMATION, FileName) + (LONG)usFullNameLength))
1192 ulCopyLength = (LONG)usFullNameLength;
1197 ulCopyLength = *Length - FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
1199 ntStatus = STATUS_BUFFER_OVERFLOW;
1202 Buffer->FileNameLength = (ULONG)usFullNameLength;
1204 *Length -= FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
1206 if( ulCopyLength > 0)
1209 Buffer->FileName[ 0] = L'\\';
1210 ulCopyLength -= sizeof( WCHAR);
1212 *Length -= sizeof( WCHAR);
1215 if( ulCopyLength >= AFSServerName.Length)
1218 RtlCopyMemory( &Buffer->FileName[ 1],
1219 AFSServerName.Buffer,
1220 AFSServerName.Length);
1222 ulCopyLength -= AFSServerName.Length;
1223 *Length -= AFSServerName.Length;
1224 cchCopied += AFSServerName.Length/sizeof( WCHAR);
1226 if ( ulCopyLength > 0 &&
1230 Buffer->FileName[ cchCopied] = L'\\';
1232 ulCopyLength -= sizeof( WCHAR);
1233 *Length -= sizeof( WCHAR);
1237 if( ulCopyLength >= pCcb->FullFileName.Length)
1240 RtlCopyMemory( &Buffer->FileName[ cchCopied],
1241 pCcb->FullFileName.Buffer,
1242 pCcb->FullFileName.Length);
1244 ulCopyLength -= pCcb->FullFileName.Length;
1245 *Length -= pCcb->FullFileName.Length;
1246 cchCopied += pCcb->FullFileName.Length/sizeof( WCHAR);
1248 if( ulCopyLength > 0 &&
1251 Buffer->FileName[ cchCopied] = L'\\';
1253 *Length -= sizeof( WCHAR);
1259 RtlCopyMemory( &Buffer->FileName[ cchCopied],
1260 pCcb->FullFileName.Buffer,
1263 *Length -= ulCopyLength;
1271 ntStatus = STATUS_BUFFER_TOO_SMALL;
1278 AFSQueryShortNameInfo( IN PIRP Irp,
1279 IN AFSDirectoryCB *DirectoryCB,
1280 IN OUT PFILE_NAME_INFORMATION Buffer,
1281 IN OUT PLONG Length)
1284 NTSTATUS ntStatus = STATUS_BUFFER_TOO_SMALL;
1285 ULONG ulCopyLength = 0;
1287 RtlZeroMemory( Buffer,
1290 if( DirectoryCB->NameInformation.ShortNameLength == 0)
1294 // The short name IS the long name
1297 if( *Length >= (LONG)FIELD_OFFSET( FILE_NAME_INFORMATION, FileName))
1300 if( *Length >= (LONG)(FIELD_OFFSET( FILE_NAME_INFORMATION, FileName) + (LONG)DirectoryCB->NameInformation.FileName.Length))
1303 ulCopyLength = (LONG)DirectoryCB->NameInformation.FileName.Length;
1305 ntStatus = STATUS_SUCCESS;
1310 ulCopyLength = *Length - FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
1312 ntStatus = STATUS_BUFFER_OVERFLOW;
1315 Buffer->FileNameLength = DirectoryCB->NameInformation.FileName.Length;
1317 *Length -= FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
1319 if( ulCopyLength > 0)
1322 RtlCopyMemory( Buffer->FileName,
1323 DirectoryCB->NameInformation.FileName.Buffer,
1326 *Length -= ulCopyLength;
1333 if( *Length >= (LONG)FIELD_OFFSET( FILE_NAME_INFORMATION, FileName))
1336 if( *Length >= (LONG)(FIELD_OFFSET( FILE_NAME_INFORMATION, FileName) + (LONG)DirectoryCB->NameInformation.FileName.Length))
1339 ulCopyLength = (LONG)DirectoryCB->NameInformation.ShortNameLength;
1341 ntStatus = STATUS_SUCCESS;
1346 ulCopyLength = *Length - FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
1348 ntStatus = STATUS_BUFFER_OVERFLOW;
1351 Buffer->FileNameLength = DirectoryCB->NameInformation.ShortNameLength;
1353 *Length -= FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
1355 if( ulCopyLength > 0)
1358 RtlCopyMemory( Buffer->FileName,
1359 DirectoryCB->NameInformation.ShortName,
1360 Buffer->FileNameLength);
1362 *Length -= ulCopyLength;
1371 AFSQueryNetworkInfo( IN PIRP Irp,
1372 IN AFSDirectoryCB *DirectoryCB,
1373 IN OUT PFILE_NETWORK_OPEN_INFORMATION Buffer,
1374 IN OUT PLONG Length)
1377 NTSTATUS ntStatus = STATUS_SUCCESS;
1378 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1379 AFSFcb *pFcb = NULL;
1380 AFSCcb *pCcb = NULL;
1381 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1382 AFSFileInfoCB stFileInfo;
1383 AFSDirectoryCB *pParentDirectoryCB = NULL;
1384 UNICODE_STRING uniParentPath;
1385 ULONG ulFileAttribs = 0;
1387 RtlZeroMemory( Buffer,
1390 if( *Length >= sizeof( FILE_NETWORK_OPEN_INFORMATION))
1393 ulFileAttribs = DirectoryCB->ObjectInformation->FileAttributes;
1395 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
1396 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
1398 if( DirectoryCB->ObjectInformation->FileType == AFS_FILE_TYPE_SYMLINK)
1401 pParentDirectoryCB = AFSGetParentEntry( pCcb->NameArray);
1403 AFSRetrieveParentPath( &pCcb->FullFileName,
1406 RtlZeroMemory( &stFileInfo,
1407 sizeof( AFSFileInfoCB));
1410 // Can't hold the Fcb while evaluating the path, leads to lock inversion
1413 AFSReleaseResource( &pFcb->NPFcb->Resource);
1415 if( NT_SUCCESS( AFSRetrieveFileAttributes( pParentDirectoryCB,
1422 ulFileAttribs = stFileInfo.FileAttributes;
1424 ulFileAttribs |= FILE_ATTRIBUTE_REPARSE_POINT;
1427 AFSAcquireShared( &pFcb->NPFcb->Resource,
1431 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1432 AFS_TRACE_LEVEL_VERBOSE_2,
1433 "AFSQueryNetworkInfo %wZ Type 0x%x Attrib 0x%x -> 0x%x\n",
1434 &pCcb->DirectoryCB->NameInformation.FileName,
1435 pCcb->DirectoryCB->ObjectInformation->FileType,
1436 pCcb->DirectoryCB->ObjectInformation->FileAttributes,
1439 Buffer->CreationTime.QuadPart = DirectoryCB->ObjectInformation->CreationTime.QuadPart;
1440 Buffer->LastAccessTime.QuadPart = DirectoryCB->ObjectInformation->LastAccessTime.QuadPart;
1441 Buffer->LastWriteTime.QuadPart = DirectoryCB->ObjectInformation->LastWriteTime.QuadPart;
1442 Buffer->ChangeTime.QuadPart = DirectoryCB->ObjectInformation->ChangeTime.QuadPart;
1444 Buffer->AllocationSize.QuadPart = DirectoryCB->ObjectInformation->AllocationSize.QuadPart;
1445 Buffer->EndOfFile.QuadPart = DirectoryCB->ObjectInformation->EndOfFile.QuadPart;
1447 Buffer->FileAttributes = ulFileAttribs;
1449 if( DirectoryCB->NameInformation.FileName.Buffer[ 0] == L'.' &&
1450 BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_HIDE_DOT_NAMES))
1453 if ( Buffer->FileAttributes != FILE_ATTRIBUTE_NORMAL)
1456 Buffer->FileAttributes |= FILE_ATTRIBUTE_HIDDEN;
1461 Buffer->FileAttributes = FILE_ATTRIBUTE_HIDDEN;
1465 *Length -= sizeof( FILE_NETWORK_OPEN_INFORMATION);
1470 ntStatus = STATUS_BUFFER_TOO_SMALL;
1477 AFSQueryStreamInfo( IN PIRP Irp,
1478 IN AFSDirectoryCB *DirectoryCB,
1479 IN OUT FILE_STREAM_INFORMATION *Buffer,
1480 IN OUT PLONG Length)
1483 NTSTATUS ntStatus = STATUS_BUFFER_TOO_SMALL;
1484 ULONG ulCopyLength = 0;
1485 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1487 if( *Length >= FIELD_OFFSET( FILE_STREAM_INFORMATION, StreamName))
1490 RtlZeroMemory( Buffer,
1493 Buffer->NextEntryOffset = 0;
1496 if( !BooleanFlagOn( DirectoryCB->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_DIRECTORY))
1499 if( *Length >= (LONG)(FIELD_OFFSET( FILE_STREAM_INFORMATION, StreamName) + 14)) // ::$DATA
1504 ntStatus = STATUS_SUCCESS;
1509 ulCopyLength = *Length - FIELD_OFFSET( FILE_STREAM_INFORMATION, StreamName);
1511 ntStatus = STATUS_BUFFER_OVERFLOW;
1514 Buffer->StreamNameLength = 14; // ::$DATA
1516 Buffer->StreamSize.QuadPart = DirectoryCB->ObjectInformation->EndOfFile.QuadPart;
1518 Buffer->StreamAllocationSize.QuadPart = DirectoryCB->ObjectInformation->AllocationSize.QuadPart;
1520 *Length -= FIELD_OFFSET( FILE_STREAM_INFORMATION, StreamName);
1522 if( ulCopyLength > 0)
1525 RtlCopyMemory( Buffer->StreamName,
1529 *Length -= ulCopyLength;
1535 Buffer->StreamNameLength = 0; // No stream for a directory
1537 // The response size is zero
1539 ntStatus = STATUS_SUCCESS;
1547 AFSQueryAttribTagInfo( IN PIRP Irp,
1548 IN AFSDirectoryCB *DirectoryCB,
1549 IN OUT FILE_ATTRIBUTE_TAG_INFORMATION *Buffer,
1550 IN OUT PLONG Length)
1553 NTSTATUS ntStatus = STATUS_BUFFER_TOO_SMALL;
1554 ULONG ulCopyLength = 0;
1555 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1556 AFSFcb *pFcb = NULL;
1557 AFSCcb *pCcb = NULL;
1558 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1559 AFSFileInfoCB stFileInfo;
1560 AFSDirectoryCB *pParentDirectoryCB = NULL;
1561 UNICODE_STRING uniParentPath;
1562 ULONG ulFileAttribs = 0;
1564 if( *Length >= sizeof( FILE_ATTRIBUTE_TAG_INFORMATION))
1567 RtlZeroMemory( Buffer,
1570 ulFileAttribs = DirectoryCB->ObjectInformation->FileAttributes;
1572 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
1573 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
1575 if( DirectoryCB->ObjectInformation->FileType == AFS_FILE_TYPE_SYMLINK)
1578 pParentDirectoryCB = AFSGetParentEntry( pCcb->NameArray);
1580 AFSRetrieveParentPath( &pCcb->FullFileName,
1583 RtlZeroMemory( &stFileInfo,
1584 sizeof( AFSFileInfoCB));
1587 // Can't hold the Fcb while evaluating the path, leads to lock inversion
1590 AFSReleaseResource( &pFcb->NPFcb->Resource);
1592 if( NT_SUCCESS( AFSRetrieveFileAttributes( pParentDirectoryCB,
1599 ulFileAttribs = stFileInfo.FileAttributes;
1601 ulFileAttribs |= FILE_ATTRIBUTE_REPARSE_POINT;
1604 AFSAcquireShared( &pFcb->NPFcb->Resource,
1608 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1609 AFS_TRACE_LEVEL_VERBOSE_2,
1610 "AFSAttribTagInfo %wZ Type 0x%x Attrib 0x%x -> 0x%x\n",
1611 &pCcb->DirectoryCB->NameInformation.FileName,
1612 pCcb->DirectoryCB->ObjectInformation->FileType,
1613 pCcb->DirectoryCB->ObjectInformation->FileAttributes,
1616 Buffer->FileAttributes = ulFileAttribs;
1618 if( DirectoryCB->NameInformation.FileName.Buffer[ 0] == L'.' &&
1619 BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_HIDE_DOT_NAMES))
1622 if ( Buffer->FileAttributes != FILE_ATTRIBUTE_NORMAL)
1625 Buffer->FileAttributes |= FILE_ATTRIBUTE_HIDDEN;
1630 Buffer->FileAttributes = FILE_ATTRIBUTE_HIDDEN;
1634 if( BooleanFlagOn( DirectoryCB->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_REPARSE_POINT))
1636 Buffer->ReparseTag = IO_REPARSE_TAG_SURROGATE|IO_REPARSE_TAG_OPENAFS_DFS;
1639 *Length -= sizeof( FILE_ATTRIBUTE_TAG_INFORMATION);
1641 ntStatus = STATUS_SUCCESS;
1648 AFSQueryRemoteProtocolInfo( IN PIRP Irp,
1649 IN AFSDirectoryCB *DirectoryCB,
1650 IN OUT FILE_REMOTE_PROTOCOL_INFORMATION *Buffer,
1651 IN OUT PLONG Length)
1654 NTSTATUS ntStatus = STATUS_BUFFER_TOO_SMALL;
1655 ULONG ulCopyLength = 0;
1656 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1658 if( *Length >= sizeof( FILE_REMOTE_PROTOCOL_INFORMATION))
1661 RtlZeroMemory( Buffer,
1664 Buffer->StructureVersion = 1;
1666 Buffer->StructureSize = sizeof(FILE_REMOTE_PROTOCOL_INFORMATION);
1668 Buffer->Protocol = WNNC_NET_OPENAFS;
1670 Buffer->ProtocolMajorVersion = 3;
1672 Buffer->ProtocolMinorVersion = 0;
1674 Buffer->ProtocolRevision = 0;
1676 *Length -= sizeof( FILE_REMOTE_PROTOCOL_INFORMATION);
1678 ntStatus = STATUS_SUCCESS;
1685 AFSQueryPhysicalNameInfo( IN PIRP Irp,
1686 IN AFSDirectoryCB *DirectoryCB,
1687 IN OUT PFILE_NETWORK_PHYSICAL_NAME_INFORMATION Buffer,
1688 IN OUT PLONG Length)
1691 NTSTATUS ntStatus = STATUS_SUCCESS;
1692 ULONG ulCopyLength = 0;
1693 ULONG cchCopied = 0;
1694 AFSFcb *pFcb = NULL;
1695 AFSCcb *pCcb = NULL;
1696 IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1697 BOOLEAN bAddLeadingSlash = FALSE;
1698 USHORT usFullNameLength = 0;
1700 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
1702 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
1704 if( *Length >= FIELD_OFFSET( FILE_NETWORK_PHYSICAL_NAME_INFORMATION, FileName))
1707 RtlZeroMemory( Buffer,
1710 if( pCcb->FullFileName.Length == 0 ||
1711 pCcb->FullFileName.Buffer[ 0] != L'\\')
1713 bAddLeadingSlash = TRUE;
1716 usFullNameLength = pCcb->FullFileName.Length;
1718 if( bAddLeadingSlash)
1720 usFullNameLength += sizeof( WCHAR);
1723 if( *Length >= (LONG)(FIELD_OFFSET( FILE_NETWORK_PHYSICAL_NAME_INFORMATION, FileName) + (LONG)usFullNameLength))
1725 ulCopyLength = (LONG)usFullNameLength;
1730 ulCopyLength = *Length - FIELD_OFFSET( FILE_NETWORK_PHYSICAL_NAME_INFORMATION, FileName);
1732 ntStatus = STATUS_BUFFER_OVERFLOW;
1735 Buffer->FileNameLength = (ULONG)usFullNameLength;
1737 *Length -= FIELD_OFFSET( FILE_NETWORK_PHYSICAL_NAME_INFORMATION, FileName);
1739 if( ulCopyLength > 0)
1742 if( bAddLeadingSlash)
1745 Buffer->FileName[ cchCopied] = L'\\';
1747 ulCopyLength -= sizeof( WCHAR);
1748 *Length -= sizeof( WCHAR);
1752 if( ulCopyLength >= pCcb->FullFileName.Length)
1755 RtlCopyMemory( &Buffer->FileName[ cchCopied],
1756 pCcb->FullFileName.Buffer,
1757 pCcb->FullFileName.Length);
1759 ulCopyLength -= pCcb->FullFileName.Length;
1760 *Length -= pCcb->FullFileName.Length;
1761 cchCopied += pCcb->FullFileName.Length/sizeof( WCHAR);
1766 RtlCopyMemory( &Buffer->FileName[ cchCopied],
1767 pCcb->FullFileName.Buffer,
1770 *Length -= ulCopyLength;
1777 ntStatus = STATUS_BUFFER_TOO_SMALL;
1784 AFSSetBasicInfo( IN PIRP Irp,
1785 IN AFSDirectoryCB *DirectoryCB)
1787 NTSTATUS ntStatus = STATUS_SUCCESS;
1788 PFILE_BASIC_INFORMATION pBuffer;
1789 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1790 ULONG ulNotifyFilter = 0;
1791 AFSCcb *pCcb = NULL;
1796 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
1798 pBuffer = (PFILE_BASIC_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
1800 pCcb->FileUnwindInfo.FileAttributes = (ULONG)-1;
1802 if( pBuffer->FileAttributes != (ULONGLONG)0)
1805 if( DirectoryCB->ObjectInformation->Fcb->Header.NodeTypeCode == AFS_FILE_FCB &&
1806 BooleanFlagOn( pBuffer->FileAttributes, FILE_ATTRIBUTE_DIRECTORY))
1809 try_return( ntStatus = STATUS_INVALID_PARAMETER);
1812 if( DirectoryCB->ObjectInformation->Fcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB)
1815 pBuffer->FileAttributes |= FILE_ATTRIBUTE_DIRECTORY;
1818 pCcb->FileUnwindInfo.FileAttributes = DirectoryCB->ObjectInformation->FileAttributes;
1820 DirectoryCB->ObjectInformation->FileAttributes = pBuffer->FileAttributes;
1822 ulNotifyFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
1824 SetFlag( DirectoryCB->ObjectInformation->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED);
1827 pCcb->FileUnwindInfo.CreationTime.QuadPart = (ULONGLONG)-1;
1829 if( pBuffer->CreationTime.QuadPart != (ULONGLONG)-1 &&
1830 pBuffer->CreationTime.QuadPart != (ULONGLONG)0)
1833 pCcb->FileUnwindInfo.CreationTime.QuadPart = DirectoryCB->ObjectInformation->CreationTime.QuadPart;
1835 DirectoryCB->ObjectInformation->CreationTime.QuadPart = pBuffer->CreationTime.QuadPart;
1837 ulNotifyFilter |= FILE_NOTIFY_CHANGE_CREATION;
1839 SetFlag( DirectoryCB->ObjectInformation->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_CREATE_TIME);
1842 pCcb->FileUnwindInfo.LastAccessTime.QuadPart = (ULONGLONG)-1;
1844 if( pBuffer->LastAccessTime.QuadPart != (ULONGLONG)-1 &&
1845 pBuffer->LastAccessTime.QuadPart != (ULONGLONG)0)
1848 pCcb->FileUnwindInfo.LastAccessTime.QuadPart = DirectoryCB->ObjectInformation->LastAccessTime.QuadPart;
1850 DirectoryCB->ObjectInformation->LastAccessTime.QuadPart = pBuffer->LastAccessTime.QuadPart;
1852 ulNotifyFilter |= FILE_NOTIFY_CHANGE_LAST_ACCESS;
1854 SetFlag( DirectoryCB->ObjectInformation->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_ACCESS_TIME);
1857 pCcb->FileUnwindInfo.LastWriteTime.QuadPart = (ULONGLONG)-1;
1859 if( pBuffer->LastWriteTime.QuadPart != (ULONGLONG)-1 &&
1860 pBuffer->LastWriteTime.QuadPart != (ULONGLONG)0)
1863 pCcb->FileUnwindInfo.LastWriteTime.QuadPart = DirectoryCB->ObjectInformation->LastWriteTime.QuadPart;
1865 DirectoryCB->ObjectInformation->LastWriteTime.QuadPart = pBuffer->LastWriteTime.QuadPart;
1867 ulNotifyFilter |= FILE_NOTIFY_CHANGE_LAST_WRITE;
1869 SetFlag( DirectoryCB->ObjectInformation->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_LAST_WRITE_TIME);
1872 pCcb->FileUnwindInfo.ChangeTime.QuadPart = (ULONGLONG)-1;
1874 if( pBuffer->ChangeTime.QuadPart != (ULONGLONG)-1 &&
1875 pBuffer->ChangeTime.QuadPart != (ULONGLONG)0)
1878 pCcb->FileUnwindInfo.ChangeTime.QuadPart = DirectoryCB->ObjectInformation->ChangeTime.QuadPart;
1880 DirectoryCB->ObjectInformation->ChangeTime.QuadPart = pBuffer->ChangeTime.QuadPart;
1882 ulNotifyFilter |= FILE_NOTIFY_CHANGE_LAST_ACCESS;
1884 SetFlag( DirectoryCB->ObjectInformation->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_CHANGE_TIME);
1887 if( ulNotifyFilter > 0)
1890 if( DirectoryCB->ObjectInformation->ParentObjectInformation != NULL)
1893 AFSFsRtlNotifyFullReportChange( DirectoryCB->ObjectInformation->ParentObjectInformation,
1895 (ULONG)ulNotifyFilter,
1896 (ULONG)FILE_ACTION_MODIFIED);
1909 AFSSetDispositionInfo( IN PIRP Irp,
1910 IN AFSDirectoryCB *DirectoryCB)
1912 NTSTATUS ntStatus = STATUS_SUCCESS;
1913 PFILE_DISPOSITION_INFORMATION pBuffer;
1914 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1915 AFSFcb *pFcb = NULL;
1916 AFSCcb *pCcb = NULL;
1921 pBuffer = (PFILE_DISPOSITION_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
1923 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
1925 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
1928 // Can't delete the root
1931 if( pFcb->Header.NodeTypeCode == AFS_ROOT_FCB)
1934 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1935 AFS_TRACE_LEVEL_ERROR,
1936 "AFSSetDispositionInfo Attempt to delete root entry\n");
1938 try_return( ntStatus = STATUS_CANNOT_DELETE);
1942 // If the file is read only then do not allow the delete
1945 if( BooleanFlagOn( DirectoryCB->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_READONLY))
1948 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1949 AFS_TRACE_LEVEL_ERROR,
1950 "AFSSetDispositionInfo Attempt to delete read only entry %wZ\n",
1951 &DirectoryCB->NameInformation.FileName);
1953 try_return( ntStatus = STATUS_CANNOT_DELETE);
1956 if( pBuffer->DeleteFile)
1960 // Check if the caller can delete the file
1963 ntStatus = AFSNotifyDelete( DirectoryCB,
1967 if( !NT_SUCCESS( ntStatus))
1970 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1971 AFS_TRACE_LEVEL_ERROR,
1972 "AFSSetDispositionInfo Cannot delete entry %wZ Status %08lX\n",
1973 &DirectoryCB->NameInformation.FileName,
1976 try_return( ntStatus);
1979 if( pFcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB)
1983 // Check if this is a directory that there are not currently other opens
1986 if( pFcb->ObjectInformation->Specific.Directory.ChildOpenHandleCount > 0)
1989 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1990 AFS_TRACE_LEVEL_ERROR,
1991 "AFSSetDispositionInfo Attempt to delete directory %wZ with open %u handles\n",
1992 &DirectoryCB->NameInformation.FileName,
1993 pFcb->ObjectInformation->Specific.Directory.ChildOpenHandleCount);
1995 try_return( ntStatus = STATUS_DIRECTORY_NOT_EMPTY);
1998 if( !AFSIsDirectoryEmptyForDelete( pFcb))
2001 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2002 AFS_TRACE_LEVEL_ERROR,
2003 "AFSSetDispositionInfo Attempt to delete non-empty directory %wZ\n",
2004 &DirectoryCB->NameInformation.FileName);
2006 try_return( ntStatus = STATUS_DIRECTORY_NOT_EMPTY);
2009 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2010 AFS_TRACE_LEVEL_VERBOSE,
2011 "AFSSetDispositionInfo Setting PENDING_DELETE on DirEntry %p Name %wZ\n",
2013 &DirectoryCB->NameInformation.FileName);
2015 SetFlag( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
2017 else if( pFcb->Header.NodeTypeCode == AFS_FILE_FCB)
2021 // Attempt to flush any outstanding data
2024 if( !MmFlushImageSection( &pFcb->NPFcb->SectionObjectPointers,
2028 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2029 AFS_TRACE_LEVEL_ERROR,
2030 "AFSSetDispositionInfo Failed to flush image section for delete Entry %wZ\n",
2031 &DirectoryCB->NameInformation.FileName);
2033 try_return( ntStatus = STATUS_CANNOT_DELETE);
2037 // Set PENDING_DELETE before CcPurgeCacheSection to avoid a
2038 // deadlock with Trend Micro's Enterprise anti-virus product
2039 // which attempts to open the file which is being deleted.
2042 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2043 AFS_TRACE_LEVEL_VERBOSE,
2044 "AFSSetDispositionInfo Setting PENDING_DELETE on DirEntry %p Name %wZ\n",
2046 &DirectoryCB->NameInformation.FileName);
2048 SetFlag( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
2051 // Purge the cache as well
2054 if( pFcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
2057 if ( !CcPurgeCacheSection( &pFcb->NPFcb->SectionObjectPointers,
2063 SetFlag( pFcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
2071 ClearFlag( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
2075 // OK, should be good to go, set the flag in the file object
2078 pIrpSp->FileObject->DeletePending = pBuffer->DeleteFile;
2089 AFSSetRenameInfo( IN PIRP Irp)
2092 NTSTATUS ntStatus = STATUS_SUCCESS;
2093 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
2094 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2095 IO_STATUS_BLOCK stIoSb = {0,0};
2096 AFSFcb *pSrcFcb = NULL, *pTargetDcb = NULL, *pTargetFcb = NULL;
2097 AFSCcb *pSrcCcb = NULL, *pTargetDirCcb = NULL;
2098 PFILE_OBJECT pSrcFileObj = pIrpSp->FileObject;
2099 PFILE_OBJECT pTargetFileObj = pIrpSp->Parameters.SetFile.FileObject;
2100 PFILE_RENAME_INFORMATION pRenameInfo = NULL;
2101 UNICODE_STRING uniTargetName, uniSourceName;
2102 BOOLEAN bReplaceIfExists = FALSE;
2103 UNICODE_STRING uniShortName;
2104 AFSDirectoryCB *pTargetDirEntry = NULL;
2105 ULONG ulTargetCRC = 0;
2106 BOOLEAN bTargetEntryExists = FALSE;
2107 AFSObjectInfoCB *pSrcObject = NULL, *pTargetObject = NULL;
2108 AFSObjectInfoCB *pSrcParentObject = NULL, *pTargetParentObject = NULL;
2109 AFSFileID stNewFid, stTmpTargetFid;
2110 ULONG ulNotificationAction = 0, ulNotifyFilter = 0;
2111 UNICODE_STRING uniFullTargetPath;
2112 BOOLEAN bCommonParent = FALSE;
2113 BOOLEAN bReleaseTargetDirLock = FALSE;
2114 BOOLEAN bReleaseSourceDirLock = FALSE;
2115 PERESOURCE pSourceDirLock = NULL;
2121 bReplaceIfExists = pIrpSp->Parameters.SetFile.ReplaceIfExists;
2123 pSrcFcb = (AFSFcb *)pSrcFileObj->FsContext;
2124 pSrcCcb = (AFSCcb *)pSrcFileObj->FsContext2;
2126 pSrcObject = pSrcFcb->ObjectInformation;
2127 pSrcParentObject = pSrcFcb->ObjectInformation->ParentObjectInformation;
2130 // Perform some basic checks to ensure FS integrity
2133 if( pSrcFcb->Header.NodeTypeCode == AFS_ROOT_FCB)
2137 // Can't rename the root directory
2140 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2141 AFS_TRACE_LEVEL_ERROR,
2142 "AFSSetRenameInfo Attempt to rename root entry\n");
2144 try_return( ntStatus = STATUS_INVALID_PARAMETER);
2147 if( pSrcFcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB)
2151 // If there are any open children then fail the rename
2154 if( pSrcFcb->ObjectInformation->Specific.Directory.ChildOpenHandleCount > 0)
2157 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2158 AFS_TRACE_LEVEL_ERROR,
2159 "AFSSetRenameInfo Attempt to rename directory with open children %wZ\n",
2160 &pSrcCcb->DirectoryCB->NameInformation.FileName);
2162 try_return( ntStatus = STATUS_ACCESS_DENIED);
2167 // Extract off the final component name from the Fcb
2170 uniSourceName.Length = (USHORT)pSrcCcb->DirectoryCB->NameInformation.FileName.Length;
2171 uniSourceName.MaximumLength = uniSourceName.Length;
2173 uniSourceName.Buffer = pSrcCcb->DirectoryCB->NameInformation.FileName.Buffer;
2176 // Resolve the target fileobject
2179 if( pTargetFileObj == NULL)
2183 // This is a simple rename. Here the target directory is the same as the source parent directory
2184 // and the name is retrieved from the system buffer information
2187 pRenameInfo = (PFILE_RENAME_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
2189 pTargetParentObject = pSrcParentObject;
2191 pTargetDcb = pTargetParentObject->Fcb;
2193 uniTargetName.Length = (USHORT)pRenameInfo->FileNameLength;
2194 uniTargetName.Buffer = (PWSTR)&pRenameInfo->FileName;
2200 // So here we have the target directory taken from the targetfile object
2203 pTargetDcb = (AFSFcb *)pTargetFileObj->FsContext;
2205 pTargetDirCcb = (AFSCcb *)pTargetFileObj->FsContext2;
2207 pTargetParentObject = (AFSObjectInfoCB *)pTargetDcb->ObjectInformation;
2210 // Grab the target name which we setup in the IRP_MJ_CREATE handler. By how we set this up
2211 // it is only the target component of the rename operation
2214 uniTargetName = *((PUNICODE_STRING)&pTargetFileObj->FileName);
2218 // The quick check to see if they are not really performing a rename
2219 // Do the names match? Only do this where the parent directories are
2223 if( pTargetParentObject == pSrcParentObject)
2226 if( FsRtlAreNamesEqual( &uniTargetName,
2231 try_return( ntStatus = STATUS_SUCCESS);
2234 bCommonParent = TRUE;
2239 bCommonParent = FALSE;
2243 // We do not allow cross-volume renames to occur
2246 if( pTargetParentObject->VolumeCB != pSrcObject->VolumeCB)
2249 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2250 AFS_TRACE_LEVEL_ERROR,
2251 "AFSSetRenameInfo Attempt to rename directory to different volume %wZ\n",
2252 &pSrcCcb->DirectoryCB->NameInformation.FileName);
2254 try_return( ntStatus = STATUS_NOT_SAME_DEVICE);
2257 ulTargetCRC = AFSGenerateCRC( &uniTargetName,
2260 AFSAcquireExcl( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock,
2263 bReleaseTargetDirLock = TRUE;
2265 if( pTargetParentObject != pSrcParentObject)
2267 AFSAcquireExcl( pSrcParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock,
2270 bReleaseSourceDirLock = TRUE;
2272 pSourceDirLock = pSrcParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock;
2275 AFSLocateCaseSensitiveDirEntry( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
2279 if( pTargetDirEntry == NULL)
2283 // Missed so perform a case insensitive lookup
2286 ulTargetCRC = AFSGenerateCRC( &uniTargetName,
2289 AFSLocateCaseInsensitiveDirEntry( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
2294 if ( !BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
2295 pTargetDirEntry == NULL && RtlIsNameLegalDOS8Dot3( &uniTargetName,
2300 // Try the short name
2302 AFSLocateShortNameDirEntry( pTargetParentObject->Specific.Directory.ShortNameTree,
2308 // Increment our ref count on the dir entry
2311 if( pTargetDirEntry != NULL)
2314 ASSERT( pTargetParentObject == pTargetDirEntry->ObjectInformation->ParentObjectInformation);
2316 lCount = InterlockedIncrement( &pTargetDirEntry->OpenReferenceCount);
2318 if( !bReplaceIfExists)
2321 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2322 AFS_TRACE_LEVEL_ERROR,
2323 "AFSSetRenameInfo Attempt to rename directory with target collision %wZ Target %wZ\n",
2324 &pSrcCcb->DirectoryCB->NameInformation.FileName,
2325 &pTargetDirEntry->NameInformation.FileName);
2327 try_return( ntStatus = STATUS_OBJECT_NAME_COLLISION);
2330 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2331 AFS_TRACE_LEVEL_ERROR,
2332 "AFSSetRenameInfo Target %wZ exists DE %p Count %08lX, performing delete of target\n",
2333 &pTargetDirEntry->NameInformation.FileName,
2335 pTargetDirEntry->OpenReferenceCount);
2338 // Pull the directory entry from the parent
2341 AFSRemoveDirNodeFromParent( pTargetParentObject,
2345 bTargetEntryExists = TRUE;
2349 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2350 AFS_TRACE_LEVEL_VERBOSE,
2351 "AFSSetRenameInfo Target does NOT exist, normal rename\n");
2355 // We need to remove the DirEntry from the parent node, update the index
2356 // and reinsert it into the parent tree. Note that for entries with the
2357 // same parent we do not pull the node from the enumeration list
2360 AFSRemoveDirNodeFromParent( pSrcFcb->ObjectInformation->ParentObjectInformation,
2361 pSrcCcb->DirectoryCB,
2365 // OK, this is a simple rename. Issue the rename
2366 // request to the service.
2369 ntStatus = AFSNotifyRename( pSrcFcb->ObjectInformation,
2370 &pSrcCcb->AuthGroup,
2371 pSrcFcb->ObjectInformation->ParentObjectInformation,
2372 pTargetDcb->ObjectInformation,
2373 pSrcCcb->DirectoryCB,
2377 if( !NT_SUCCESS( ntStatus))
2381 // Attempt to re-insert the directory entry
2384 AFSInsertDirectoryNode( pSrcFcb->ObjectInformation->ParentObjectInformation,
2385 pSrcCcb->DirectoryCB,
2388 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2389 AFS_TRACE_LEVEL_ERROR,
2390 "AFSSetRenameInfo Failed rename of %wZ to target %wZ Status %08lX\n",
2391 &pSrcCcb->DirectoryCB->NameInformation.FileName,
2395 try_return( ntStatus);
2399 // Set the notification up for the source file
2402 if( pSrcCcb->DirectoryCB->ObjectInformation->ParentObjectInformation == pTargetParentObject &&
2403 !bTargetEntryExists)
2406 ulNotificationAction = FILE_ACTION_RENAMED_OLD_NAME;
2411 ulNotificationAction = FILE_ACTION_REMOVED;
2414 if( pSrcCcb->DirectoryCB->ObjectInformation->FileType == AFS_FILE_TYPE_DIRECTORY)
2417 ulNotifyFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
2422 ulNotifyFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
2425 AFSFsRtlNotifyFullReportChange( pSrcCcb->DirectoryCB->ObjectInformation->ParentObjectInformation,
2427 (ULONG)ulNotifyFilter,
2428 (ULONG)ulNotificationAction);
2431 // Update the name in the dir entry.
2434 ntStatus = AFSUpdateDirEntryName( pSrcCcb->DirectoryCB,
2437 if( !NT_SUCCESS( ntStatus))
2441 // Attempt to re-insert the directory entry
2444 AFSInsertDirectoryNode( pSrcFcb->ObjectInformation->ParentObjectInformation,
2445 pSrcCcb->DirectoryCB,
2448 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2449 AFS_TRACE_LEVEL_ERROR,
2450 "AFSSetRenameInfo Failed update of dir entry %wZ to target %wZ Status %08lX\n",
2451 &pSrcCcb->DirectoryCB->NameInformation.FileName,
2455 try_return( ntStatus);
2459 // Update the object information block, if needed
2462 if( !AFSIsEqualFID( &pSrcObject->FileId,
2466 AFSAcquireExcl( pSrcObject->VolumeCB->ObjectInfoTree.TreeLock,
2470 // Remove the old information entry
2473 AFSRemoveHashEntry( &pSrcObject->VolumeCB->ObjectInfoTree.TreeHead,
2474 &pSrcObject->TreeEntry);
2476 RtlCopyMemory( &pSrcObject->FileId,
2478 sizeof( AFSFileID));
2481 // Insert the entry into the new object table.
2484 pSrcObject->TreeEntry.HashIndex = AFSCreateLowIndex( &pSrcObject->FileId);
2486 if( pSrcObject->VolumeCB->ObjectInfoTree.TreeHead == NULL)
2489 pSrcObject->VolumeCB->ObjectInfoTree.TreeHead = &pSrcObject->TreeEntry;
2494 if ( !NT_SUCCESS( AFSInsertHashEntry( pSrcObject->VolumeCB->ObjectInfoTree.TreeHead,
2495 &pSrcObject->TreeEntry)))
2499 // Lost a race, an ObjectInfo object already exists for this FID.
2500 // Let this copy be garbage collected.
2503 ClearFlag( pSrcObject->Flags, AFS_OBJECT_INSERTED_HASH_TREE);
2507 AFSReleaseResource( pSrcObject->VolumeCB->ObjectInfoTree.TreeLock);
2511 // Update the hash values for the name trees.
2514 pSrcCcb->DirectoryCB->CaseSensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pSrcCcb->DirectoryCB->NameInformation.FileName,
2517 pSrcCcb->DirectoryCB->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pSrcCcb->DirectoryCB->NameInformation.FileName,
2520 if( !BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
2521 pSrcCcb->DirectoryCB->NameInformation.ShortNameLength > 0 &&
2522 !RtlIsNameLegalDOS8Dot3( &pSrcCcb->DirectoryCB->NameInformation.FileName,
2527 uniShortName.Length = pSrcCcb->DirectoryCB->NameInformation.ShortNameLength;
2528 uniShortName.MaximumLength = uniShortName.Length;
2529 uniShortName.Buffer = pSrcCcb->DirectoryCB->NameInformation.ShortName;
2531 pSrcCcb->DirectoryCB->Type.Data.ShortNameTreeEntry.HashIndex = AFSGenerateCRC( &uniShortName,
2534 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2535 AFS_TRACE_LEVEL_VERBOSE,
2536 "AFSSetRenameInfo Initialized short name hash for %wZ longname %wZ\n",
2538 &pSrcCcb->DirectoryCB->NameInformation.FileName);
2543 pSrcCcb->DirectoryCB->Type.Data.ShortNameTreeEntry.HashIndex = 0;
2550 // Update the file index for the object in the new parent
2553 pSrcCcb->DirectoryCB->FileIndex = (ULONG)InterlockedIncrement( &pTargetParentObject->Specific.Directory.DirectoryNodeHdr.ContentIndex);
2557 // Re-insert the directory entry
2560 AFSInsertDirectoryNode( pTargetParentObject,
2561 pSrcCcb->DirectoryCB,
2565 // Update the parent pointer in the source object if they are different
2568 if( pSrcCcb->DirectoryCB->ObjectInformation->ParentObjectInformation != pTargetParentObject)
2571 lCount = InterlockedDecrement( &pSrcCcb->DirectoryCB->ObjectInformation->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);
2573 lCount = InterlockedDecrement( &pSrcCcb->DirectoryCB->ObjectInformation->ParentObjectInformation->Specific.Directory.ChildOpenReferenceCount);
2575 lCount = InterlockedIncrement( &pTargetParentObject->Specific.Directory.ChildOpenHandleCount);
2577 lCount = InterlockedIncrement( &pTargetParentObject->Specific.Directory.ChildOpenReferenceCount);
2579 pSrcCcb->DirectoryCB->ObjectInformation->ParentObjectInformation = pTargetParentObject;
2581 ulNotificationAction = FILE_ACTION_ADDED;
2586 ulNotificationAction = FILE_ACTION_RENAMED_NEW_NAME;
2590 // Now update the notification for the target file
2593 AFSFsRtlNotifyFullReportChange( pTargetParentObject->ParentObjectInformation,
2595 (ULONG)ulNotifyFilter,
2596 (ULONG)ulNotificationAction);
2599 // If we performed the rename of the target because it existed, we now need to
2600 // delete the tmp target we created above
2603 if( bTargetEntryExists)
2606 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2607 AFS_TRACE_LEVEL_VERBOSE,
2608 "AFSSetRenameInfo Setting DELETE flag in dir entry %p name %wZ\n",
2610 &pTargetDirEntry->NameInformation.FileName);
2612 SetFlag( pTargetDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
2615 // Try and purge the cache map if this is a file
2618 if( pTargetDirEntry->ObjectInformation->FileType == AFS_FILE_TYPE_FILE &&
2619 pTargetDirEntry->ObjectInformation->Fcb != NULL &&
2620 pTargetDirEntry->OpenReferenceCount > 1)
2623 pTargetFcb = pTargetDirEntry->ObjectInformation->Fcb;
2625 AFSAcquireExcl( &pTargetFcb->NPFcb->Resource,
2629 // Close the section in the event it was mapped
2632 if( !MmForceSectionClosed( &pTargetFcb->NPFcb->SectionObjectPointers,
2636 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2637 AFS_TRACE_LEVEL_ERROR,
2638 "AFSSetRenameInfo Failed to delete section for target file %wZ\n",
2639 &pTargetDirEntry->NameInformation.FileName);
2642 AFSReleaseResource( &pTargetFcb->NPFcb->Resource);
2645 ASSERT( pTargetDirEntry->OpenReferenceCount > 0);
2647 lCount = InterlockedDecrement( &pTargetDirEntry->OpenReferenceCount); // The count we added above
2652 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2653 AFS_TRACE_LEVEL_VERBOSE,
2654 "AFSSetRenameInfo Deleting dir entry %p name %wZ\n",
2656 &pTargetDirEntry->NameInformation.FileName);
2658 AFSDeleteDirEntry( pTargetParentObject,
2662 pTargetDirEntry = NULL;
2668 if( !NT_SUCCESS( ntStatus))
2671 if( bTargetEntryExists)
2673 AFSInsertDirectoryNode( pTargetDirEntry->ObjectInformation->ParentObjectInformation,
2679 if( pTargetDirEntry != NULL)
2682 lCount = InterlockedDecrement( &pTargetDirEntry->OpenReferenceCount);
2685 if( bReleaseTargetDirLock)
2687 AFSReleaseResource( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
2690 if( bReleaseSourceDirLock)
2692 AFSReleaseResource( pSourceDirLock);
2700 AFSSetPositionInfo( IN PIRP Irp,
2701 IN AFSDirectoryCB *DirectoryCB)
2703 NTSTATUS ntStatus = STATUS_SUCCESS;
2704 PFILE_POSITION_INFORMATION pBuffer;
2705 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2707 pBuffer = (PFILE_POSITION_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
2709 pIrpSp->FileObject->CurrentByteOffset.QuadPart = pBuffer->CurrentByteOffset.QuadPart;
2715 AFSSetAllocationInfo( IN PIRP Irp,
2716 IN AFSDirectoryCB *DirectoryCB)
2718 NTSTATUS ntStatus = STATUS_SUCCESS;
2719 PFILE_ALLOCATION_INFORMATION pBuffer;
2720 BOOLEAN bReleasePaging = FALSE;
2721 BOOLEAN bTellCc = FALSE;
2722 BOOLEAN bTellService = FALSE;
2723 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2724 PFILE_OBJECT pFileObject = pIrpSp->FileObject;
2725 AFSFcb *pFcb = NULL;
2726 AFSCcb *pCcb = NULL;
2727 LARGE_INTEGER liSaveAlloc;
2728 LARGE_INTEGER liSaveFileSize;
2729 LARGE_INTEGER liSaveVDL;
2731 pBuffer = (PFILE_ALLOCATION_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
2733 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
2735 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
2738 // save values to put back
2740 liSaveAlloc = pFcb->Header.AllocationSize;
2741 liSaveFileSize = pFcb->Header.FileSize;
2742 liSaveVDL = pFcb->Header.ValidDataLength;
2744 if( pFcb->Header.AllocationSize.QuadPart == pBuffer->AllocationSize.QuadPart ||
2745 pIrpSp->Parameters.SetFile.AdvanceOnly)
2747 return STATUS_SUCCESS ;
2750 if( pFcb->Header.AllocationSize.QuadPart > pBuffer->AllocationSize.QuadPart)
2753 // Truncating the file
2755 if( !MmCanFileBeTruncated( pFileObject->SectionObjectPointer,
2756 &pBuffer->AllocationSize))
2759 ntStatus = STATUS_USER_MAPPED_FILE ;
2764 // If this is a truncation we need to grab the paging IO resource.
2767 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2768 AFS_TRACE_LEVEL_VERBOSE,
2769 "AFSSetAllocationInfo Acquiring Fcb PagingIo lock %08lX EXCL %08lX\n",
2770 &pFcb->NPFcb->PagingResource,
2771 PsGetCurrentThread());
2773 AFSAcquireExcl( &pFcb->NPFcb->PagingResource,
2776 bReleasePaging = TRUE;
2779 // Must drop the Fcb Resource. When changing the file size
2780 // a deadlock can occur with Trend Micro's filter if the file
2781 // size is set to zero.
2784 AFSReleaseResource( &pFcb->NPFcb->Resource);
2786 pFcb->Header.AllocationSize = pBuffer->AllocationSize;
2788 pFcb->ObjectInformation->AllocationSize = pBuffer->AllocationSize;
2791 // Tell Cc that Allocation is moved.
2795 if( pFcb->Header.FileSize.QuadPart > pBuffer->AllocationSize.QuadPart)
2798 // We are pulling the EOF back as well so we need to tell
2801 bTellService = TRUE;
2803 pFcb->Header.FileSize = pBuffer->AllocationSize;
2805 pFcb->ObjectInformation->EndOfFile = pBuffer->AllocationSize;
2813 // Tell Cc if allocation is increased.
2816 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2817 AFS_TRACE_LEVEL_VERBOSE,
2818 "AFSSetAllocationInfo Acquiring Fcb PagingIo lock %08lX EXCL %08lX\n",
2819 &pFcb->NPFcb->PagingResource,
2820 PsGetCurrentThread());
2822 AFSAcquireExcl( &pFcb->NPFcb->PagingResource,
2825 bReleasePaging = TRUE;
2828 // Must drop the Fcb Resource. When changing the file size
2829 // a deadlock can occur with Trend Micro's filter if the file
2830 // size is set to zero.
2833 AFSReleaseResource( &pFcb->NPFcb->Resource);
2835 bTellCc = pBuffer->AllocationSize.QuadPart > pFcb->Header.AllocationSize.QuadPart;
2837 pFcb->Header.AllocationSize = pBuffer->AllocationSize;
2839 pFcb->ObjectInformation->AllocationSize = pBuffer->AllocationSize;
2843 // Now Tell the server if we have to
2847 ntStatus = AFSUpdateFileInformation( &pFcb->ObjectInformation->ParentObjectInformation->FileId,
2848 pFcb->ObjectInformation,
2852 if (NT_SUCCESS(ntStatus))
2855 // Trim extents if we told the service - the update has done an implicit
2856 // trim at the service.
2860 AFSTrimExtents( pFcb,
2861 &pFcb->Header.FileSize);
2864 KeQuerySystemTime( &pFcb->ObjectInformation->ChangeTime);
2866 SetFlag( pFcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_CHANGE_TIME);
2869 CcIsFileCached( pFileObject))
2871 CcSetFileSizes( pFileObject,
2872 (PCC_FILE_SIZES)&pFcb->Header.AllocationSize);
2878 // Put the saved values back
2880 pFcb->Header.ValidDataLength = liSaveVDL;
2881 pFcb->Header.FileSize = liSaveFileSize;
2882 pFcb->Header.AllocationSize = liSaveAlloc;
2883 pFcb->ObjectInformation->EndOfFile = liSaveFileSize;
2884 pFcb->ObjectInformation->AllocationSize = liSaveAlloc;
2890 AFSReleaseResource( &pFcb->NPFcb->PagingResource);
2892 AFSAcquireExcl( &pFcb->NPFcb->Resource,
2900 AFSSetEndOfFileInfo( IN PIRP Irp,
2901 IN AFSDirectoryCB *DirectoryCB)
2903 NTSTATUS ntStatus = STATUS_SUCCESS;
2904 PFILE_END_OF_FILE_INFORMATION pBuffer;
2905 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2906 PFILE_OBJECT pFileObject = pIrpSp->FileObject;
2907 LARGE_INTEGER liSaveSize;
2908 LARGE_INTEGER liSaveVDL;
2909 LARGE_INTEGER liSaveAlloc;
2910 BOOLEAN bModified = FALSE;
2911 BOOLEAN bReleasePaging = FALSE;
2912 BOOLEAN bTruncated = FALSE;
2913 AFSFcb *pFcb = NULL;
2914 AFSCcb *pCcb = NULL;
2916 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
2918 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
2920 pBuffer = (PFILE_END_OF_FILE_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
2922 liSaveSize = pFcb->Header.FileSize;
2923 liSaveAlloc = pFcb->Header.AllocationSize;
2924 liSaveVDL = pFcb->Header.ValidDataLength;
2926 if( pFcb->Header.FileSize.QuadPart != pBuffer->EndOfFile.QuadPart &&
2927 !pIrpSp->Parameters.SetFile.AdvanceOnly)
2930 if( pBuffer->EndOfFile.QuadPart < pFcb->Header.FileSize.QuadPart)
2933 // Truncating the file
2934 if( !MmCanFileBeTruncated( pFileObject->SectionObjectPointer,
2935 &pBuffer->EndOfFile))
2938 ntStatus = STATUS_USER_MAPPED_FILE;
2944 // If this is a truncation we need to grab the paging
2947 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2948 AFS_TRACE_LEVEL_VERBOSE,
2949 "AFSSetAllocationInfo Acquiring Fcb PagingIo lock %08lX EXCL %08lX\n",
2950 &pFcb->NPFcb->PagingResource,
2951 PsGetCurrentThread());
2953 AFSAcquireExcl( &pFcb->NPFcb->PagingResource,
2956 bReleasePaging = TRUE;
2959 // Must drop the Fcb Resource. When changing the file size
2960 // a deadlock can occur with Trend Micro's filter if the file
2961 // size is set to zero.
2964 AFSReleaseResource( &pFcb->NPFcb->Resource);
2966 pFcb->Header.AllocationSize = pBuffer->EndOfFile;
2968 pFcb->Header.FileSize = pBuffer->EndOfFile;
2970 pFcb->ObjectInformation->EndOfFile = pBuffer->EndOfFile;
2972 pFcb->ObjectInformation->AllocationSize = pBuffer->EndOfFile;
2974 if( pFcb->Header.ValidDataLength.QuadPart > pFcb->Header.FileSize.QuadPart)
2977 pFcb->Header.ValidDataLength = pFcb->Header.FileSize;
2989 // extending the file, move EOF
2993 // If this is a truncation we need to grab the paging
2996 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2997 AFS_TRACE_LEVEL_VERBOSE,
2998 "AFSSetAllocationInfo Acquiring Fcb PagingIo lock %08lX EXCL %08lX\n",
2999 &pFcb->NPFcb->PagingResource,
3000 PsGetCurrentThread());
3002 AFSAcquireExcl( &pFcb->NPFcb->PagingResource,
3005 bReleasePaging = TRUE;
3008 // Must drop the Fcb Resource. When changing the file size
3009 // a deadlock can occur with Trend Micro's filter if the file
3010 // size is set to zero.
3013 AFSReleaseResource( &pFcb->NPFcb->Resource);
3015 pFcb->Header.FileSize = pBuffer->EndOfFile;
3017 pFcb->ObjectInformation->EndOfFile = pBuffer->EndOfFile;
3019 if (pFcb->Header.FileSize.QuadPart > pFcb->Header.AllocationSize.QuadPart)
3022 // And Allocation as needed.
3024 pFcb->Header.AllocationSize = pBuffer->EndOfFile;
3026 pFcb->ObjectInformation->AllocationSize = pBuffer->EndOfFile;
3036 KeQuerySystemTime( &pFcb->ObjectInformation->ChangeTime);
3038 SetFlag( pFcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_CHANGE_TIME);
3044 ntStatus = AFSUpdateFileInformation( &pFcb->ObjectInformation->ParentObjectInformation->FileId,
3045 pFcb->ObjectInformation,
3048 if( NT_SUCCESS(ntStatus))
3051 // We are now good to go so tell CC.
3053 CcSetFileSizes( pFileObject,
3054 (PCC_FILE_SIZES)&pFcb->Header.AllocationSize);
3057 // And give up those extents
3062 AFSTrimExtents( pFcb,
3063 &pFcb->Header.FileSize);
3068 pFcb->Header.ValidDataLength = liSaveVDL;
3069 pFcb->Header.FileSize = liSaveSize;
3070 pFcb->Header.AllocationSize = liSaveAlloc;
3071 pFcb->ObjectInformation->EndOfFile = liSaveSize;
3072 pFcb->ObjectInformation->AllocationSize = liSaveAlloc;
3079 AFSReleaseResource( &pFcb->NPFcb->PagingResource);
3081 AFSAcquireExcl( &pFcb->NPFcb->Resource,
3089 AFSProcessShareSetInfo( IN IRP *Irp,
3094 NTSTATUS ntStatus = STATUS_SUCCESS;
3095 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
3096 ULONG ulOutputBufferLen = 0, ulInputBufferLen;
3097 FILE_INFORMATION_CLASS ulFileInformationClass;
3098 void *pPipeInfo = NULL;
3102 ulFileInformationClass = pIrpSp->Parameters.SetFile.FileInformationClass;
3104 AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
3105 AFS_TRACE_LEVEL_VERBOSE,
3106 "AFSProcessShareSetInfo On pipe %wZ Class %08lX\n",
3107 &Ccb->DirectoryCB->NameInformation.FileName,
3108 ulFileInformationClass);
3110 pPipeInfo = AFSLockSystemBuffer( Irp,
3111 pIrpSp->Parameters.SetFile.Length);
3113 if( pPipeInfo == NULL)
3116 AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
3117 AFS_TRACE_LEVEL_ERROR,
3118 "AFSProcessShareSetInfo Failed to lock buffer on pipe %wZ\n",
3119 &Ccb->DirectoryCB->NameInformation.FileName);
3121 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
3125 // Send the request to the service
3128 ntStatus = AFSNotifySetPipeInfo( Ccb,
3129 (ULONG)ulFileInformationClass,
3130 pIrpSp->Parameters.SetFile.Length,
3133 if( !NT_SUCCESS( ntStatus))
3136 AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
3137 AFS_TRACE_LEVEL_ERROR,
3138 "AFSProcessShareSetInfo Failed to send request to service on pipe %wZ Status %08lX\n",
3139 &Ccb->DirectoryCB->NameInformation.FileName,
3142 try_return( ntStatus);
3145 AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
3146 AFS_TRACE_LEVEL_VERBOSE,
3147 "AFSProcessShareSetInfo Completed request on pipe %wZ Class %08lX\n",
3148 &Ccb->DirectoryCB->NameInformation.FileName,
3149 ulFileInformationClass);
3160 AFSProcessShareQueryInfo( IN IRP *Irp,
3165 NTSTATUS ntStatus = STATUS_SUCCESS;
3166 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
3167 ULONG ulOutputBufferLen = 0, ulInputBufferLen;
3168 FILE_INFORMATION_CLASS ulFileInformationClass;
3169 void *pPipeInfo = NULL;
3174 ulFileInformationClass = pIrpSp->Parameters.QueryFile.FileInformationClass;
3176 AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
3177 AFS_TRACE_LEVEL_VERBOSE,
3178 "AFSProcessShareQueryInfo On pipe %wZ Class %08lX\n",
3179 &Ccb->DirectoryCB->NameInformation.FileName,
3180 ulFileInformationClass);
3182 pPipeInfo = AFSLockSystemBuffer( Irp,
3183 pIrpSp->Parameters.QueryFile.Length);
3185 if( pPipeInfo == NULL)
3188 AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
3189 AFS_TRACE_LEVEL_ERROR,
3190 "AFSProcessShareQueryInfo Failed to lock buffer on pipe %wZ\n",
3191 &Ccb->DirectoryCB->NameInformation.FileName);
3193 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
3197 // Send the request to the service
3200 ntStatus = AFSNotifyQueryPipeInfo( Ccb,
3201 (ULONG)ulFileInformationClass,
3202 pIrpSp->Parameters.QueryFile.Length,
3204 (ULONG *)&Irp->IoStatus.Information);
3206 if( !NT_SUCCESS( ntStatus))
3209 AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
3210 AFS_TRACE_LEVEL_ERROR,
3211 "AFSProcessShareQueryInfo Failed to send request to service on pipe %wZ Status %08lX\n",
3212 &Ccb->DirectoryCB->NameInformation.FileName,
3215 try_return( ntStatus);
3218 AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
3219 AFS_TRACE_LEVEL_VERBOSE,
3220 "AFSProcessShareQueryInfo Completed request on pipe %wZ Class %08lX\n",
3221 &Ccb->DirectoryCB->NameInformation.FileName,
3222 ulFileInformationClass);
3233 AFSProcessPIOCtlQueryInfo( IN IRP *Irp,
3236 IN OUT LONG *Length)
3239 NTSTATUS ntStatus = STATUS_SUCCESS;
3240 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
3241 FILE_INFORMATION_CLASS ulFileInformationClass;
3246 ulFileInformationClass = pIrpSp->Parameters.QueryFile.FileInformationClass;
3248 switch( ulFileInformationClass)
3251 case FileBasicInformation:
3254 AFSDbgLogMsg( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
3255 AFS_TRACE_LEVEL_VERBOSE,
3256 "AFSProcessPIOCtlQueryInfo (FileBasicInformation)\n");
3258 if ( *Length >= sizeof( FILE_BASIC_INFORMATION))
3260 PFILE_BASIC_INFORMATION pBasic = (PFILE_BASIC_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
3262 pBasic->CreationTime.QuadPart = 0;
3263 pBasic->LastAccessTime.QuadPart = 0;
3264 pBasic->ChangeTime.QuadPart = 0;
3265 pBasic->LastWriteTime.QuadPart = 0;
3266 pBasic->FileAttributes = FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM;