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;
75 // Determine the type of request this request is
78 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
80 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
85 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
86 AFS_TRACE_LEVEL_ERROR,
87 "AFSQueryFileInfo Attempted access (%08lX) when pFcb == NULL\n",
90 try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST);
93 lLength = (LONG)pIrpSp->Parameters.QueryFile.Length;
94 stFileInformationClass = pIrpSp->Parameters.QueryFile.FileInformationClass;
95 pBuffer = Irp->AssociatedIrp.SystemBuffer;
97 RtlZeroMemory( &stAuthGroup,
100 AFSRetrieveAuthGroupFnc( (ULONGLONG)PsGetCurrentProcessId(),
101 (ULONGLONG)PsGetCurrentThreadId(),
104 AFSVerifyEntry( &stAuthGroup,
108 // Grab the main shared right off the bat
111 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
112 AFS_TRACE_LEVEL_VERBOSE,
113 "AFSQueryFileInfo Acquiring Fcb lock %08lX SHARED %08lX\n",
114 &pFcb->NPFcb->Resource,
115 PsGetCurrentThread());
117 AFSAcquireShared( &pFcb->NPFcb->Resource,
123 // Don't allow requests against IOCtl nodes
126 if( pFcb->Header.NodeTypeCode == AFS_SPECIAL_SHARE_FCB)
129 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
130 AFS_TRACE_LEVEL_VERBOSE,
131 "AFSQueryFileInfo Processing request against SpecialShare Fcb\n");
133 ntStatus = AFSProcessShareQueryInfo( Irp,
137 try_return( ntStatus);
139 else if( pFcb->Header.NodeTypeCode == AFS_IOCTL_FCB)
141 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
142 AFS_TRACE_LEVEL_VERBOSE,
143 "AFSQueryFileInfo request against PIOCtl Fcb\n");
145 ntStatus = AFSProcessPIOCtlQueryInfo( Irp,
150 try_return( ntStatus);
153 else if( pFcb->Header.NodeTypeCode == AFS_INVALID_FCB)
155 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
156 AFS_TRACE_LEVEL_VERBOSE,
157 "AFSQueryFileInfo request against Invalid Fcb\n");
159 try_return( ntStatus = STATUS_ACCESS_DENIED);
163 // Process the request
166 switch( stFileInformationClass)
169 case FileAllInformation:
172 PFILE_ALL_INFORMATION pAllInfo;
175 // For the all information class we'll typecast a local
176 // pointer to the output buffer and then call the
177 // individual routines to fill in the buffer.
180 pAllInfo = (PFILE_ALL_INFORMATION)pBuffer;
182 ntStatus = AFSQueryBasicInfo( Irp,
184 &pAllInfo->BasicInformation,
187 if( !NT_SUCCESS( ntStatus))
190 try_return( ntStatus);
193 ntStatus = AFSQueryStandardInfo( Irp,
195 &pAllInfo->StandardInformation,
198 if( !NT_SUCCESS( ntStatus))
201 try_return( ntStatus);
204 ntStatus = AFSQueryInternalInfo( Irp,
206 &pAllInfo->InternalInformation,
209 if( !NT_SUCCESS( ntStatus))
212 try_return( ntStatus);
215 ntStatus = AFSQueryEaInfo( Irp,
217 &pAllInfo->EaInformation,
220 if( !NT_SUCCESS( ntStatus))
223 try_return( ntStatus);
226 ntStatus = AFSQueryAccess( Irp,
228 &pAllInfo->AccessInformation,
231 if( !NT_SUCCESS( ntStatus))
234 try_return( ntStatus);
237 ntStatus = AFSQueryPositionInfo( Irp,
239 &pAllInfo->PositionInformation,
242 if( !NT_SUCCESS( ntStatus))
245 try_return( ntStatus);
248 ntStatus = AFSQueryMode( Irp,
250 &pAllInfo->ModeInformation,
253 if( !NT_SUCCESS( ntStatus))
256 try_return( ntStatus);
259 ntStatus = AFSQueryAlignment( Irp,
261 &pAllInfo->AlignmentInformation,
264 if( !NT_SUCCESS( ntStatus))
267 try_return( ntStatus);
270 ntStatus = AFSQueryNameInfo( Irp,
272 &pAllInfo->NameInformation,
275 if( !NT_SUCCESS( ntStatus))
278 try_return( ntStatus);
284 case FileBasicInformation:
287 ntStatus = AFSQueryBasicInfo( Irp,
289 (PFILE_BASIC_INFORMATION)pBuffer,
295 case FileStandardInformation:
298 ntStatus = AFSQueryStandardInfo( Irp,
300 (PFILE_STANDARD_INFORMATION)pBuffer,
306 case FileInternalInformation:
309 ntStatus = AFSQueryInternalInfo( Irp,
311 (PFILE_INTERNAL_INFORMATION)pBuffer,
317 case FileEaInformation:
320 ntStatus = AFSQueryEaInfo( Irp,
322 (PFILE_EA_INFORMATION)pBuffer,
328 case FilePositionInformation:
331 ntStatus = AFSQueryPositionInfo( Irp,
333 (PFILE_POSITION_INFORMATION)pBuffer,
339 case FileNormalizedNameInformation:
340 case FileNameInformation:
343 ntStatus = AFSQueryNameInfo( Irp,
345 (PFILE_NAME_INFORMATION)pBuffer,
351 case FileAlternateNameInformation:
354 ntStatus = AFSQueryShortNameInfo( Irp,
356 (PFILE_NAME_INFORMATION)pBuffer,
362 case FileNetworkOpenInformation:
365 ntStatus = AFSQueryNetworkInfo( Irp,
367 (PFILE_NETWORK_OPEN_INFORMATION)pBuffer,
373 case FileStreamInformation:
376 ntStatus = AFSQueryStreamInfo( Irp,
378 (FILE_STREAM_INFORMATION *)pBuffer,
385 case FileAttributeTagInformation:
388 ntStatus = AFSQueryAttribTagInfo( Irp,
390 (FILE_ATTRIBUTE_TAG_INFORMATION *)pBuffer,
396 case FileRemoteProtocolInformation:
399 ntStatus = AFSQueryRemoteProtocolInfo( Irp,
401 (FILE_REMOTE_PROTOCOL_INFORMATION *)pBuffer,
407 case FileNetworkPhysicalNameInformation:
410 ntStatus = AFSQueryPhysicalNameInfo( Irp,
412 (FILE_NETWORK_PHYSICAL_NAME_INFORMATION *)pBuffer,
420 ntStatus = STATUS_INVALID_PARAMETER;
427 Irp->IoStatus.Information = pIrpSp->Parameters.QueryFile.Length - lLength;
432 AFSReleaseResource( &pFcb->NPFcb->Resource);
435 if( !NT_SUCCESS( ntStatus) &&
436 ntStatus != STATUS_INVALID_PARAMETER &&
437 ntStatus != STATUS_BUFFER_OVERFLOW)
441 pCcb->DirectoryCB != NULL)
444 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
445 AFS_TRACE_LEVEL_ERROR,
446 "AFSQueryFileInfo Failed to process request for %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
447 &pCcb->DirectoryCB->NameInformation.FileName,
448 pCcb->DirectoryCB->ObjectInformation->FileId.Cell,
449 pCcb->DirectoryCB->ObjectInformation->FileId.Volume,
450 pCcb->DirectoryCB->ObjectInformation->FileId.Vnode,
451 pCcb->DirectoryCB->ObjectInformation->FileId.Unique,
456 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
461 "EXCEPTION - AFSQueryFileInfo\n");
463 AFSDumpTraceFilesFnc();
465 ntStatus = STATUS_UNSUCCESSFUL;
470 AFSReleaseResource( &pFcb->NPFcb->Resource);
474 AFSCompleteRequest( Irp,
481 // Function: AFSSetFileInfo
485 // This function is the dispatch handler for the IRP_MJ_SET_FILE_INFORMATION request
489 // A status is returned for the function
493 AFSSetFileInfo( IN PDEVICE_OBJECT LibDeviceObject,
497 NTSTATUS ntStatus = STATUS_SUCCESS;
498 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
499 IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
502 BOOLEAN bCompleteRequest = TRUE;
503 FILE_INFORMATION_CLASS FileInformationClass;
504 BOOLEAN bCanQueueRequest = FALSE;
505 PFILE_OBJECT pFileObject = NULL;
506 BOOLEAN bReleaseMain = FALSE;
507 BOOLEAN bUpdateFileInfo = FALSE;
508 AFSFileID stParentFileId;
513 pFileObject = pIrpSp->FileObject;
515 pFcb = (AFSFcb *)pFileObject->FsContext;
516 pCcb = (AFSCcb *)pFileObject->FsContext2;
521 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
522 AFS_TRACE_LEVEL_ERROR,
523 "AFSSetFileInfo Attempted access (%08lX) when pFcb == NULL\n",
526 try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST);
529 bCanQueueRequest = !(IoIsOperationSynchronous( Irp) | (KeGetCurrentIrql() != PASSIVE_LEVEL));
530 FileInformationClass = pIrpSp->Parameters.SetFile.FileInformationClass;
536 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
537 AFS_TRACE_LEVEL_VERBOSE,
538 "AFSSetFileInfo Acquiring Fcb lock %08lX EXCL %08lX\n",
539 &pFcb->NPFcb->Resource,
540 PsGetCurrentThread());
542 AFSAcquireExcl( &pFcb->NPFcb->Resource,
548 // Don't allow requests against IOCtl nodes
551 if( pFcb->Header.NodeTypeCode == AFS_IOCTL_FCB)
554 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
555 AFS_TRACE_LEVEL_ERROR,
556 "AFSSetFileInfo Failing request against PIOCtl Fcb\n");
558 try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST);
560 else if( pFcb->Header.NodeTypeCode == AFS_SPECIAL_SHARE_FCB)
563 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
564 AFS_TRACE_LEVEL_VERBOSE,
565 "AFSSetFileInfo Processing request against SpecialShare Fcb\n");
567 ntStatus = AFSProcessShareSetInfo( Irp,
571 try_return( ntStatus);
574 if( BooleanFlagOn( pFcb->ObjectInformation->VolumeCB->VolumeInformation.Characteristics, FILE_READ_ONLY_DEVICE))
577 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
578 AFS_TRACE_LEVEL_ERROR,
579 "AFSSetFileInfo Request failed due to read only volume\n",
582 try_return( ntStatus = STATUS_MEDIA_WRITE_PROTECTED);
585 if( pFcb->Header.NodeTypeCode == AFS_INVALID_FCB &&
586 FileInformationClass != FileDispositionInformation)
588 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
589 AFS_TRACE_LEVEL_VERBOSE,
590 "AFSSetFileInfo request against Invalid Fcb\n");
592 try_return( ntStatus = STATUS_ACCESS_DENIED);
596 // Ensure rename operations are synchronous
599 if( FileInformationClass == FileRenameInformation)
602 bCanQueueRequest = FALSE;
606 // Store away the parent fid
609 RtlZeroMemory( &stParentFileId,
612 if( pFcb->ObjectInformation->ParentObjectInformation != NULL)
614 stParentFileId = pFcb->ObjectInformation->ParentObjectInformation->FileId;
618 // Process the request
621 switch( FileInformationClass)
624 case FileBasicInformation:
627 bUpdateFileInfo = TRUE;
629 ntStatus = AFSSetBasicInfo( Irp,
635 case FileDispositionInformation:
638 ntStatus = AFSSetDispositionInfo( Irp,
644 case FileRenameInformation:
647 ntStatus = AFSSetRenameInfo( Irp);
652 case FilePositionInformation:
655 ntStatus = AFSSetPositionInfo( Irp,
661 case FileLinkInformation:
664 ntStatus = AFSSetFileLinkInfo( Irp);
669 case FileAllocationInformation:
672 ntStatus = AFSSetAllocationInfo( Irp,
678 case FileEndOfFileInformation:
681 ntStatus = AFSSetEndOfFileInfo( Irp,
689 ntStatus = STATUS_INVALID_PARAMETER;
699 AFSReleaseResource( &pFcb->NPFcb->Resource);
702 if( NT_SUCCESS( ntStatus) &&
706 ntStatus = AFSUpdateFileInformation( &stParentFileId,
707 pFcb->ObjectInformation,
710 if( !NT_SUCCESS( ntStatus))
713 AFSAcquireExcl( &pFcb->NPFcb->Resource,
717 // Unwind the update and fail the request
720 AFSUnwindFileInfo( pFcb,
723 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
724 AFS_TRACE_LEVEL_ERROR,
725 "AFSSetFileInfo Failed to send file info update to service request for %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
726 &pCcb->DirectoryCB->NameInformation.FileName,
727 pCcb->DirectoryCB->ObjectInformation->FileId.Cell,
728 pCcb->DirectoryCB->ObjectInformation->FileId.Volume,
729 pCcb->DirectoryCB->ObjectInformation->FileId.Vnode,
730 pCcb->DirectoryCB->ObjectInformation->FileId.Unique,
733 AFSReleaseResource( &pFcb->NPFcb->Resource);
737 if( !NT_SUCCESS( ntStatus))
741 pCcb->DirectoryCB != NULL)
744 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
745 AFS_TRACE_LEVEL_ERROR,
746 "AFSSetFileInfo Failed to process request for %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
747 &pCcb->DirectoryCB->NameInformation.FileName,
748 pCcb->DirectoryCB->ObjectInformation->FileId.Cell,
749 pCcb->DirectoryCB->ObjectInformation->FileId.Volume,
750 pCcb->DirectoryCB->ObjectInformation->FileId.Vnode,
751 pCcb->DirectoryCB->ObjectInformation->FileId.Unique,
756 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
761 "EXCEPTION - AFSSetFileInfo\n");
763 AFSDumpTraceFilesFnc();
765 ntStatus = STATUS_UNSUCCESSFUL;
770 AFSReleaseResource( &pFcb->NPFcb->Resource);
774 AFSCompleteRequest( Irp,
781 // Function: AFSQueryBasicInfo
785 // This function is the handler for the query basic information request
789 // A status is returned for the function
793 AFSQueryBasicInfo( IN PIRP Irp,
794 IN AFSDirectoryCB *DirectoryCB,
795 IN OUT PFILE_BASIC_INFORMATION Buffer,
798 NTSTATUS ntStatus = STATUS_SUCCESS;
799 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
800 ULONG ulFileAttribs = 0;
803 IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
804 AFSFileInfoCB stFileInfo;
805 AFSDirectoryCB *pParentDirectoryCB = NULL;
806 UNICODE_STRING uniParentPath;
808 if( *Length >= sizeof( FILE_BASIC_INFORMATION))
811 RtlZeroMemory( Buffer,
814 ulFileAttribs = DirectoryCB->ObjectInformation->FileAttributes;
816 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
817 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
819 if( DirectoryCB->ObjectInformation->FileType == AFS_FILE_TYPE_SYMLINK)
822 pParentDirectoryCB = AFSGetParentEntry( pCcb->NameArray);
824 AFSRetrieveParentPath( &pCcb->FullFileName,
827 RtlZeroMemory( &stFileInfo,
828 sizeof( AFSFileInfoCB));
831 // Can't hold the Fcb while evaluating the path, leads to lock inversion
834 AFSReleaseResource( &pFcb->NPFcb->Resource);
836 if( NT_SUCCESS( AFSRetrieveFileAttributes( pParentDirectoryCB,
844 if ( ulFileAttribs == FILE_ATTRIBUTE_NORMAL)
847 ulFileAttribs = FILE_ATTRIBUTE_REPARSE_POINT;
852 ulFileAttribs |= FILE_ATTRIBUTE_REPARSE_POINT;
855 if ( stFileInfo.FileAttributes & FILE_ATTRIBUTE_DIRECTORY)
858 ulFileAttribs |= FILE_ATTRIBUTE_DIRECTORY;
862 AFSAcquireShared( &pFcb->NPFcb->Resource,
867 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
868 AFS_TRACE_LEVEL_VERBOSE_2,
869 "AFSQueryBasicInfo %wZ Type 0x%x Attrib 0x%x -> 0x%x\n",
870 &pCcb->DirectoryCB->NameInformation.FileName,
871 pCcb->DirectoryCB->ObjectInformation->FileType,
872 pCcb->DirectoryCB->ObjectInformation->FileAttributes,
875 Buffer->CreationTime = DirectoryCB->ObjectInformation->CreationTime;
876 Buffer->LastAccessTime = DirectoryCB->ObjectInformation->LastAccessTime;
877 Buffer->LastWriteTime = DirectoryCB->ObjectInformation->LastWriteTime;
878 Buffer->ChangeTime = DirectoryCB->ObjectInformation->ChangeTime;
879 Buffer->FileAttributes = ulFileAttribs;
881 if( DirectoryCB->NameInformation.FileName.Buffer[ 0] == L'.' &&
882 BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_HIDE_DOT_NAMES))
885 if ( Buffer->FileAttributes != FILE_ATTRIBUTE_NORMAL)
887 Buffer->FileAttributes |= FILE_ATTRIBUTE_HIDDEN;
891 Buffer->FileAttributes = FILE_ATTRIBUTE_HIDDEN;
895 *Length -= sizeof( FILE_BASIC_INFORMATION);
900 ntStatus = STATUS_BUFFER_TOO_SMALL;
907 AFSQueryStandardInfo( IN PIRP Irp,
908 IN AFSDirectoryCB *DirectoryCB,
909 IN OUT PFILE_STANDARD_INFORMATION Buffer,
913 NTSTATUS ntStatus = STATUS_SUCCESS;
916 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
917 AFSFileInfoCB stFileInfo;
918 AFSDirectoryCB *pParentDirectoryCB = NULL;
919 UNICODE_STRING uniParentPath;
920 ULONG ulFileAttribs = 0;
922 if( *Length >= sizeof( FILE_STANDARD_INFORMATION))
925 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
926 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
928 RtlZeroMemory( Buffer,
931 Buffer->NumberOfLinks = 1;
932 Buffer->DeletePending = BooleanFlagOn( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
934 Buffer->AllocationSize.QuadPart = (ULONGLONG)((DirectoryCB->ObjectInformation->AllocationSize.QuadPart/PAGE_SIZE) + 1) * PAGE_SIZE;
936 Buffer->EndOfFile = DirectoryCB->ObjectInformation->EndOfFile;
938 ulFileAttribs = DirectoryCB->ObjectInformation->FileAttributes;
940 if( DirectoryCB->ObjectInformation->FileType == AFS_FILE_TYPE_SYMLINK)
943 pParentDirectoryCB = AFSGetParentEntry( pCcb->NameArray);
945 AFSRetrieveParentPath( &pCcb->FullFileName,
948 RtlZeroMemory( &stFileInfo,
949 sizeof( AFSFileInfoCB));
952 // Can't hold the Fcb while evaluating the path, leads to lock inversion
955 AFSReleaseResource( &pFcb->NPFcb->Resource);
957 if( NT_SUCCESS( AFSRetrieveFileAttributes( pParentDirectoryCB,
965 if ( ulFileAttribs == FILE_ATTRIBUTE_NORMAL)
968 ulFileAttribs = FILE_ATTRIBUTE_REPARSE_POINT;
973 ulFileAttribs |= FILE_ATTRIBUTE_REPARSE_POINT;
976 if ( stFileInfo.FileAttributes & FILE_ATTRIBUTE_DIRECTORY)
979 ulFileAttribs |= FILE_ATTRIBUTE_DIRECTORY;
983 AFSAcquireShared( &pFcb->NPFcb->Resource,
987 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
988 AFS_TRACE_LEVEL_VERBOSE_2,
989 "AFSQueryStandardInfo %wZ Type 0x%x Attrib 0x%x -> 0x%x\n",
990 &pCcb->DirectoryCB->NameInformation.FileName,
991 pCcb->DirectoryCB->ObjectInformation->FileType,
992 pCcb->DirectoryCB->ObjectInformation->FileAttributes,
995 Buffer->Directory = BooleanFlagOn( ulFileAttribs, FILE_ATTRIBUTE_DIRECTORY);
997 *Length -= sizeof( FILE_STANDARD_INFORMATION);
1002 ntStatus = STATUS_BUFFER_TOO_SMALL;
1009 AFSQueryInternalInfo( IN PIRP Irp,
1011 IN OUT PFILE_INTERNAL_INFORMATION Buffer,
1012 IN OUT PLONG Length)
1015 NTSTATUS ntStatus = STATUS_SUCCESS;
1017 if( *Length >= sizeof( FILE_INTERNAL_INFORMATION))
1020 Buffer->IndexNumber.HighPart = Fcb->ObjectInformation->FileId.Volume;
1022 Buffer->IndexNumber.LowPart = Fcb->ObjectInformation->FileId.Vnode;
1024 *Length -= sizeof( FILE_INTERNAL_INFORMATION);
1029 ntStatus = STATUS_BUFFER_TOO_SMALL;
1036 AFSQueryEaInfo( IN PIRP Irp,
1037 IN AFSDirectoryCB *DirectoryCB,
1038 IN OUT PFILE_EA_INFORMATION Buffer,
1039 IN OUT PLONG Length)
1042 NTSTATUS ntStatus = STATUS_SUCCESS;
1044 RtlZeroMemory( Buffer,
1047 if( *Length >= sizeof( FILE_EA_INFORMATION))
1052 *Length -= sizeof( FILE_EA_INFORMATION);
1057 ntStatus = STATUS_BUFFER_TOO_SMALL;
1064 AFSQueryPositionInfo( IN PIRP Irp,
1066 IN OUT PFILE_POSITION_INFORMATION Buffer,
1067 IN OUT PLONG Length)
1070 NTSTATUS ntStatus = STATUS_SUCCESS;
1071 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1073 if( *Length >= sizeof( FILE_POSITION_INFORMATION))
1076 RtlZeroMemory( Buffer,
1079 Buffer->CurrentByteOffset.QuadPart = pIrpSp->FileObject->CurrentByteOffset.QuadPart;
1081 *Length -= sizeof( FILE_POSITION_INFORMATION);
1086 ntStatus = STATUS_BUFFER_TOO_SMALL;
1093 AFSQueryAccess( IN PIRP Irp,
1095 IN OUT PFILE_ACCESS_INFORMATION Buffer,
1096 IN OUT PLONG Length)
1099 NTSTATUS ntStatus = STATUS_SUCCESS;
1101 if( *Length >= sizeof( FILE_ACCESS_INFORMATION))
1104 RtlZeroMemory( Buffer,
1107 Buffer->AccessFlags = 0;
1109 *Length -= sizeof( FILE_ACCESS_INFORMATION);
1114 ntStatus = STATUS_BUFFER_TOO_SMALL;
1121 AFSQueryMode( IN PIRP Irp,
1123 IN OUT PFILE_MODE_INFORMATION Buffer,
1124 IN OUT PLONG Length)
1127 NTSTATUS ntStatus = STATUS_SUCCESS;
1129 if( *Length >= sizeof( FILE_MODE_INFORMATION))
1132 RtlZeroMemory( Buffer,
1137 *Length -= sizeof( FILE_MODE_INFORMATION);
1142 ntStatus = STATUS_BUFFER_TOO_SMALL;
1149 AFSQueryAlignment( IN PIRP Irp,
1151 IN OUT PFILE_ALIGNMENT_INFORMATION Buffer,
1152 IN OUT PLONG Length)
1155 NTSTATUS ntStatus = STATUS_SUCCESS;
1157 if( *Length >= sizeof( FILE_ALIGNMENT_INFORMATION))
1160 RtlZeroMemory( Buffer,
1163 Buffer->AlignmentRequirement = 1;
1165 *Length -= sizeof( FILE_ALIGNMENT_INFORMATION);
1170 ntStatus = STATUS_BUFFER_TOO_SMALL;
1177 AFSQueryNameInfo( IN PIRP Irp,
1178 IN AFSDirectoryCB *DirectoryCB,
1179 IN OUT PFILE_NAME_INFORMATION Buffer,
1180 IN OUT PLONG Length)
1183 NTSTATUS ntStatus = STATUS_SUCCESS;
1184 ULONG ulCopyLength = 0;
1185 ULONG cchCopied = 0;
1186 AFSFcb *pFcb = NULL;
1187 AFSCcb *pCcb = NULL;
1188 IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1189 BOOLEAN bAddLeadingSlash = FALSE;
1190 BOOLEAN bAddTrailingSlash = FALSE;
1191 USHORT usFullNameLength = 0;
1193 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
1195 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
1197 if( *Length >= FIELD_OFFSET( FILE_NAME_INFORMATION, FileName))
1200 RtlZeroMemory( Buffer,
1203 if( pCcb->FullFileName.Length == 0 ||
1204 pCcb->FullFileName.Buffer[ 0] != L'\\')
1206 bAddLeadingSlash = TRUE;
1209 if( pFcb->ObjectInformation->FileType == AFS_FILE_TYPE_DIRECTORY &&
1210 pCcb->FullFileName.Length > 0 &&
1211 pCcb->FullFileName.Buffer[ (pCcb->FullFileName.Length/sizeof( WCHAR)) - 1] != L'\\')
1213 bAddTrailingSlash = TRUE;
1216 usFullNameLength = sizeof( WCHAR) +
1217 AFSServerName.Length +
1218 pCcb->FullFileName.Length;
1220 if( bAddLeadingSlash)
1222 usFullNameLength += sizeof( WCHAR);
1225 if( bAddTrailingSlash)
1227 usFullNameLength += sizeof( WCHAR);
1230 if( *Length >= (LONG)(FIELD_OFFSET( FILE_NAME_INFORMATION, FileName) + (LONG)usFullNameLength))
1233 ulCopyLength = (LONG)usFullNameLength;
1238 ulCopyLength = *Length - FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
1240 ntStatus = STATUS_BUFFER_OVERFLOW;
1243 Buffer->FileNameLength = (ULONG)usFullNameLength;
1245 *Length -= FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
1247 if( ulCopyLength > 0)
1250 Buffer->FileName[ 0] = L'\\';
1251 ulCopyLength -= sizeof( WCHAR);
1253 *Length -= sizeof( WCHAR);
1256 if( ulCopyLength >= AFSServerName.Length)
1259 RtlCopyMemory( &Buffer->FileName[ 1],
1260 AFSServerName.Buffer,
1261 AFSServerName.Length);
1263 ulCopyLength -= AFSServerName.Length;
1264 *Length -= AFSServerName.Length;
1265 cchCopied += AFSServerName.Length/sizeof( WCHAR);
1267 if ( ulCopyLength > 0 &&
1271 Buffer->FileName[ cchCopied] = L'\\';
1273 ulCopyLength -= sizeof( WCHAR);
1274 *Length -= sizeof( WCHAR);
1278 if( ulCopyLength >= pCcb->FullFileName.Length)
1281 RtlCopyMemory( &Buffer->FileName[ cchCopied],
1282 pCcb->FullFileName.Buffer,
1283 pCcb->FullFileName.Length);
1285 ulCopyLength -= pCcb->FullFileName.Length;
1286 *Length -= pCcb->FullFileName.Length;
1287 cchCopied += pCcb->FullFileName.Length/sizeof( WCHAR);
1289 if( ulCopyLength > 0 &&
1292 Buffer->FileName[ cchCopied] = L'\\';
1294 *Length -= sizeof( WCHAR);
1300 RtlCopyMemory( &Buffer->FileName[ cchCopied],
1301 pCcb->FullFileName.Buffer,
1304 *Length -= ulCopyLength;
1312 ntStatus = STATUS_BUFFER_TOO_SMALL;
1319 AFSQueryShortNameInfo( IN PIRP Irp,
1320 IN AFSDirectoryCB *DirectoryCB,
1321 IN OUT PFILE_NAME_INFORMATION Buffer,
1322 IN OUT PLONG Length)
1325 NTSTATUS ntStatus = STATUS_BUFFER_TOO_SMALL;
1326 ULONG ulCopyLength = 0;
1328 RtlZeroMemory( Buffer,
1331 if( DirectoryCB->NameInformation.ShortNameLength == 0)
1335 // The short name IS the long name
1338 if( *Length >= (LONG)FIELD_OFFSET( FILE_NAME_INFORMATION, FileName))
1341 if( *Length >= (LONG)(FIELD_OFFSET( FILE_NAME_INFORMATION, FileName) + (LONG)DirectoryCB->NameInformation.FileName.Length))
1344 ulCopyLength = (LONG)DirectoryCB->NameInformation.FileName.Length;
1346 ntStatus = STATUS_SUCCESS;
1351 ulCopyLength = *Length - FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
1353 ntStatus = STATUS_BUFFER_OVERFLOW;
1356 Buffer->FileNameLength = DirectoryCB->NameInformation.FileName.Length;
1358 *Length -= FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
1360 if( ulCopyLength > 0)
1363 RtlCopyMemory( Buffer->FileName,
1364 DirectoryCB->NameInformation.FileName.Buffer,
1367 *Length -= ulCopyLength;
1374 if( *Length >= (LONG)FIELD_OFFSET( FILE_NAME_INFORMATION, FileName))
1377 if( *Length >= (LONG)(FIELD_OFFSET( FILE_NAME_INFORMATION, FileName) + (LONG)DirectoryCB->NameInformation.FileName.Length))
1380 ulCopyLength = (LONG)DirectoryCB->NameInformation.ShortNameLength;
1382 ntStatus = STATUS_SUCCESS;
1387 ulCopyLength = *Length - FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
1389 ntStatus = STATUS_BUFFER_OVERFLOW;
1392 Buffer->FileNameLength = DirectoryCB->NameInformation.ShortNameLength;
1394 *Length -= FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
1396 if( ulCopyLength > 0)
1399 RtlCopyMemory( Buffer->FileName,
1400 DirectoryCB->NameInformation.ShortName,
1401 Buffer->FileNameLength);
1403 *Length -= ulCopyLength;
1412 AFSQueryNetworkInfo( IN PIRP Irp,
1413 IN AFSDirectoryCB *DirectoryCB,
1414 IN OUT PFILE_NETWORK_OPEN_INFORMATION Buffer,
1415 IN OUT PLONG Length)
1418 NTSTATUS ntStatus = STATUS_SUCCESS;
1419 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1420 AFSFcb *pFcb = NULL;
1421 AFSCcb *pCcb = NULL;
1422 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1423 AFSFileInfoCB stFileInfo;
1424 AFSDirectoryCB *pParentDirectoryCB = NULL;
1425 UNICODE_STRING uniParentPath;
1426 ULONG ulFileAttribs = 0;
1428 RtlZeroMemory( Buffer,
1431 if( *Length >= sizeof( FILE_NETWORK_OPEN_INFORMATION))
1434 ulFileAttribs = DirectoryCB->ObjectInformation->FileAttributes;
1436 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
1437 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
1439 if( DirectoryCB->ObjectInformation->FileType == AFS_FILE_TYPE_SYMLINK)
1442 pParentDirectoryCB = AFSGetParentEntry( pCcb->NameArray);
1444 AFSRetrieveParentPath( &pCcb->FullFileName,
1447 RtlZeroMemory( &stFileInfo,
1448 sizeof( AFSFileInfoCB));
1451 // Can't hold the Fcb while evaluating the path, leads to lock inversion
1454 AFSReleaseResource( &pFcb->NPFcb->Resource);
1456 if( NT_SUCCESS( AFSRetrieveFileAttributes( pParentDirectoryCB,
1464 if ( ulFileAttribs == FILE_ATTRIBUTE_NORMAL)
1467 ulFileAttribs = FILE_ATTRIBUTE_REPARSE_POINT;
1472 ulFileAttribs |= FILE_ATTRIBUTE_REPARSE_POINT;
1475 if ( stFileInfo.FileAttributes & FILE_ATTRIBUTE_DIRECTORY)
1478 ulFileAttribs |= FILE_ATTRIBUTE_DIRECTORY;
1482 AFSAcquireShared( &pFcb->NPFcb->Resource,
1486 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1487 AFS_TRACE_LEVEL_VERBOSE_2,
1488 "AFSQueryNetworkInfo %wZ Type 0x%x Attrib 0x%x -> 0x%x\n",
1489 &pCcb->DirectoryCB->NameInformation.FileName,
1490 pCcb->DirectoryCB->ObjectInformation->FileType,
1491 pCcb->DirectoryCB->ObjectInformation->FileAttributes,
1494 Buffer->CreationTime.QuadPart = DirectoryCB->ObjectInformation->CreationTime.QuadPart;
1495 Buffer->LastAccessTime.QuadPart = DirectoryCB->ObjectInformation->LastAccessTime.QuadPart;
1496 Buffer->LastWriteTime.QuadPart = DirectoryCB->ObjectInformation->LastWriteTime.QuadPart;
1497 Buffer->ChangeTime.QuadPart = DirectoryCB->ObjectInformation->ChangeTime.QuadPart;
1499 Buffer->AllocationSize.QuadPart = DirectoryCB->ObjectInformation->AllocationSize.QuadPart;
1500 Buffer->EndOfFile.QuadPart = DirectoryCB->ObjectInformation->EndOfFile.QuadPart;
1502 Buffer->FileAttributes = ulFileAttribs;
1504 if( DirectoryCB->NameInformation.FileName.Buffer[ 0] == L'.' &&
1505 BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_HIDE_DOT_NAMES))
1508 if ( Buffer->FileAttributes != FILE_ATTRIBUTE_NORMAL)
1511 Buffer->FileAttributes |= FILE_ATTRIBUTE_HIDDEN;
1516 Buffer->FileAttributes = FILE_ATTRIBUTE_HIDDEN;
1520 *Length -= sizeof( FILE_NETWORK_OPEN_INFORMATION);
1525 ntStatus = STATUS_BUFFER_TOO_SMALL;
1532 AFSQueryStreamInfo( IN PIRP Irp,
1533 IN AFSDirectoryCB *DirectoryCB,
1534 IN OUT FILE_STREAM_INFORMATION *Buffer,
1535 IN OUT PLONG Length)
1538 NTSTATUS ntStatus = STATUS_BUFFER_TOO_SMALL;
1539 ULONG ulCopyLength = 0;
1540 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1542 if( *Length >= FIELD_OFFSET( FILE_STREAM_INFORMATION, StreamName))
1545 RtlZeroMemory( Buffer,
1548 Buffer->NextEntryOffset = 0;
1551 if( !BooleanFlagOn( DirectoryCB->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_DIRECTORY))
1554 if( *Length >= (LONG)(FIELD_OFFSET( FILE_STREAM_INFORMATION, StreamName) + 14)) // ::$DATA
1559 ntStatus = STATUS_SUCCESS;
1564 ulCopyLength = *Length - FIELD_OFFSET( FILE_STREAM_INFORMATION, StreamName);
1566 ntStatus = STATUS_BUFFER_OVERFLOW;
1569 Buffer->StreamNameLength = 14; // ::$DATA
1571 Buffer->StreamSize.QuadPart = DirectoryCB->ObjectInformation->EndOfFile.QuadPart;
1573 Buffer->StreamAllocationSize.QuadPart = DirectoryCB->ObjectInformation->AllocationSize.QuadPart;
1575 *Length -= FIELD_OFFSET( FILE_STREAM_INFORMATION, StreamName);
1577 if( ulCopyLength > 0)
1580 RtlCopyMemory( Buffer->StreamName,
1584 *Length -= ulCopyLength;
1590 Buffer->StreamNameLength = 0; // No stream for a directory
1592 // The response size is zero
1594 ntStatus = STATUS_SUCCESS;
1602 AFSQueryAttribTagInfo( IN PIRP Irp,
1603 IN AFSDirectoryCB *DirectoryCB,
1604 IN OUT FILE_ATTRIBUTE_TAG_INFORMATION *Buffer,
1605 IN OUT PLONG Length)
1608 NTSTATUS ntStatus = STATUS_BUFFER_TOO_SMALL;
1609 ULONG ulCopyLength = 0;
1610 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1611 AFSFcb *pFcb = NULL;
1612 AFSCcb *pCcb = NULL;
1613 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1614 AFSFileInfoCB stFileInfo;
1615 AFSDirectoryCB *pParentDirectoryCB = NULL;
1616 UNICODE_STRING uniParentPath;
1617 ULONG ulFileAttribs = 0;
1619 if( *Length >= sizeof( FILE_ATTRIBUTE_TAG_INFORMATION))
1622 RtlZeroMemory( Buffer,
1625 ulFileAttribs = DirectoryCB->ObjectInformation->FileAttributes;
1627 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
1628 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
1630 if( DirectoryCB->ObjectInformation->FileType == AFS_FILE_TYPE_SYMLINK)
1633 pParentDirectoryCB = AFSGetParentEntry( pCcb->NameArray);
1635 AFSRetrieveParentPath( &pCcb->FullFileName,
1638 RtlZeroMemory( &stFileInfo,
1639 sizeof( AFSFileInfoCB));
1642 // Can't hold the Fcb while evaluating the path, leads to lock inversion
1645 AFSReleaseResource( &pFcb->NPFcb->Resource);
1647 if( NT_SUCCESS( AFSRetrieveFileAttributes( pParentDirectoryCB,
1655 if ( ulFileAttribs == FILE_ATTRIBUTE_NORMAL)
1658 ulFileAttribs = FILE_ATTRIBUTE_REPARSE_POINT;
1663 ulFileAttribs |= FILE_ATTRIBUTE_REPARSE_POINT;
1666 if ( stFileInfo.FileAttributes & FILE_ATTRIBUTE_DIRECTORY)
1669 ulFileAttribs |= FILE_ATTRIBUTE_DIRECTORY;
1673 AFSAcquireShared( &pFcb->NPFcb->Resource,
1677 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1678 AFS_TRACE_LEVEL_VERBOSE_2,
1679 "AFSAttribTagInfo %wZ Type 0x%x Attrib 0x%x -> 0x%x\n",
1680 &pCcb->DirectoryCB->NameInformation.FileName,
1681 pCcb->DirectoryCB->ObjectInformation->FileType,
1682 pCcb->DirectoryCB->ObjectInformation->FileAttributes,
1685 Buffer->FileAttributes = ulFileAttribs;
1687 if( DirectoryCB->NameInformation.FileName.Buffer[ 0] == L'.' &&
1688 BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_HIDE_DOT_NAMES))
1691 if ( Buffer->FileAttributes != FILE_ATTRIBUTE_NORMAL)
1694 Buffer->FileAttributes |= FILE_ATTRIBUTE_HIDDEN;
1699 Buffer->FileAttributes = FILE_ATTRIBUTE_HIDDEN;
1703 if( BooleanFlagOn( DirectoryCB->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_REPARSE_POINT))
1705 Buffer->ReparseTag = IO_REPARSE_TAG_SURROGATE|IO_REPARSE_TAG_OPENAFS_DFS;
1708 *Length -= sizeof( FILE_ATTRIBUTE_TAG_INFORMATION);
1710 ntStatus = STATUS_SUCCESS;
1717 AFSQueryRemoteProtocolInfo( IN PIRP Irp,
1718 IN AFSDirectoryCB *DirectoryCB,
1719 IN OUT FILE_REMOTE_PROTOCOL_INFORMATION *Buffer,
1720 IN OUT PLONG Length)
1723 NTSTATUS ntStatus = STATUS_BUFFER_TOO_SMALL;
1724 ULONG ulCopyLength = 0;
1725 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1727 if( *Length >= sizeof( FILE_REMOTE_PROTOCOL_INFORMATION))
1730 RtlZeroMemory( Buffer,
1733 Buffer->StructureVersion = 1;
1735 Buffer->StructureSize = sizeof(FILE_REMOTE_PROTOCOL_INFORMATION);
1737 Buffer->Protocol = WNNC_NET_OPENAFS;
1739 Buffer->ProtocolMajorVersion = 3;
1741 Buffer->ProtocolMinorVersion = 0;
1743 Buffer->ProtocolRevision = 0;
1745 *Length -= sizeof( FILE_REMOTE_PROTOCOL_INFORMATION);
1747 ntStatus = STATUS_SUCCESS;
1754 AFSQueryPhysicalNameInfo( IN PIRP Irp,
1755 IN AFSDirectoryCB *DirectoryCB,
1756 IN OUT PFILE_NETWORK_PHYSICAL_NAME_INFORMATION Buffer,
1757 IN OUT PLONG Length)
1760 NTSTATUS ntStatus = STATUS_SUCCESS;
1761 ULONG ulCopyLength = 0;
1762 ULONG cchCopied = 0;
1763 AFSFcb *pFcb = NULL;
1764 AFSCcb *pCcb = NULL;
1765 IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1766 BOOLEAN bAddLeadingSlash = FALSE;
1767 USHORT usFullNameLength = 0;
1769 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
1771 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
1773 if( *Length >= FIELD_OFFSET( FILE_NETWORK_PHYSICAL_NAME_INFORMATION, FileName))
1776 RtlZeroMemory( Buffer,
1779 if( pCcb->FullFileName.Length == 0 ||
1780 pCcb->FullFileName.Buffer[ 0] != L'\\')
1782 bAddLeadingSlash = TRUE;
1785 usFullNameLength = pCcb->FullFileName.Length;
1787 if( bAddLeadingSlash)
1789 usFullNameLength += sizeof( WCHAR);
1792 if( *Length >= (LONG)(FIELD_OFFSET( FILE_NETWORK_PHYSICAL_NAME_INFORMATION, FileName) + (LONG)usFullNameLength))
1794 ulCopyLength = (LONG)usFullNameLength;
1799 ulCopyLength = *Length - FIELD_OFFSET( FILE_NETWORK_PHYSICAL_NAME_INFORMATION, FileName);
1801 ntStatus = STATUS_BUFFER_OVERFLOW;
1804 Buffer->FileNameLength = (ULONG)usFullNameLength;
1806 *Length -= FIELD_OFFSET( FILE_NETWORK_PHYSICAL_NAME_INFORMATION, FileName);
1808 if( ulCopyLength > 0)
1811 if( bAddLeadingSlash)
1814 Buffer->FileName[ cchCopied] = L'\\';
1816 ulCopyLength -= sizeof( WCHAR);
1817 *Length -= sizeof( WCHAR);
1821 if( ulCopyLength >= pCcb->FullFileName.Length)
1824 RtlCopyMemory( &Buffer->FileName[ cchCopied],
1825 pCcb->FullFileName.Buffer,
1826 pCcb->FullFileName.Length);
1828 ulCopyLength -= pCcb->FullFileName.Length;
1829 *Length -= pCcb->FullFileName.Length;
1830 cchCopied += pCcb->FullFileName.Length/sizeof( WCHAR);
1835 RtlCopyMemory( &Buffer->FileName[ cchCopied],
1836 pCcb->FullFileName.Buffer,
1839 *Length -= ulCopyLength;
1846 ntStatus = STATUS_BUFFER_TOO_SMALL;
1853 AFSSetBasicInfo( IN PIRP Irp,
1854 IN AFSDirectoryCB *DirectoryCB)
1856 NTSTATUS ntStatus = STATUS_SUCCESS;
1857 PFILE_BASIC_INFORMATION pBuffer;
1858 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1859 ULONG ulNotifyFilter = 0;
1860 AFSCcb *pCcb = NULL;
1865 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
1867 pBuffer = (PFILE_BASIC_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
1869 pCcb->FileUnwindInfo.FileAttributes = (ULONG)-1;
1871 if( pBuffer->FileAttributes != (ULONGLONG)0)
1874 if( DirectoryCB->ObjectInformation->Fcb->Header.NodeTypeCode == AFS_FILE_FCB &&
1875 BooleanFlagOn( pBuffer->FileAttributes, FILE_ATTRIBUTE_DIRECTORY))
1878 try_return( ntStatus = STATUS_INVALID_PARAMETER);
1881 if( DirectoryCB->ObjectInformation->Fcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB)
1884 pBuffer->FileAttributes |= FILE_ATTRIBUTE_DIRECTORY;
1887 pCcb->FileUnwindInfo.FileAttributes = DirectoryCB->ObjectInformation->FileAttributes;
1889 DirectoryCB->ObjectInformation->FileAttributes = pBuffer->FileAttributes;
1891 ulNotifyFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
1893 SetFlag( DirectoryCB->ObjectInformation->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED);
1896 pCcb->FileUnwindInfo.CreationTime.QuadPart = (ULONGLONG)-1;
1898 if( pBuffer->CreationTime.QuadPart != (ULONGLONG)-1 &&
1899 pBuffer->CreationTime.QuadPart != (ULONGLONG)0)
1902 pCcb->FileUnwindInfo.CreationTime.QuadPart = DirectoryCB->ObjectInformation->CreationTime.QuadPart;
1904 DirectoryCB->ObjectInformation->CreationTime.QuadPart = pBuffer->CreationTime.QuadPart;
1906 ulNotifyFilter |= FILE_NOTIFY_CHANGE_CREATION;
1908 SetFlag( DirectoryCB->ObjectInformation->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_CREATE_TIME);
1911 pCcb->FileUnwindInfo.LastAccessTime.QuadPart = (ULONGLONG)-1;
1913 if( pBuffer->LastAccessTime.QuadPart != (ULONGLONG)-1 &&
1914 pBuffer->LastAccessTime.QuadPart != (ULONGLONG)0)
1917 pCcb->FileUnwindInfo.LastAccessTime.QuadPart = DirectoryCB->ObjectInformation->LastAccessTime.QuadPart;
1919 DirectoryCB->ObjectInformation->LastAccessTime.QuadPart = pBuffer->LastAccessTime.QuadPart;
1921 ulNotifyFilter |= FILE_NOTIFY_CHANGE_LAST_ACCESS;
1923 SetFlag( DirectoryCB->ObjectInformation->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_ACCESS_TIME);
1926 pCcb->FileUnwindInfo.LastWriteTime.QuadPart = (ULONGLONG)-1;
1928 if( pBuffer->LastWriteTime.QuadPart != (ULONGLONG)-1 &&
1929 pBuffer->LastWriteTime.QuadPart != (ULONGLONG)0)
1932 pCcb->FileUnwindInfo.LastWriteTime.QuadPart = DirectoryCB->ObjectInformation->LastWriteTime.QuadPart;
1934 DirectoryCB->ObjectInformation->LastWriteTime.QuadPart = pBuffer->LastWriteTime.QuadPart;
1936 ulNotifyFilter |= FILE_NOTIFY_CHANGE_LAST_WRITE;
1938 SetFlag( DirectoryCB->ObjectInformation->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_LAST_WRITE_TIME);
1941 pCcb->FileUnwindInfo.ChangeTime.QuadPart = (ULONGLONG)-1;
1943 if( pBuffer->ChangeTime.QuadPart != (ULONGLONG)-1 &&
1944 pBuffer->ChangeTime.QuadPart != (ULONGLONG)0)
1947 pCcb->FileUnwindInfo.ChangeTime.QuadPart = DirectoryCB->ObjectInformation->ChangeTime.QuadPart;
1949 DirectoryCB->ObjectInformation->ChangeTime.QuadPart = pBuffer->ChangeTime.QuadPart;
1951 ulNotifyFilter |= FILE_NOTIFY_CHANGE_LAST_ACCESS;
1953 SetFlag( DirectoryCB->ObjectInformation->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_CHANGE_TIME);
1956 if( ulNotifyFilter > 0)
1959 if( DirectoryCB->ObjectInformation->ParentObjectInformation != NULL)
1962 AFSFsRtlNotifyFullReportChange( DirectoryCB->ObjectInformation->ParentObjectInformation,
1964 (ULONG)ulNotifyFilter,
1965 (ULONG)FILE_ACTION_MODIFIED);
1978 AFSSetDispositionInfo( IN PIRP Irp,
1979 IN AFSDirectoryCB *DirectoryCB)
1981 NTSTATUS ntStatus = STATUS_SUCCESS;
1982 PFILE_DISPOSITION_INFORMATION pBuffer;
1983 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1984 AFSFcb *pFcb = NULL;
1985 AFSCcb *pCcb = NULL;
1990 pBuffer = (PFILE_DISPOSITION_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
1992 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
1994 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
1997 // Can't delete the root
2000 if( pFcb->Header.NodeTypeCode == AFS_ROOT_FCB)
2003 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2004 AFS_TRACE_LEVEL_ERROR,
2005 "AFSSetDispositionInfo Attempt to delete root entry\n");
2007 try_return( ntStatus = STATUS_CANNOT_DELETE);
2011 // If the file is read only then do not allow the delete
2014 if( BooleanFlagOn( DirectoryCB->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_READONLY))
2017 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2018 AFS_TRACE_LEVEL_ERROR,
2019 "AFSSetDispositionInfo Attempt to delete read only entry %wZ\n",
2020 &DirectoryCB->NameInformation.FileName);
2022 try_return( ntStatus = STATUS_CANNOT_DELETE);
2025 if( pBuffer->DeleteFile)
2029 // Check if the caller can delete the file
2032 ntStatus = AFSNotifyDelete( DirectoryCB,
2036 if( !NT_SUCCESS( ntStatus))
2039 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2040 AFS_TRACE_LEVEL_ERROR,
2041 "AFSSetDispositionInfo Cannot delete entry %wZ Status %08lX\n",
2042 &DirectoryCB->NameInformation.FileName,
2045 try_return( ntStatus);
2048 if( pFcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB)
2052 // Reduce the Link count in the object information block
2053 // to correspond with the deletion of the directory entry.
2056 pFcb->ObjectInformation->Links--;
2059 // Check if this is a directory that there are not currently other opens
2062 if( pFcb->ObjectInformation->Specific.Directory.ChildOpenHandleCount > 0)
2065 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2066 AFS_TRACE_LEVEL_ERROR,
2067 "AFSSetDispositionInfo Attempt to delete directory %wZ with open %u handles\n",
2068 &DirectoryCB->NameInformation.FileName,
2069 pFcb->ObjectInformation->Specific.Directory.ChildOpenHandleCount);
2071 try_return( ntStatus = STATUS_DIRECTORY_NOT_EMPTY);
2074 if( !AFSIsDirectoryEmptyForDelete( pFcb))
2077 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2078 AFS_TRACE_LEVEL_ERROR,
2079 "AFSSetDispositionInfo Attempt to delete non-empty directory %wZ\n",
2080 &DirectoryCB->NameInformation.FileName);
2082 try_return( ntStatus = STATUS_DIRECTORY_NOT_EMPTY);
2085 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2086 AFS_TRACE_LEVEL_VERBOSE,
2087 "AFSSetDispositionInfo Setting PENDING_DELETE on DirEntry %p Name %wZ\n",
2089 &DirectoryCB->NameInformation.FileName);
2091 SetFlag( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
2093 else if( pFcb->Header.NodeTypeCode == AFS_FILE_FCB)
2097 // Attempt to flush any outstanding data
2100 if( !MmFlushImageSection( &pFcb->NPFcb->SectionObjectPointers,
2104 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2105 AFS_TRACE_LEVEL_ERROR,
2106 "AFSSetDispositionInfo Failed to flush image section for delete Entry %wZ\n",
2107 &DirectoryCB->NameInformation.FileName);
2109 try_return( ntStatus = STATUS_CANNOT_DELETE);
2113 // Set PENDING_DELETE before CcPurgeCacheSection to avoid a
2114 // deadlock with Trend Micro's Enterprise anti-virus product
2115 // which attempts to open the file which is being deleted.
2118 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2119 AFS_TRACE_LEVEL_VERBOSE,
2120 "AFSSetDispositionInfo Setting PENDING_DELETE on DirEntry %p Name %wZ\n",
2122 &DirectoryCB->NameInformation.FileName);
2124 SetFlag( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
2127 // Purge the cache as well
2130 if( pFcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
2133 if ( !CcPurgeCacheSection( &pFcb->NPFcb->SectionObjectPointers,
2139 SetFlag( pFcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
2147 ClearFlag( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
2151 // OK, should be good to go, set the flag in the file object
2154 pIrpSp->FileObject->DeletePending = pBuffer->DeleteFile;
2165 AFSSetFileLinkInfo( IN PIRP Irp)
2168 NTSTATUS ntStatus = STATUS_SUCCESS;
2169 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
2170 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2171 IO_STATUS_BLOCK stIoSb = {0,0};
2172 PFILE_LINK_INFORMATION pFileLinkInfo = NULL;
2173 PFILE_OBJECT pSrcFileObj = NULL;
2174 PFILE_OBJECT pTargetFileObj = pIrpSp->Parameters.SetFile.FileObject;
2175 AFSFcb *pSrcFcb = NULL, *pTargetDcb = NULL, *pTargetFcb = NULL;
2176 AFSCcb *pSrcCcb = NULL, *pTargetDirCcb = NULL;
2177 AFSObjectInfoCB *pSrcObject = NULL, *pTargetObject = NULL;
2178 AFSObjectInfoCB *pSrcParentObject = NULL, *pTargetParentObject = NULL;
2179 UNICODE_STRING uniSourceName, uniTargetName;
2180 UNICODE_STRING uniFullTargetName, uniTargetParentName;
2181 UNICODE_STRING uniShortName;
2182 BOOLEAN bCommonParent = FALSE;
2183 AFSDirectoryCB *pTargetDirEntry = NULL;
2184 AFSDirectoryCB *pNewTargetDirEntry = NULL;
2186 BOOLEAN bTargetEntryExists = FALSE;
2188 BOOLEAN bReleaseTargetDirLock = FALSE;
2190 ULONG ulNotificationAction = 0, ulNotifyFilter = 0;
2195 pSrcFileObj = pIrpSp->FileObject;
2197 pSrcFcb = (AFSFcb *)pSrcFileObj->FsContext;
2198 pSrcCcb = (AFSCcb *)pSrcFileObj->FsContext2;
2200 pSrcObject = pSrcFcb->ObjectInformation;
2201 pSrcParentObject = pSrcFcb->ObjectInformation->ParentObjectInformation;
2203 pFileLinkInfo = (PFILE_LINK_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
2206 // Perform some basic checks to ensure FS integrity
2209 if( pSrcFcb->Header.NodeTypeCode != AFS_FILE_FCB)
2212 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2213 AFS_TRACE_LEVEL_ERROR,
2214 "AFSSetFileLinkInfo Attempt to non-file (INVALID_PARAMETER)\n");
2216 try_return( ntStatus = STATUS_INVALID_PARAMETER);
2219 if( pTargetFileObj == NULL)
2222 if ( pFileLinkInfo->RootDirectory)
2226 // The target directory is provided by HANDLE
2227 // RootDirectory is only set when the target directory is not the same
2228 // as the source directory.
2230 // AFS only supports hard links within a single directory.
2232 // The IOManager should translate any Handle to a FileObject for us.
2233 // However, the failure to receive a FileObject is treated as a fatal
2237 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2238 AFS_TRACE_LEVEL_ERROR,
2239 "AFSSetFileLinkInfo Attempt to link %wZ to alternate directory by handle INVALID_PARAMETER\n",
2240 &pSrcCcb->DirectoryCB->NameInformation.FileName);
2242 try_return( ntStatus = STATUS_INVALID_PARAMETER);
2247 uniFullTargetName.Length = (USHORT)pFileLinkInfo->FileNameLength;
2249 uniFullTargetName.Buffer = (PWSTR)&pFileLinkInfo->FileName;
2251 AFSRetrieveFinalComponent( &uniFullTargetName,
2254 AFSRetrieveParentPath( &uniFullTargetName,
2255 &uniTargetParentName);
2257 if ( uniTargetParentName.Length == 0)
2261 // This is a simple rename. Here the target directory is the same as the source parent directory
2262 // and the name is retrieved from the system buffer information
2265 pTargetParentObject = pSrcParentObject;
2270 // uniTargetParentName contains the directory the renamed object
2271 // will be moved to. Must obtain the TargetParentObject.
2274 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2275 AFS_TRACE_LEVEL_ERROR,
2276 "AFSSetFileLinkInfo Attempt to link %wZ to alternate directory %wZ (NOT_SAME_DEVICE)\n",
2277 &pSrcCcb->DirectoryCB->NameInformation.FileName,
2278 &uniFullTargetName);
2280 try_return( ntStatus = STATUS_NOT_SAME_DEVICE);
2284 pTargetDcb = pTargetParentObject->Fcb;
2290 // So here we have the target directory taken from the targetfile object
2293 pTargetDcb = (AFSFcb *)pTargetFileObj->FsContext;
2295 pTargetDirCcb = (AFSCcb *)pTargetFileObj->FsContext2;
2297 pTargetParentObject = (AFSObjectInfoCB *)pTargetDcb->ObjectInformation;
2300 // Grab the target name which we setup in the IRP_MJ_CREATE handler. By how we set this up
2301 // it is only the target component of the rename operation
2304 uniTargetName = *((PUNICODE_STRING)&pTargetFileObj->FileName);
2308 // The quick check to see if they are self linking.
2309 // Do the names match? Only do this where the parent directories are
2313 if( pTargetParentObject == pSrcParentObject)
2316 if( FsRtlAreNamesEqual( &uniTargetName,
2321 try_return( ntStatus = STATUS_SUCCESS);
2324 bCommonParent = TRUE;
2330 // We do not allow cross-volume hard links
2333 if( pTargetParentObject->VolumeCB != pSrcObject->VolumeCB)
2336 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2337 AFS_TRACE_LEVEL_ERROR,
2338 "AFSSetFileLinkInfo Attempt to link to different volume %wZ\n",
2339 &pSrcCcb->DirectoryCB->NameInformation.FileName);
2341 try_return( ntStatus = STATUS_NOT_SAME_DEVICE);
2345 ulTargetCRC = AFSGenerateCRC( &uniTargetName,
2348 AFSAcquireExcl( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock,
2351 bReleaseTargetDirLock = TRUE;
2353 AFSLocateCaseSensitiveDirEntry( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
2357 if( pTargetDirEntry == NULL)
2361 // Missed so perform a case insensitive lookup
2364 ulTargetCRC = AFSGenerateCRC( &uniTargetName,
2367 AFSLocateCaseInsensitiveDirEntry( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
2372 if ( !BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
2373 pTargetDirEntry == NULL && RtlIsNameLegalDOS8Dot3( &uniTargetName,
2378 // Try the short name
2380 AFSLocateShortNameDirEntry( pTargetParentObject->Specific.Directory.ShortNameTree,
2386 // Increment our ref count on the dir entry
2389 if( pTargetDirEntry != NULL)
2392 ASSERT( pTargetParentObject == pTargetDirEntry->ObjectInformation->ParentObjectInformation);
2394 lCount = InterlockedIncrement( &pTargetDirEntry->OpenReferenceCount);
2396 if( !pFileLinkInfo->ReplaceIfExists)
2399 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2400 AFS_TRACE_LEVEL_ERROR,
2401 "AFSSetFileLinkInfo Attempt to link with target collision %wZ Target %wZ\n",
2402 &pSrcCcb->DirectoryCB->NameInformation.FileName,
2403 &pTargetDirEntry->NameInformation.FileName);
2405 try_return( ntStatus = STATUS_OBJECT_NAME_COLLISION);
2408 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2409 AFS_TRACE_LEVEL_ERROR,
2410 "AFSSetFileLinkInfo Target %wZ exists DE %p Count %08lX, performing delete of target\n",
2411 &pTargetDirEntry->NameInformation.FileName,
2413 pTargetDirEntry->OpenReferenceCount);
2416 // Pull the directory entry from the parent
2419 AFSRemoveDirNodeFromParent( pTargetParentObject,
2423 bTargetEntryExists = TRUE;
2427 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2428 AFS_TRACE_LEVEL_VERBOSE,
2429 "AFSSetFileLinkInfo Target does NOT exist, normal linking\n");
2433 // OK, this is a simple rename. Issue the rename
2434 // request to the service.
2437 ntStatus = AFSNotifyHardLink( pSrcFcb->ObjectInformation,
2438 &pSrcCcb->AuthGroup,
2439 pSrcFcb->ObjectInformation->ParentObjectInformation,
2440 pTargetDcb->ObjectInformation,
2441 pSrcCcb->DirectoryCB,
2443 pFileLinkInfo->ReplaceIfExists,
2444 &pNewTargetDirEntry);
2446 if( !NT_SUCCESS( ntStatus))
2449 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2450 AFS_TRACE_LEVEL_ERROR,
2451 "AFSSetFileLinkInfo Failed link of %wZ to target %wZ Status %08lX\n",
2452 &pSrcCcb->DirectoryCB->NameInformation.FileName,
2456 try_return( ntStatus);
2459 AFSInsertDirectoryNode( pTargetDcb->ObjectInformation,
2464 // Send notification for the target link file
2467 if( bTargetEntryExists || pNewTargetDirEntry)
2470 ulNotificationAction = FILE_ACTION_MODIFIED;
2475 ulNotificationAction = FILE_ACTION_ADDED;
2478 AFSFsRtlNotifyFullReportChange( pTargetParentObject->ParentObjectInformation,
2480 (ULONG)ulNotifyFilter,
2481 (ULONG)ulNotificationAction);
2485 if( !NT_SUCCESS( ntStatus))
2488 if( bTargetEntryExists)
2491 AFSInsertDirectoryNode( pTargetDirEntry->ObjectInformation->ParentObjectInformation,
2497 if( pTargetDirEntry != NULL)
2500 lCount = InterlockedDecrement( &pTargetDirEntry->OpenReferenceCount);
2503 if( bReleaseTargetDirLock)
2506 AFSReleaseResource( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
2514 AFSSetRenameInfo( IN PIRP Irp)
2517 NTSTATUS ntStatus = STATUS_SUCCESS;
2518 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
2519 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2520 IO_STATUS_BLOCK stIoSb = {0,0};
2521 AFSFcb *pSrcFcb = NULL, *pTargetDcb = NULL, *pTargetFcb = NULL;
2522 AFSCcb *pSrcCcb = NULL, *pTargetDirCcb = NULL;
2523 PFILE_OBJECT pSrcFileObj = pIrpSp->FileObject;
2524 PFILE_OBJECT pTargetFileObj = pIrpSp->Parameters.SetFile.FileObject;
2525 PFILE_OBJECT pTargetParentFileObj = NULL;
2526 PFILE_RENAME_INFORMATION pRenameInfo = NULL;
2527 UNICODE_STRING uniTargetName, uniSourceName, uniTargetParentName;
2528 BOOLEAN bReplaceIfExists = FALSE;
2529 UNICODE_STRING uniShortName;
2530 AFSDirectoryCB *pTargetDirEntry = NULL;
2531 ULONG ulTargetCRC = 0;
2532 BOOLEAN bTargetEntryExists = FALSE;
2533 AFSObjectInfoCB *pSrcObject = NULL, *pTargetObject = NULL;
2534 AFSObjectInfoCB *pSrcParentObject = NULL, *pTargetParentObject = NULL;
2535 AFSFileID stNewFid, stTmpTargetFid;
2536 ULONG ulNotificationAction = 0, ulNotifyFilter = 0;
2537 UNICODE_STRING uniFullTargetName;
2538 BOOLEAN bCommonParent = FALSE;
2539 BOOLEAN bReleaseTargetDirLock = FALSE;
2540 BOOLEAN bReleaseSourceDirLock = FALSE;
2541 BOOLEAN bDereferenceTargetParentObject = FALSE;
2542 PERESOURCE pSourceDirLock = NULL;
2548 bReplaceIfExists = pIrpSp->Parameters.SetFile.ReplaceIfExists;
2550 pRenameInfo = (PFILE_RENAME_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
2552 pSrcFcb = (AFSFcb *)pSrcFileObj->FsContext;
2553 pSrcCcb = (AFSCcb *)pSrcFileObj->FsContext2;
2555 pSrcObject = pSrcFcb->ObjectInformation;
2556 pSrcParentObject = pSrcFcb->ObjectInformation->ParentObjectInformation;
2559 // Perform some basic checks to ensure FS integrity
2562 if( pSrcFcb->Header.NodeTypeCode == AFS_ROOT_FCB)
2566 // Can't rename the root directory
2569 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2570 AFS_TRACE_LEVEL_ERROR,
2571 "AFSSetRenameInfo Attempt to rename root entry\n");
2573 try_return( ntStatus = STATUS_INVALID_PARAMETER);
2576 if( pSrcFcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB)
2580 // If there are any open children then fail the rename
2583 if( pSrcFcb->ObjectInformation->Specific.Directory.ChildOpenHandleCount > 0)
2586 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2587 AFS_TRACE_LEVEL_ERROR,
2588 "AFSSetRenameInfo Attempt to rename directory with open children %wZ\n",
2589 &pSrcCcb->DirectoryCB->NameInformation.FileName);
2591 try_return( ntStatus = STATUS_ACCESS_DENIED);
2597 // Extract off the final component name from the Fcb
2600 uniSourceName.Length = (USHORT)pSrcCcb->DirectoryCB->NameInformation.FileName.Length;
2601 uniSourceName.MaximumLength = uniSourceName.Length;
2603 uniSourceName.Buffer = pSrcCcb->DirectoryCB->NameInformation.FileName.Buffer;
2606 // Resolve the target fileobject
2609 if( pTargetFileObj == NULL)
2612 if ( pRenameInfo->RootDirectory)
2615 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2616 AFS_TRACE_LEVEL_ERROR,
2617 "AFSSetRenameInfo Handle provided but no FileObject ntStatus INVALID_PARAMETER\n");
2619 try_return( ntStatus = STATUS_INVALID_PARAMETER);
2624 uniFullTargetName.Length = (USHORT)pRenameInfo->FileNameLength;
2626 uniFullTargetName.Buffer = (PWSTR)&pRenameInfo->FileName;
2628 AFSRetrieveFinalComponent( &uniFullTargetName,
2631 AFSRetrieveParentPath( &uniFullTargetName,
2632 &uniTargetParentName);
2634 if ( uniTargetParentName.Length == 0)
2638 // This is a simple rename. Here the target directory is the same as the source parent directory
2639 // and the name is retrieved from the system buffer information
2642 pTargetParentObject = pSrcParentObject;
2647 // uniTargetParentName contains the directory the renamed object
2648 // will be moved to. Must obtain the TargetParentObject.
2651 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2652 AFS_TRACE_LEVEL_ERROR,
2653 "AFSSetRenameInfo Attempt to move %wZ to %wZ -- not yet supported (NOT_SAME_DEVICE)\n",
2654 &pSrcCcb->DirectoryCB->NameInformation.FileName,
2655 &uniFullTargetName);
2657 try_return( ntStatus = STATUS_NOT_SAME_DEVICE);
2661 pTargetDcb = pTargetParentObject->Fcb;
2667 // So here we have the target directory taken from the targetfile object
2670 pTargetDcb = (AFSFcb *)pTargetFileObj->FsContext;
2672 pTargetDirCcb = (AFSCcb *)pTargetFileObj->FsContext2;
2674 pTargetParentObject = (AFSObjectInfoCB *)pTargetDcb->ObjectInformation;
2677 // Grab the target name which we setup in the IRP_MJ_CREATE handler. By how we set this up
2678 // it is only the target component of the rename operation
2681 uniTargetName = *((PUNICODE_STRING)&pTargetFileObj->FileName);
2685 // The quick check to see if they are not really performing a rename
2686 // Do the names match? Only do this where the parent directories are
2690 if( pTargetParentObject == pSrcParentObject)
2693 if( FsRtlAreNamesEqual( &uniTargetName,
2698 try_return( ntStatus = STATUS_SUCCESS);
2701 bCommonParent = TRUE;
2706 bCommonParent = FALSE;
2710 // We do not allow cross-volume renames to occur
2713 if( pTargetParentObject->VolumeCB != pSrcObject->VolumeCB)
2716 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2717 AFS_TRACE_LEVEL_ERROR,
2718 "AFSSetRenameInfo Attempt to rename directory to different volume %wZ\n",
2719 &pSrcCcb->DirectoryCB->NameInformation.FileName);
2721 try_return( ntStatus = STATUS_NOT_SAME_DEVICE);
2724 ulTargetCRC = AFSGenerateCRC( &uniTargetName,
2727 AFSAcquireExcl( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock,
2730 bReleaseTargetDirLock = TRUE;
2732 if( pTargetParentObject != pSrcParentObject)
2734 AFSAcquireExcl( pSrcParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock,
2737 bReleaseSourceDirLock = TRUE;
2739 pSourceDirLock = pSrcParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock;
2742 AFSLocateCaseSensitiveDirEntry( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
2746 if( pTargetDirEntry == NULL)
2750 // Missed so perform a case insensitive lookup
2753 ulTargetCRC = AFSGenerateCRC( &uniTargetName,
2756 AFSLocateCaseInsensitiveDirEntry( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
2761 if ( !BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
2762 pTargetDirEntry == NULL && RtlIsNameLegalDOS8Dot3( &uniTargetName,
2767 // Try the short name
2769 AFSLocateShortNameDirEntry( pTargetParentObject->Specific.Directory.ShortNameTree,
2775 // Increment our ref count on the dir entry
2778 if( pTargetDirEntry != NULL)
2781 ASSERT( pTargetParentObject == pTargetDirEntry->ObjectInformation->ParentObjectInformation);
2783 lCount = InterlockedIncrement( &pTargetDirEntry->OpenReferenceCount);
2785 if( !bReplaceIfExists)
2788 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2789 AFS_TRACE_LEVEL_ERROR,
2790 "AFSSetRenameInfo Attempt to rename directory with target collision %wZ Target %wZ\n",
2791 &pSrcCcb->DirectoryCB->NameInformation.FileName,
2792 &pTargetDirEntry->NameInformation.FileName);
2794 try_return( ntStatus = STATUS_OBJECT_NAME_COLLISION);
2797 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2798 AFS_TRACE_LEVEL_ERROR,
2799 "AFSSetRenameInfo Target %wZ exists DE %p Count %08lX, performing delete of target\n",
2800 &pTargetDirEntry->NameInformation.FileName,
2802 pTargetDirEntry->OpenReferenceCount);
2805 // Pull the directory entry from the parent
2808 AFSRemoveDirNodeFromParent( pTargetParentObject,
2812 bTargetEntryExists = TRUE;
2816 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2817 AFS_TRACE_LEVEL_VERBOSE,
2818 "AFSSetRenameInfo Target does NOT exist, normal rename\n");
2822 // We need to remove the DirEntry from the parent node, update the index
2823 // and reinsert it into the parent tree. Note that for entries with the
2824 // same parent we do not pull the node from the enumeration list
2827 AFSRemoveDirNodeFromParent( pSrcFcb->ObjectInformation->ParentObjectInformation,
2828 pSrcCcb->DirectoryCB,
2832 // OK, this is a simple rename. Issue the rename
2833 // request to the service.
2836 ntStatus = AFSNotifyRename( pSrcFcb->ObjectInformation,
2837 &pSrcCcb->AuthGroup,
2838 pSrcFcb->ObjectInformation->ParentObjectInformation,
2839 pTargetDcb->ObjectInformation,
2840 pSrcCcb->DirectoryCB,
2844 if( !NT_SUCCESS( ntStatus))
2848 // Attempt to re-insert the directory entry
2851 AFSInsertDirectoryNode( pSrcFcb->ObjectInformation->ParentObjectInformation,
2852 pSrcCcb->DirectoryCB,
2855 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2856 AFS_TRACE_LEVEL_ERROR,
2857 "AFSSetRenameInfo Failed rename of %wZ to target %wZ Status %08lX\n",
2858 &pSrcCcb->DirectoryCB->NameInformation.FileName,
2862 try_return( ntStatus);
2866 // Set the notification up for the source file
2869 if( pSrcCcb->DirectoryCB->ObjectInformation->ParentObjectInformation == pTargetParentObject &&
2870 !bTargetEntryExists)
2873 ulNotificationAction = FILE_ACTION_RENAMED_OLD_NAME;
2878 ulNotificationAction = FILE_ACTION_REMOVED;
2881 if( pSrcCcb->DirectoryCB->ObjectInformation->FileType == AFS_FILE_TYPE_DIRECTORY)
2884 ulNotifyFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
2889 ulNotifyFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
2892 AFSFsRtlNotifyFullReportChange( pSrcCcb->DirectoryCB->ObjectInformation->ParentObjectInformation,
2894 (ULONG)ulNotifyFilter,
2895 (ULONG)ulNotificationAction);
2898 // Update the name in the dir entry.
2901 ntStatus = AFSUpdateDirEntryName( pSrcCcb->DirectoryCB,
2904 if( !NT_SUCCESS( ntStatus))
2908 // Attempt to re-insert the directory entry
2911 AFSInsertDirectoryNode( pSrcFcb->ObjectInformation->ParentObjectInformation,
2912 pSrcCcb->DirectoryCB,
2915 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2916 AFS_TRACE_LEVEL_ERROR,
2917 "AFSSetRenameInfo Failed update of dir entry %wZ to target %wZ Status %08lX\n",
2918 &pSrcCcb->DirectoryCB->NameInformation.FileName,
2922 try_return( ntStatus);
2926 // Update the object information block, if needed
2929 if( !AFSIsEqualFID( &pSrcObject->FileId,
2933 AFSAcquireExcl( pSrcObject->VolumeCB->ObjectInfoTree.TreeLock,
2937 // Remove the old information entry
2940 AFSRemoveHashEntry( &pSrcObject->VolumeCB->ObjectInfoTree.TreeHead,
2941 &pSrcObject->TreeEntry);
2943 RtlCopyMemory( &pSrcObject->FileId,
2945 sizeof( AFSFileID));
2948 // Insert the entry into the new object table.
2951 pSrcObject->TreeEntry.HashIndex = AFSCreateLowIndex( &pSrcObject->FileId);
2953 if( pSrcObject->VolumeCB->ObjectInfoTree.TreeHead == NULL)
2956 pSrcObject->VolumeCB->ObjectInfoTree.TreeHead = &pSrcObject->TreeEntry;
2961 if ( !NT_SUCCESS( AFSInsertHashEntry( pSrcObject->VolumeCB->ObjectInfoTree.TreeHead,
2962 &pSrcObject->TreeEntry)))
2966 // Lost a race, an ObjectInfo object already exists for this FID.
2967 // Let this copy be garbage collected.
2970 ClearFlag( pSrcObject->Flags, AFS_OBJECT_INSERTED_HASH_TREE);
2974 AFSReleaseResource( pSrcObject->VolumeCB->ObjectInfoTree.TreeLock);
2978 // Update the hash values for the name trees.
2981 pSrcCcb->DirectoryCB->CaseSensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pSrcCcb->DirectoryCB->NameInformation.FileName,
2984 pSrcCcb->DirectoryCB->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pSrcCcb->DirectoryCB->NameInformation.FileName,
2987 if( !BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
2988 pSrcCcb->DirectoryCB->NameInformation.ShortNameLength > 0 &&
2989 !RtlIsNameLegalDOS8Dot3( &pSrcCcb->DirectoryCB->NameInformation.FileName,
2994 uniShortName.Length = pSrcCcb->DirectoryCB->NameInformation.ShortNameLength;
2995 uniShortName.MaximumLength = uniShortName.Length;
2996 uniShortName.Buffer = pSrcCcb->DirectoryCB->NameInformation.ShortName;
2998 pSrcCcb->DirectoryCB->Type.Data.ShortNameTreeEntry.HashIndex = AFSGenerateCRC( &uniShortName,
3001 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3002 AFS_TRACE_LEVEL_VERBOSE,
3003 "AFSSetRenameInfo Initialized short name hash for %wZ longname %wZ\n",
3005 &pSrcCcb->DirectoryCB->NameInformation.FileName);
3010 pSrcCcb->DirectoryCB->Type.Data.ShortNameTreeEntry.HashIndex = 0;
3017 // Update the file index for the object in the new parent
3020 pSrcCcb->DirectoryCB->FileIndex = (ULONG)InterlockedIncrement( &pTargetParentObject->Specific.Directory.DirectoryNodeHdr.ContentIndex);
3024 // Re-insert the directory entry
3027 AFSInsertDirectoryNode( pTargetParentObject,
3028 pSrcCcb->DirectoryCB,
3032 // Update the parent pointer in the source object if they are different
3035 if( pSrcCcb->DirectoryCB->ObjectInformation->ParentObjectInformation != pTargetParentObject)
3038 lCount = InterlockedDecrement( &pSrcCcb->DirectoryCB->ObjectInformation->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);
3040 lCount = InterlockedDecrement( &pSrcCcb->DirectoryCB->ObjectInformation->ParentObjectInformation->Specific.Directory.ChildOpenReferenceCount);
3042 lCount = InterlockedIncrement( &pTargetParentObject->Specific.Directory.ChildOpenHandleCount);
3044 lCount = InterlockedIncrement( &pTargetParentObject->Specific.Directory.ChildOpenReferenceCount);
3046 pSrcCcb->DirectoryCB->ObjectInformation->ParentObjectInformation = pTargetParentObject;
3048 ulNotificationAction = FILE_ACTION_ADDED;
3053 ulNotificationAction = FILE_ACTION_RENAMED_NEW_NAME;
3057 // Now update the notification for the target file
3060 AFSFsRtlNotifyFullReportChange( pTargetParentObject->ParentObjectInformation,
3062 (ULONG)ulNotifyFilter,
3063 (ULONG)ulNotificationAction);
3066 // If we performed the rename of the target because it existed, we now need to
3067 // delete the tmp target we created above
3070 if( bTargetEntryExists)
3073 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3074 AFS_TRACE_LEVEL_VERBOSE,
3075 "AFSSetRenameInfo Setting DELETE flag in dir entry %p name %wZ\n",
3077 &pTargetDirEntry->NameInformation.FileName);
3079 SetFlag( pTargetDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
3082 // Try and purge the cache map if this is a file
3085 if( pTargetDirEntry->ObjectInformation->FileType == AFS_FILE_TYPE_FILE &&
3086 pTargetDirEntry->ObjectInformation->Fcb != NULL &&
3087 pTargetDirEntry->OpenReferenceCount > 1)
3090 pTargetFcb = pTargetDirEntry->ObjectInformation->Fcb;
3092 AFSAcquireExcl( &pTargetFcb->NPFcb->Resource,
3096 // Close the section in the event it was mapped
3099 if( !MmForceSectionClosed( &pTargetFcb->NPFcb->SectionObjectPointers,
3103 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3104 AFS_TRACE_LEVEL_ERROR,
3105 "AFSSetRenameInfo Failed to delete section for target file %wZ\n",
3106 &pTargetDirEntry->NameInformation.FileName);
3109 AFSReleaseResource( &pTargetFcb->NPFcb->Resource);
3112 ASSERT( pTargetDirEntry->OpenReferenceCount > 0);
3114 lCount = InterlockedDecrement( &pTargetDirEntry->OpenReferenceCount); // The count we added above
3119 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3120 AFS_TRACE_LEVEL_VERBOSE,
3121 "AFSSetRenameInfo Deleting dir entry %p name %wZ\n",
3123 &pTargetDirEntry->NameInformation.FileName);
3125 AFSDeleteDirEntry( pTargetParentObject,
3129 pTargetDirEntry = NULL;
3134 if( !NT_SUCCESS( ntStatus))
3137 if( bTargetEntryExists)
3139 AFSInsertDirectoryNode( pTargetDirEntry->ObjectInformation->ParentObjectInformation,
3145 if( pTargetDirEntry != NULL)
3148 lCount = InterlockedDecrement( &pTargetDirEntry->OpenReferenceCount);
3151 if( bReleaseTargetDirLock)
3153 AFSReleaseResource( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
3156 if( bReleaseSourceDirLock)
3158 AFSReleaseResource( pSourceDirLock);
3162 if ( bDereferenceTargetParentObject)
3165 ObDereferenceObject( pTargetParentFileObj);
3172 AFSSetPositionInfo( IN PIRP Irp,
3173 IN AFSDirectoryCB *DirectoryCB)
3175 NTSTATUS ntStatus = STATUS_SUCCESS;
3176 PFILE_POSITION_INFORMATION pBuffer;
3177 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
3179 pBuffer = (PFILE_POSITION_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
3181 pIrpSp->FileObject->CurrentByteOffset.QuadPart = pBuffer->CurrentByteOffset.QuadPart;
3187 AFSSetAllocationInfo( IN PIRP Irp,
3188 IN AFSDirectoryCB *DirectoryCB)
3190 NTSTATUS ntStatus = STATUS_SUCCESS;
3191 PFILE_ALLOCATION_INFORMATION pBuffer;
3192 BOOLEAN bReleasePaging = FALSE;
3193 BOOLEAN bTellCc = FALSE;
3194 BOOLEAN bTellService = FALSE;
3195 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
3196 PFILE_OBJECT pFileObject = pIrpSp->FileObject;
3197 AFSFcb *pFcb = NULL;
3198 AFSCcb *pCcb = NULL;
3199 LARGE_INTEGER liSaveAlloc;
3200 LARGE_INTEGER liSaveFileSize;
3201 LARGE_INTEGER liSaveVDL;
3203 pBuffer = (PFILE_ALLOCATION_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
3205 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
3207 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
3210 // save values to put back
3212 liSaveAlloc = pFcb->Header.AllocationSize;
3213 liSaveFileSize = pFcb->Header.FileSize;
3214 liSaveVDL = pFcb->Header.ValidDataLength;
3216 if( pFcb->Header.AllocationSize.QuadPart == pBuffer->AllocationSize.QuadPart ||
3217 pIrpSp->Parameters.SetFile.AdvanceOnly)
3219 return STATUS_SUCCESS ;
3222 if( pFcb->Header.AllocationSize.QuadPart > pBuffer->AllocationSize.QuadPart)
3225 // Truncating the file
3227 if( !MmCanFileBeTruncated( pFileObject->SectionObjectPointer,
3228 &pBuffer->AllocationSize))
3231 ntStatus = STATUS_USER_MAPPED_FILE ;
3236 // If this is a truncation we need to grab the paging IO resource.
3239 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3240 AFS_TRACE_LEVEL_VERBOSE,
3241 "AFSSetAllocationInfo Acquiring Fcb PagingIo lock %08lX EXCL %08lX\n",
3242 &pFcb->NPFcb->PagingResource,
3243 PsGetCurrentThread());
3245 AFSAcquireExcl( &pFcb->NPFcb->PagingResource,
3248 bReleasePaging = TRUE;
3251 // Must drop the Fcb Resource. When changing the file size
3252 // a deadlock can occur with Trend Micro's filter if the file
3253 // size is set to zero.
3256 AFSReleaseResource( &pFcb->NPFcb->Resource);
3258 pFcb->Header.AllocationSize = pBuffer->AllocationSize;
3260 pFcb->ObjectInformation->AllocationSize = pBuffer->AllocationSize;
3263 // Tell Cc that Allocation is moved.
3267 if( pFcb->Header.FileSize.QuadPart > pBuffer->AllocationSize.QuadPart)
3270 // We are pulling the EOF back as well so we need to tell
3273 bTellService = TRUE;
3275 pFcb->Header.FileSize = pBuffer->AllocationSize;
3277 pFcb->ObjectInformation->EndOfFile = pBuffer->AllocationSize;
3285 // Tell Cc if allocation is increased.
3288 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3289 AFS_TRACE_LEVEL_VERBOSE,
3290 "AFSSetAllocationInfo Acquiring Fcb PagingIo lock %08lX EXCL %08lX\n",
3291 &pFcb->NPFcb->PagingResource,
3292 PsGetCurrentThread());
3294 AFSAcquireExcl( &pFcb->NPFcb->PagingResource,
3297 bReleasePaging = TRUE;
3300 // Must drop the Fcb Resource. When changing the file size
3301 // a deadlock can occur with Trend Micro's filter if the file
3302 // size is set to zero.
3305 AFSReleaseResource( &pFcb->NPFcb->Resource);
3307 bTellCc = pBuffer->AllocationSize.QuadPart > pFcb->Header.AllocationSize.QuadPart;
3309 pFcb->Header.AllocationSize = pBuffer->AllocationSize;
3311 pFcb->ObjectInformation->AllocationSize = pBuffer->AllocationSize;
3315 // Now Tell the server if we have to
3319 ntStatus = AFSUpdateFileInformation( &pFcb->ObjectInformation->ParentObjectInformation->FileId,
3320 pFcb->ObjectInformation,
3324 if (NT_SUCCESS(ntStatus))
3327 // Trim extents if we told the service - the update has done an implicit
3328 // trim at the service.
3332 AFSTrimExtents( pFcb,
3333 &pFcb->Header.FileSize);
3336 KeQuerySystemTime( &pFcb->ObjectInformation->ChangeTime);
3338 SetFlag( pFcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_CHANGE_TIME);
3341 CcIsFileCached( pFileObject))
3343 CcSetFileSizes( pFileObject,
3344 (PCC_FILE_SIZES)&pFcb->Header.AllocationSize);
3350 // Put the saved values back
3352 pFcb->Header.ValidDataLength = liSaveVDL;
3353 pFcb->Header.FileSize = liSaveFileSize;
3354 pFcb->Header.AllocationSize = liSaveAlloc;
3355 pFcb->ObjectInformation->EndOfFile = liSaveFileSize;
3356 pFcb->ObjectInformation->AllocationSize = liSaveAlloc;
3362 AFSReleaseResource( &pFcb->NPFcb->PagingResource);
3364 AFSAcquireExcl( &pFcb->NPFcb->Resource,
3372 AFSSetEndOfFileInfo( IN PIRP Irp,
3373 IN AFSDirectoryCB *DirectoryCB)
3375 NTSTATUS ntStatus = STATUS_SUCCESS;
3376 PFILE_END_OF_FILE_INFORMATION pBuffer;
3377 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
3378 PFILE_OBJECT pFileObject = pIrpSp->FileObject;
3379 LARGE_INTEGER liSaveSize;
3380 LARGE_INTEGER liSaveVDL;
3381 LARGE_INTEGER liSaveAlloc;
3382 BOOLEAN bModified = FALSE;
3383 BOOLEAN bReleasePaging = FALSE;
3384 BOOLEAN bTruncated = FALSE;
3385 AFSFcb *pFcb = NULL;
3386 AFSCcb *pCcb = NULL;
3388 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
3390 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
3392 pBuffer = (PFILE_END_OF_FILE_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
3394 liSaveSize = pFcb->Header.FileSize;
3395 liSaveAlloc = pFcb->Header.AllocationSize;
3396 liSaveVDL = pFcb->Header.ValidDataLength;
3398 if( pFcb->Header.FileSize.QuadPart != pBuffer->EndOfFile.QuadPart &&
3399 !pIrpSp->Parameters.SetFile.AdvanceOnly)
3402 if( pBuffer->EndOfFile.QuadPart < pFcb->Header.FileSize.QuadPart)
3405 // Truncating the file
3406 if( !MmCanFileBeTruncated( pFileObject->SectionObjectPointer,
3407 &pBuffer->EndOfFile))
3410 ntStatus = STATUS_USER_MAPPED_FILE;
3416 // If this is a truncation we need to grab the paging
3419 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3420 AFS_TRACE_LEVEL_VERBOSE,
3421 "AFSSetAllocationInfo Acquiring Fcb PagingIo lock %08lX EXCL %08lX\n",
3422 &pFcb->NPFcb->PagingResource,
3423 PsGetCurrentThread());
3425 AFSAcquireExcl( &pFcb->NPFcb->PagingResource,
3428 bReleasePaging = TRUE;
3431 // Must drop the Fcb Resource. When changing the file size
3432 // a deadlock can occur with Trend Micro's filter if the file
3433 // size is set to zero.
3436 AFSReleaseResource( &pFcb->NPFcb->Resource);
3438 pFcb->Header.AllocationSize = pBuffer->EndOfFile;
3440 pFcb->Header.FileSize = pBuffer->EndOfFile;
3442 pFcb->ObjectInformation->EndOfFile = pBuffer->EndOfFile;
3444 pFcb->ObjectInformation->AllocationSize = pBuffer->EndOfFile;
3446 if( pFcb->Header.ValidDataLength.QuadPart > pFcb->Header.FileSize.QuadPart)
3449 pFcb->Header.ValidDataLength = pFcb->Header.FileSize;
3461 // extending the file, move EOF
3465 // If this is a truncation we need to grab the paging
3468 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3469 AFS_TRACE_LEVEL_VERBOSE,
3470 "AFSSetAllocationInfo Acquiring Fcb PagingIo lock %08lX EXCL %08lX\n",
3471 &pFcb->NPFcb->PagingResource,
3472 PsGetCurrentThread());
3474 AFSAcquireExcl( &pFcb->NPFcb->PagingResource,
3477 bReleasePaging = TRUE;
3480 // Must drop the Fcb Resource. When changing the file size
3481 // a deadlock can occur with Trend Micro's filter if the file
3482 // size is set to zero.
3485 AFSReleaseResource( &pFcb->NPFcb->Resource);
3487 pFcb->Header.FileSize = pBuffer->EndOfFile;
3489 pFcb->ObjectInformation->EndOfFile = pBuffer->EndOfFile;
3491 if (pFcb->Header.FileSize.QuadPart > pFcb->Header.AllocationSize.QuadPart)
3494 // And Allocation as needed.
3496 pFcb->Header.AllocationSize = pBuffer->EndOfFile;
3498 pFcb->ObjectInformation->AllocationSize = pBuffer->EndOfFile;
3508 KeQuerySystemTime( &pFcb->ObjectInformation->ChangeTime);
3510 SetFlag( pFcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_CHANGE_TIME);
3516 ntStatus = AFSUpdateFileInformation( &pFcb->ObjectInformation->ParentObjectInformation->FileId,
3517 pFcb->ObjectInformation,
3520 if( NT_SUCCESS(ntStatus))
3523 // We are now good to go so tell CC.
3525 CcSetFileSizes( pFileObject,
3526 (PCC_FILE_SIZES)&pFcb->Header.AllocationSize);
3529 // And give up those extents
3534 AFSTrimExtents( pFcb,
3535 &pFcb->Header.FileSize);
3540 pFcb->Header.ValidDataLength = liSaveVDL;
3541 pFcb->Header.FileSize = liSaveSize;
3542 pFcb->Header.AllocationSize = liSaveAlloc;
3543 pFcb->ObjectInformation->EndOfFile = liSaveSize;
3544 pFcb->ObjectInformation->AllocationSize = liSaveAlloc;
3551 AFSReleaseResource( &pFcb->NPFcb->PagingResource);
3553 AFSAcquireExcl( &pFcb->NPFcb->Resource,
3561 AFSProcessShareSetInfo( IN IRP *Irp,
3566 NTSTATUS ntStatus = STATUS_SUCCESS;
3567 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
3568 ULONG ulOutputBufferLen = 0, ulInputBufferLen;
3569 FILE_INFORMATION_CLASS ulFileInformationClass;
3570 void *pPipeInfo = NULL;
3574 ulFileInformationClass = pIrpSp->Parameters.SetFile.FileInformationClass;
3576 AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
3577 AFS_TRACE_LEVEL_VERBOSE,
3578 "AFSProcessShareSetInfo On pipe %wZ Class %08lX\n",
3579 &Ccb->DirectoryCB->NameInformation.FileName,
3580 ulFileInformationClass);
3582 pPipeInfo = AFSLockSystemBuffer( Irp,
3583 pIrpSp->Parameters.SetFile.Length);
3585 if( pPipeInfo == NULL)
3588 AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
3589 AFS_TRACE_LEVEL_ERROR,
3590 "AFSProcessShareSetInfo Failed to lock buffer on pipe %wZ\n",
3591 &Ccb->DirectoryCB->NameInformation.FileName);
3593 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
3597 // Send the request to the service
3600 ntStatus = AFSNotifySetPipeInfo( Ccb,
3601 (ULONG)ulFileInformationClass,
3602 pIrpSp->Parameters.SetFile.Length,
3605 if( !NT_SUCCESS( ntStatus))
3608 AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
3609 AFS_TRACE_LEVEL_ERROR,
3610 "AFSProcessShareSetInfo Failed to send request to service on pipe %wZ Status %08lX\n",
3611 &Ccb->DirectoryCB->NameInformation.FileName,
3614 try_return( ntStatus);
3617 AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
3618 AFS_TRACE_LEVEL_VERBOSE,
3619 "AFSProcessShareSetInfo Completed request on pipe %wZ Class %08lX\n",
3620 &Ccb->DirectoryCB->NameInformation.FileName,
3621 ulFileInformationClass);
3632 AFSProcessShareQueryInfo( IN IRP *Irp,
3637 NTSTATUS ntStatus = STATUS_SUCCESS;
3638 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
3639 ULONG ulOutputBufferLen = 0, ulInputBufferLen;
3640 FILE_INFORMATION_CLASS ulFileInformationClass;
3641 void *pPipeInfo = NULL;
3646 ulFileInformationClass = pIrpSp->Parameters.QueryFile.FileInformationClass;
3648 AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
3649 AFS_TRACE_LEVEL_VERBOSE,
3650 "AFSProcessShareQueryInfo On pipe %wZ Class %08lX\n",
3651 &Ccb->DirectoryCB->NameInformation.FileName,
3652 ulFileInformationClass);
3654 pPipeInfo = AFSLockSystemBuffer( Irp,
3655 pIrpSp->Parameters.QueryFile.Length);
3657 if( pPipeInfo == NULL)
3660 AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
3661 AFS_TRACE_LEVEL_ERROR,
3662 "AFSProcessShareQueryInfo Failed to lock buffer on pipe %wZ\n",
3663 &Ccb->DirectoryCB->NameInformation.FileName);
3665 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
3669 // Send the request to the service
3672 ntStatus = AFSNotifyQueryPipeInfo( Ccb,
3673 (ULONG)ulFileInformationClass,
3674 pIrpSp->Parameters.QueryFile.Length,
3676 (ULONG *)&Irp->IoStatus.Information);
3678 if( !NT_SUCCESS( ntStatus))
3681 AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
3682 AFS_TRACE_LEVEL_ERROR,
3683 "AFSProcessShareQueryInfo Failed to send request to service on pipe %wZ Status %08lX\n",
3684 &Ccb->DirectoryCB->NameInformation.FileName,
3687 try_return( ntStatus);
3690 AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
3691 AFS_TRACE_LEVEL_VERBOSE,
3692 "AFSProcessShareQueryInfo Completed request on pipe %wZ Class %08lX\n",
3693 &Ccb->DirectoryCB->NameInformation.FileName,
3694 ulFileInformationClass);
3705 AFSProcessPIOCtlQueryInfo( IN IRP *Irp,
3708 IN OUT LONG *Length)
3711 NTSTATUS ntStatus = STATUS_SUCCESS;
3712 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
3713 FILE_INFORMATION_CLASS ulFileInformationClass;
3718 ulFileInformationClass = pIrpSp->Parameters.QueryFile.FileInformationClass;
3720 switch( ulFileInformationClass)
3723 case FileBasicInformation:
3726 AFSDbgLogMsg( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
3727 AFS_TRACE_LEVEL_VERBOSE,
3728 "AFSProcessPIOCtlQueryInfo (FileBasicInformation)\n");
3730 if ( *Length >= sizeof( FILE_BASIC_INFORMATION))
3732 PFILE_BASIC_INFORMATION pBasic = (PFILE_BASIC_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
3734 pBasic->CreationTime.QuadPart = 0;
3735 pBasic->LastAccessTime.QuadPart = 0;
3736 pBasic->ChangeTime.QuadPart = 0;
3737 pBasic->LastWriteTime.QuadPart = 0;
3738 pBasic->FileAttributes = FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM;
3740 *Length -= sizeof( FILE_BASIC_INFORMATION);
3744 ntStatus = STATUS_BUFFER_TOO_SMALL;
3750 case FileStandardInformation:
3753 AFSDbgLogMsg( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
3754 AFS_TRACE_LEVEL_VERBOSE,
3755 "AFSProcessPIOCtlQueryInfo (FileStandardInformation)\n");
3757 if ( *Length >= sizeof( FILE_STANDARD_INFORMATION))
3759 PFILE_STANDARD_INFORMATION pStandard = (PFILE_STANDARD_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
3761 pStandard->NumberOfLinks = 1;
3762 pStandard->DeletePending = 0;
3763 pStandard->AllocationSize.QuadPart = 0;
3764 pStandard->EndOfFile.QuadPart = 0;
3765 pStandard->Directory = 0;
3767 *Length -= sizeof( FILE_STANDARD_INFORMATION);
3771 ntStatus = STATUS_BUFFER_TOO_SMALL;
3777 case FileNormalizedNameInformation:
3778 case FileNameInformation:
3781 ULONG ulCopyLength = 0;
3782 AFSFcb *pFcb = NULL;
3783 AFSCcb *pCcb = NULL;
3784 USHORT usFullNameLength = 0;
3785 PFILE_NAME_INFORMATION pNameInfo = (PFILE_NAME_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
3786 UNICODE_STRING uniName;
3788 AFSDbgLogMsg( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
3789 AFS_TRACE_LEVEL_VERBOSE,
3790 "AFSProcessPIOCtlQueryInfo (FileNameInformation)\n");
3792 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
3793 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
3795 if( *Length < FIELD_OFFSET( FILE_NAME_INFORMATION, FileName))
3797 ntStatus = STATUS_BUFFER_TOO_SMALL;
3801 RtlZeroMemory( pNameInfo,
3804 usFullNameLength = sizeof( WCHAR) +
3805 AFSServerName.Length +
3806 pCcb->FullFileName.Length;
3808 if( *Length >= (LONG)(FIELD_OFFSET( FILE_NAME_INFORMATION, FileName) + (LONG)usFullNameLength))
3810 ulCopyLength = (LONG)usFullNameLength;
3814 ulCopyLength = *Length - FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
3815 ntStatus = STATUS_BUFFER_OVERFLOW;
3818 pNameInfo->FileNameLength = (ULONG)usFullNameLength;
3820 *Length -= FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
3822 if( ulCopyLength > 0)
3825 pNameInfo->FileName[ 0] = L'\\';
3826 ulCopyLength -= sizeof( WCHAR);
3828 *Length -= sizeof( WCHAR);
3830 if( ulCopyLength >= AFSServerName.Length)
3833 RtlCopyMemory( &pNameInfo->FileName[ 1],
3834 AFSServerName.Buffer,
3835 AFSServerName.Length);
3837 ulCopyLength -= AFSServerName.Length;
3838 *Length -= AFSServerName.Length;
3840 if( ulCopyLength >= pCcb->FullFileName.Length)
3843 RtlCopyMemory( &pNameInfo->FileName[ 1 + (AFSServerName.Length/sizeof( WCHAR))],
3844 pCcb->FullFileName.Buffer,
3845 pCcb->FullFileName.Length);
3847 ulCopyLength -= pCcb->FullFileName.Length;
3848 *Length -= pCcb->FullFileName.Length;
3850 uniName.Length = (USHORT)pNameInfo->FileNameLength;
3851 uniName.MaximumLength = uniName.Length;
3852 uniName.Buffer = pNameInfo->FileName;
3857 RtlCopyMemory( &pNameInfo->FileName[ 1 + (AFSServerName.Length/sizeof( WCHAR))],
3858 pCcb->FullFileName.Buffer,
3861 *Length -= ulCopyLength;
3863 uniName.Length = (USHORT)(sizeof( WCHAR) + AFSServerName.Length + ulCopyLength);
3864 uniName.MaximumLength = uniName.Length;
3865 uniName.Buffer = pNameInfo->FileName;
3868 AFSDbgLogMsg( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
3869 AFS_TRACE_LEVEL_VERBOSE,
3870 "AFSProcessPIOCtlQueryInfo (FileNameInformation) Returning %wZ\n",
3878 case FileInternalInformation:
3881 PFILE_INTERNAL_INFORMATION pInternalInfo = (PFILE_INTERNAL_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
3883 AFSDbgLogMsg( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
3884 AFS_TRACE_LEVEL_VERBOSE,
3885 "AFSProcessPIOCtlQueryInfo (FileInternalInformation)\n");
3887 if( *Length >= sizeof( FILE_INTERNAL_INFORMATION))
3890 pInternalInfo->IndexNumber.HighPart = 0;
3892 pInternalInfo->IndexNumber.LowPart = 0;
3894 *Length -= sizeof( FILE_INTERNAL_INFORMATION);
3899 ntStatus = STATUS_BUFFER_TOO_SMALL;
3905 case FileAllInformation:
3907 ntStatus = STATUS_INVALID_PARAMETER;
3909 AFSDbgLogMsg( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
3910 AFS_TRACE_LEVEL_WARNING,
3911 "AFSProcessPIOCtlQueryInfo (FileAllInformation) Not Implemented\n");
3916 case FileEaInformation:
3918 ntStatus = STATUS_INVALID_PARAMETER;
3920 AFSDbgLogMsg( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
3921 AFS_TRACE_LEVEL_WARNING,
3922 "AFSProcessPIOCtlQueryInfo (FileEaInformation) Not Implemented\n");
3927 case FilePositionInformation:
3929 ntStatus = STATUS_INVALID_PARAMETER;
3931 AFSDbgLogMsg( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
3932 AFS_TRACE_LEVEL_WARNING,
3933 "AFSProcessPIOCtlQueryInfo (FilePositionInformation) Not Implemented\n");
3938 case FileAlternateNameInformation:
3940 ntStatus = STATUS_INVALID_PARAMETER;
3942 AFSDbgLogMsg( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
3943 AFS_TRACE_LEVEL_WARNING,
3944 "AFSProcessPIOCtlQueryInfo (FileAlternateNameInformation) Not Implemented\n");
3949 case FileNetworkOpenInformation:
3951 ntStatus = STATUS_INVALID_PARAMETER;
3953 AFSDbgLogMsg( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
3954 AFS_TRACE_LEVEL_WARNING,
3955 "AFSProcessPIOCtlQueryInfo (FileNetworkOpenInformation) Not Implemented\n");
3960 case FileStreamInformation:
3962 ntStatus = STATUS_INVALID_PARAMETER;
3964 AFSDbgLogMsg( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
3965 AFS_TRACE_LEVEL_WARNING,
3966 "AFSProcessPIOCtlQueryInfo (FileStreamInformation) Not Implemented\n");
3971 case FileAttributeTagInformation:
3973 ntStatus = STATUS_INVALID_PARAMETER;
3975 AFSDbgLogMsg( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
3976 AFS_TRACE_LEVEL_WARNING,
3977 "AFSProcessPIOCtlQueryInfo (FileAttributeTagInformation) Not Implemented\n");
3982 case FileRemoteProtocolInformation:
3984 ntStatus = STATUS_INVALID_PARAMETER;
3986 AFSDbgLogMsg( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
3987 AFS_TRACE_LEVEL_WARNING,
3988 "AFSProcessPIOCtlQueryInfo (FileRemoteProtocolInformation) Not Implemented\n");
3993 case FileNetworkPhysicalNameInformation:
3995 ntStatus = STATUS_INVALID_PARAMETER;
3997 AFSDbgLogMsg( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
3998 AFS_TRACE_LEVEL_WARNING,
3999 "AFSProcessPIOCtlQueryInfo (FileNetworkPhysicalNameInformation) Not Implemented\n");
4006 ntStatus = STATUS_INVALID_PARAMETER;
4008 AFSDbgLogMsg( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4009 AFS_TRACE_LEVEL_WARNING,
4010 "AFSProcessPIOCtlQueryInfo Not handling request %08lX\n",
4011 ulFileInformationClass);
4018 AFSDbgLogMsg( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4019 AFS_TRACE_LEVEL_VERBOSE,
4020 "AFSProcessPIOCtlQueryInfo ntStatus %08lX\n",