2 * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC.
3 * Copyright (c) 2009, 2010, 2011, 2014 Your File System, Inc.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * - Redistributions of source code must retain the above copyright notice,
11 * this list of conditions and the following disclaimer.
12 * - Redistributions in binary form must reproduce the above copyright
14 * this list of conditions and the following disclaimer in the
16 * and/or other materials provided with the distribution.
17 * - Neither the names of Kernel Drivers, LLC and Your File System, Inc.
18 * nor the names of their contributors may be used to endorse or promote
19 * products derived from this software without specific prior written
20 * permission from Kernel Drivers, LLC and Your File System, Inc.
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
24 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
25 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
26 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 // File: AFSFileInfo.cpp
39 #include "AFSCommon.h"
42 // Function: AFSQueryFileInfo
46 // This function is the dispatch handler for the IRP_MJ_QUERY_FILE_INFORMATION request
50 // A status is returned for the function
54 AFSQueryFileInfo( IN PDEVICE_OBJECT LibDeviceObject,
58 UNREFERENCED_PARAMETER(LibDeviceObject);
59 NTSTATUS ntStatus = STATUS_SUCCESS;
60 IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
63 BOOLEAN bReleaseMain = FALSE;
65 FILE_INFORMATION_CLASS stFileInformationClass;
73 // Determine the type of request this request is
76 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
78 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
83 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
84 AFS_TRACE_LEVEL_ERROR,
85 "AFSQueryFileInfo Attempted access (%p) when pFcb == NULL\n",
88 try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST);
91 lLength = (LONG)pIrpSp->Parameters.QueryFile.Length;
92 stFileInformationClass = pIrpSp->Parameters.QueryFile.FileInformationClass;
93 pBuffer = Irp->AssociatedIrp.SystemBuffer;
95 if ( BooleanFlagOn( pFcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY))
98 RtlZeroMemory( &stAuthGroup,
101 AFSRetrieveAuthGroupFnc( (ULONGLONG)PsGetCurrentProcessId(),
102 (ULONGLONG)PsGetCurrentThreadId(),
105 ntStatus = AFSVerifyEntry( &stAuthGroup,
109 if ( NT_SUCCESS( ntStatus))
112 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
113 AFS_TRACE_LEVEL_VERBOSE,
114 "AFSQueryFileInfo FID %08lX-%08lX-%08lX-%08lX Clearing Verify Flag\n",
115 pFcb->ObjectInformation->FileId.Cell,
116 pFcb->ObjectInformation->FileId.Volume,
117 pFcb->ObjectInformation->FileId.Vnode,
118 pFcb->ObjectInformation->FileId.Unique));
120 ClearFlag( pFcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY);
125 ntStatus = STATUS_SUCCESS;
130 // Grab the main shared right off the bat
133 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
134 AFS_TRACE_LEVEL_VERBOSE,
135 "AFSQueryFileInfo Acquiring Fcb lock %p SHARED %08lX\n",
136 &pFcb->NPFcb->Resource,
137 PsGetCurrentThread()));
139 AFSAcquireShared( &pFcb->NPFcb->Resource,
145 // Don't allow requests against IOCtl nodes
148 if( pFcb->Header.NodeTypeCode == AFS_SPECIAL_SHARE_FCB)
151 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
152 AFS_TRACE_LEVEL_VERBOSE,
153 "AFSQueryFileInfo Processing request against SpecialShare Fcb\n"));
155 ntStatus = AFSProcessShareQueryInfo( Irp,
159 try_return( ntStatus);
161 else if( pFcb->Header.NodeTypeCode == AFS_IOCTL_FCB)
163 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
164 AFS_TRACE_LEVEL_VERBOSE,
165 "AFSQueryFileInfo request against PIOCtl Fcb\n"));
167 ntStatus = AFSProcessPIOCtlQueryInfo( Irp,
172 try_return( ntStatus);
175 else if( pFcb->Header.NodeTypeCode == AFS_INVALID_FCB)
177 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
178 AFS_TRACE_LEVEL_VERBOSE,
179 "AFSQueryFileInfo request against Invalid Fcb\n"));
181 try_return( ntStatus = STATUS_ACCESS_DENIED);
185 // Process the request
188 switch( stFileInformationClass)
191 case FileAllInformation:
194 PFILE_ALL_INFORMATION pAllInfo;
197 // For the all information class we'll typecast a local
198 // pointer to the output buffer and then call the
199 // individual routines to fill in the buffer.
202 pAllInfo = (PFILE_ALL_INFORMATION)pBuffer;
204 ntStatus = AFSQueryBasicInfo( Irp,
206 &pAllInfo->BasicInformation,
209 if( !NT_SUCCESS( ntStatus))
212 try_return( ntStatus);
215 ntStatus = AFSQueryStandardInfo( Irp,
217 &pAllInfo->StandardInformation,
220 if( !NT_SUCCESS( ntStatus))
223 try_return( ntStatus);
226 ntStatus = AFSQueryInternalInfo( Irp,
228 &pAllInfo->InternalInformation,
231 if( !NT_SUCCESS( ntStatus))
234 try_return( ntStatus);
237 ntStatus = AFSQueryEaInfo( Irp,
239 &pAllInfo->EaInformation,
242 if( !NT_SUCCESS( ntStatus))
245 try_return( ntStatus);
249 // We skip setting AccessInformation since this is set by the IO Mgr prior
250 // to sending this request to the file system
253 if( lLength < sizeof( FILE_ACCESS_INFORMATION))
255 try_return( ntStatus = STATUS_INFO_LENGTH_MISMATCH);
258 lLength -= sizeof( FILE_ACCESS_INFORMATION);
260 ntStatus = AFSQueryPositionInfo( Irp,
262 &pAllInfo->PositionInformation,
265 if( !NT_SUCCESS( ntStatus))
268 try_return( ntStatus);
272 // We skip setting ModeInformation and AlignmentInformation since this is set by the IO Mgr prior
273 // to sending this request to the file system
276 if( lLength < sizeof( FILE_MODE_INFORMATION))
278 try_return( ntStatus = STATUS_INFO_LENGTH_MISMATCH);
281 lLength -= sizeof( FILE_MODE_INFORMATION);
283 if( lLength < sizeof( FILE_ALIGNMENT_INFORMATION))
285 try_return( ntStatus = STATUS_INFO_LENGTH_MISMATCH);
288 lLength -= sizeof( FILE_ALIGNMENT_INFORMATION);
291 // Populate the name information
294 ntStatus = AFSQueryNameInfo( Irp,
296 &pAllInfo->NameInformation,
299 if( !NT_SUCCESS( ntStatus))
302 try_return( ntStatus);
308 case FileBasicInformation:
311 ntStatus = AFSQueryBasicInfo( Irp,
313 (PFILE_BASIC_INFORMATION)pBuffer,
319 case FileStandardInformation:
322 ntStatus = AFSQueryStandardInfo( Irp,
324 (PFILE_STANDARD_INFORMATION)pBuffer,
330 case FileInternalInformation:
333 ntStatus = AFSQueryInternalInfo( Irp,
335 (PFILE_INTERNAL_INFORMATION)pBuffer,
341 case FileEaInformation:
344 ntStatus = AFSQueryEaInfo( Irp,
346 (PFILE_EA_INFORMATION)pBuffer,
352 case FilePositionInformation:
355 ntStatus = AFSQueryPositionInfo( Irp,
357 (PFILE_POSITION_INFORMATION)pBuffer,
363 case FileNormalizedNameInformation:
364 case FileNameInformation:
367 ntStatus = AFSQueryNameInfo( Irp,
369 (PFILE_NAME_INFORMATION)pBuffer,
375 case FileAlternateNameInformation:
378 ntStatus = AFSQueryShortNameInfo( Irp,
380 (PFILE_NAME_INFORMATION)pBuffer,
386 case FileNetworkOpenInformation:
389 ntStatus = AFSQueryNetworkInfo( Irp,
391 (PFILE_NETWORK_OPEN_INFORMATION)pBuffer,
397 case FileStreamInformation:
400 ntStatus = AFSQueryStreamInfo( Irp,
402 (FILE_STREAM_INFORMATION *)pBuffer,
409 case FileAttributeTagInformation:
412 ntStatus = AFSQueryAttribTagInfo( Irp,
414 (FILE_ATTRIBUTE_TAG_INFORMATION *)pBuffer,
420 case FileRemoteProtocolInformation:
423 ntStatus = AFSQueryRemoteProtocolInfo( Irp,
425 (FILE_REMOTE_PROTOCOL_INFORMATION *)pBuffer,
431 case FileNetworkPhysicalNameInformation:
434 ntStatus = AFSQueryPhysicalNameInfo( Irp,
436 (FILE_NETWORK_PHYSICAL_NAME_INFORMATION *)pBuffer,
444 ntStatus = STATUS_INVALID_PARAMETER;
451 Irp->IoStatus.Information = pIrpSp->Parameters.QueryFile.Length - lLength;
456 AFSReleaseResource( &pFcb->NPFcb->Resource);
459 if( !NT_SUCCESS( ntStatus) &&
460 ntStatus != STATUS_INVALID_PARAMETER &&
461 ntStatus != STATUS_BUFFER_OVERFLOW)
465 pCcb->DirectoryCB != NULL)
468 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
469 AFS_TRACE_LEVEL_ERROR,
470 "AFSQueryFileInfo Failed to process request for %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
471 &pCcb->DirectoryCB->NameInformation.FileName,
472 pFcb->ObjectInformation->FileId.Cell,
473 pFcb->ObjectInformation->FileId.Volume,
474 pFcb->ObjectInformation->FileId.Vnode,
475 pFcb->ObjectInformation->FileId.Unique,
480 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
485 "EXCEPTION - AFSQueryFileInfo\n"));
487 AFSDumpTraceFilesFnc();
489 ntStatus = STATUS_UNSUCCESSFUL;
494 AFSReleaseResource( &pFcb->NPFcb->Resource);
498 AFSCompleteRequest( Irp,
505 // Function: AFSSetFileInfo
509 // This function is the dispatch handler for the IRP_MJ_SET_FILE_INFORMATION request
513 // A status is returned for the function
517 AFSSetFileInfo( IN PDEVICE_OBJECT LibDeviceObject,
521 UNREFERENCED_PARAMETER(LibDeviceObject);
522 NTSTATUS ntStatus = STATUS_SUCCESS;
523 IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
526 FILE_INFORMATION_CLASS FileInformationClass;
527 BOOLEAN bCanQueueRequest = FALSE;
528 PFILE_OBJECT pFileObject = NULL;
529 BOOLEAN bReleaseMain = FALSE;
530 BOOLEAN bUpdateFileInfo = FALSE;
531 AFSFileID stParentFileId;
536 pFileObject = pIrpSp->FileObject;
538 pFcb = (AFSFcb *)pFileObject->FsContext;
539 pCcb = (AFSCcb *)pFileObject->FsContext2;
544 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
545 AFS_TRACE_LEVEL_ERROR,
546 "AFSSetFileInfo Attempted access (%p) when pFcb == NULL\n",
549 try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST);
552 bCanQueueRequest = !(IoIsOperationSynchronous( Irp) | (KeGetCurrentIrql() != PASSIVE_LEVEL));
553 FileInformationClass = pIrpSp->Parameters.SetFile.FileInformationClass;
559 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
560 AFS_TRACE_LEVEL_VERBOSE,
561 "AFSSetFileInfo Acquiring Fcb lock %p EXCL %08lX\n",
562 &pFcb->NPFcb->Resource,
563 PsGetCurrentThread()));
565 AFSAcquireExcl( &pFcb->NPFcb->Resource,
571 // Don't allow requests against IOCtl nodes
574 if( pFcb->Header.NodeTypeCode == AFS_IOCTL_FCB)
577 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
578 AFS_TRACE_LEVEL_ERROR,
579 "AFSSetFileInfo Failing request against PIOCtl Fcb\n"));
581 try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST);
583 else if( pFcb->Header.NodeTypeCode == AFS_SPECIAL_SHARE_FCB)
586 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
587 AFS_TRACE_LEVEL_VERBOSE,
588 "AFSSetFileInfo Processing request against SpecialShare Fcb\n"));
590 ntStatus = AFSProcessShareSetInfo( Irp,
594 try_return( ntStatus);
597 if( FileInformationClass != FilePositionInformation &&
598 BooleanFlagOn( pFcb->ObjectInformation->VolumeCB->VolumeInformation.FileSystemAttributes, FILE_READ_ONLY_VOLUME))
601 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
602 AFS_TRACE_LEVEL_ERROR,
603 "AFSSetFileInfo Request failed due to read only volume\n",
606 try_return( ntStatus = STATUS_MEDIA_WRITE_PROTECTED);
609 if( pFcb->Header.NodeTypeCode == AFS_INVALID_FCB &&
610 FileInformationClass != FileDispositionInformation)
612 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
613 AFS_TRACE_LEVEL_VERBOSE,
614 "AFSSetFileInfo request against Invalid Fcb\n"));
616 try_return( ntStatus = STATUS_ACCESS_DENIED);
620 // Ensure rename operations are synchronous
623 if( FileInformationClass == FileRenameInformation)
626 bCanQueueRequest = FALSE;
630 // Store away the parent fid
633 RtlZeroMemory( &stParentFileId,
636 if( BooleanFlagOn( pFcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
639 stParentFileId = pFcb->ObjectInformation->ParentFileId;
643 // Process the request
646 switch( FileInformationClass)
649 case FileBasicInformation:
652 ntStatus = AFSSetBasicInfo( Irp,
659 case FileDispositionInformation:
662 ntStatus = AFSSetDispositionInfo( Irp,
668 case FileRenameInformation:
671 ntStatus = AFSSetRenameInfo( Irp);
676 case FilePositionInformation:
679 ntStatus = AFSSetPositionInfo( Irp,
685 case FileLinkInformation:
688 ntStatus = AFSSetFileLinkInfo( Irp);
693 case FileAllocationInformation:
696 ntStatus = AFSSetAllocationInfo( Irp,
702 case FileEndOfFileInformation:
705 ntStatus = AFSSetEndOfFileInfo( Irp,
713 ntStatus = STATUS_INVALID_PARAMETER;
723 AFSReleaseResource( &pFcb->NPFcb->Resource);
726 if( NT_SUCCESS( ntStatus) &&
730 ntStatus = AFSUpdateFileInformation( &stParentFileId,
731 pFcb->ObjectInformation,
734 if( !NT_SUCCESS( ntStatus))
737 AFSAcquireExcl( &pFcb->NPFcb->Resource,
741 // Unwind the update and fail the request
744 AFSUnwindFileInfo( pFcb,
747 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
748 AFS_TRACE_LEVEL_ERROR,
749 "AFSSetFileInfo Failed to send file info update to service request for %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
750 &pCcb->DirectoryCB->NameInformation.FileName,
751 pFcb->ObjectInformation->FileId.Cell,
752 pFcb->ObjectInformation->FileId.Volume,
753 pFcb->ObjectInformation->FileId.Vnode,
754 pFcb->ObjectInformation->FileId.Unique,
757 AFSReleaseResource( &pFcb->NPFcb->Resource);
761 if( !NT_SUCCESS( ntStatus))
765 pCcb->DirectoryCB != NULL)
768 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
769 AFS_TRACE_LEVEL_ERROR,
770 "AFSSetFileInfo Failed to process request for %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
771 &pCcb->DirectoryCB->NameInformation.FileName,
772 pFcb->ObjectInformation->FileId.Cell,
773 pFcb->ObjectInformation->FileId.Volume,
774 pFcb->ObjectInformation->FileId.Vnode,
775 pFcb->ObjectInformation->FileId.Unique,
780 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
785 "EXCEPTION - AFSSetFileInfo\n"));
787 AFSDumpTraceFilesFnc();
789 ntStatus = STATUS_UNSUCCESSFUL;
794 AFSReleaseResource( &pFcb->NPFcb->Resource);
798 AFSCompleteRequest( Irp,
805 // Function: AFSQueryBasicInfo
809 // This function is the handler for the query basic information request
813 // A status is returned for the function
817 AFSQueryBasicInfo( IN PIRP Irp,
818 IN AFSDirectoryCB *DirectoryCB,
819 IN OUT PFILE_BASIC_INFORMATION Buffer,
822 NTSTATUS ntStatus = STATUS_INFO_LENGTH_MISMATCH;
823 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
824 ULONG ulFileAttribs = 0;
827 IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
828 AFSFileInfoCB stFileInfo;
829 AFSDirectoryCB *pParentDirectoryCB = NULL;
830 UNICODE_STRING uniParentPath;
832 if( *Length >= sizeof( FILE_BASIC_INFORMATION))
835 RtlZeroMemory( Buffer,
838 ulFileAttribs = DirectoryCB->ObjectInformation->FileAttributes;
840 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
841 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
843 if( DirectoryCB->ObjectInformation->FileType == AFS_FILE_TYPE_SYMLINK)
846 pParentDirectoryCB = AFSGetParentEntry( pCcb->NameArray);
848 AFSRetrieveParentPath( &pCcb->FullFileName,
851 RtlZeroMemory( &stFileInfo,
852 sizeof( AFSFileInfoCB));
855 // Can't hold the Fcb while evaluating the path, leads to lock inversion
858 AFSReleaseResource( &pFcb->NPFcb->Resource);
861 // Its a reparse point regardless of whether the file attributes
862 // can be retrieved for the target.
865 if ( ulFileAttribs == FILE_ATTRIBUTE_NORMAL)
868 ulFileAttribs = FILE_ATTRIBUTE_REPARSE_POINT;
873 ulFileAttribs |= FILE_ATTRIBUTE_REPARSE_POINT;
876 if( NT_SUCCESS( AFSRetrieveFileAttributes( pParentDirectoryCB,
884 if ( stFileInfo.FileAttributes & FILE_ATTRIBUTE_DIRECTORY)
887 ulFileAttribs |= FILE_ATTRIBUTE_DIRECTORY;
891 AFSAcquireShared( &pFcb->NPFcb->Resource,
896 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
897 AFS_TRACE_LEVEL_VERBOSE_2,
898 "AFSQueryBasicInfo %wZ Type 0x%x Attrib 0x%x -> 0x%x\n",
899 &pCcb->DirectoryCB->NameInformation.FileName,
900 pFcb->ObjectInformation->FileType,
901 pFcb->ObjectInformation->FileAttributes,
904 Buffer->CreationTime = DirectoryCB->ObjectInformation->CreationTime;
905 Buffer->LastAccessTime = DirectoryCB->ObjectInformation->LastAccessTime;
906 Buffer->LastWriteTime = DirectoryCB->ObjectInformation->LastWriteTime;
907 Buffer->ChangeTime = DirectoryCB->ObjectInformation->ChangeTime;
908 Buffer->FileAttributes = ulFileAttribs;
910 if( DirectoryCB->NameInformation.FileName.Buffer[ 0] == L'.' &&
911 BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_HIDE_DOT_NAMES))
914 if ( Buffer->FileAttributes != FILE_ATTRIBUTE_NORMAL)
916 Buffer->FileAttributes |= FILE_ATTRIBUTE_HIDDEN;
920 Buffer->FileAttributes = FILE_ATTRIBUTE_HIDDEN;
924 *Length -= sizeof( FILE_BASIC_INFORMATION);
926 ntStatus = STATUS_SUCCESS;
933 AFSQueryStandardInfo( IN PIRP Irp,
934 IN AFSDirectoryCB *DirectoryCB,
935 IN OUT PFILE_STANDARD_INFORMATION Buffer,
939 NTSTATUS ntStatus = STATUS_INFO_LENGTH_MISMATCH;
942 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
943 AFSFileInfoCB stFileInfo;
944 AFSDirectoryCB *pParentDirectoryCB = NULL;
945 UNICODE_STRING uniParentPath;
946 ULONG ulFileAttribs = 0;
948 if( *Length >= sizeof( FILE_STANDARD_INFORMATION))
951 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
952 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
954 RtlZeroMemory( Buffer,
957 Buffer->NumberOfLinks = 1;
958 Buffer->DeletePending = BooleanFlagOn( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
960 Buffer->AllocationSize.QuadPart = (ULONGLONG)((DirectoryCB->ObjectInformation->AllocationSize.QuadPart/PAGE_SIZE) + 1) * PAGE_SIZE;
962 Buffer->EndOfFile = DirectoryCB->ObjectInformation->EndOfFile;
964 ulFileAttribs = DirectoryCB->ObjectInformation->FileAttributes;
966 if( DirectoryCB->ObjectInformation->FileType == AFS_FILE_TYPE_SYMLINK)
969 pParentDirectoryCB = AFSGetParentEntry( pCcb->NameArray);
971 AFSRetrieveParentPath( &pCcb->FullFileName,
974 RtlZeroMemory( &stFileInfo,
975 sizeof( AFSFileInfoCB));
978 // Can't hold the Fcb while evaluating the path, leads to lock inversion
981 AFSReleaseResource( &pFcb->NPFcb->Resource);
984 // Its a reparse point regardless of whether or not the
985 // file attributes can be retrieved.
988 if ( ulFileAttribs == FILE_ATTRIBUTE_NORMAL)
991 ulFileAttribs = FILE_ATTRIBUTE_REPARSE_POINT;
996 ulFileAttribs |= FILE_ATTRIBUTE_REPARSE_POINT;
999 if( NT_SUCCESS( AFSRetrieveFileAttributes( pParentDirectoryCB,
1007 if ( stFileInfo.FileAttributes & FILE_ATTRIBUTE_DIRECTORY)
1010 ulFileAttribs |= FILE_ATTRIBUTE_DIRECTORY;
1014 AFSAcquireShared( &pFcb->NPFcb->Resource,
1018 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1019 AFS_TRACE_LEVEL_VERBOSE_2,
1020 "AFSQueryStandardInfo %wZ Type 0x%x Attrib 0x%x -> 0x%x\n",
1021 &pCcb->DirectoryCB->NameInformation.FileName,
1022 pFcb->ObjectInformation->FileType,
1023 pFcb->ObjectInformation->FileAttributes,
1026 Buffer->Directory = BooleanFlagOn( ulFileAttribs, FILE_ATTRIBUTE_DIRECTORY);
1028 *Length -= sizeof( FILE_STANDARD_INFORMATION);
1030 ntStatus = STATUS_SUCCESS;
1037 AFSQueryInternalInfo( IN PIRP Irp,
1039 IN OUT PFILE_INTERNAL_INFORMATION Buffer,
1040 IN OUT PLONG Length)
1043 UNREFERENCED_PARAMETER(Irp);
1044 NTSTATUS ntStatus = STATUS_INFO_LENGTH_MISMATCH;
1046 if( *Length >= sizeof( FILE_INTERNAL_INFORMATION))
1049 Buffer->IndexNumber.HighPart = Fcb->ObjectInformation->FileId.Vnode;
1051 Buffer->IndexNumber.LowPart = Fcb->ObjectInformation->FileId.Unique;
1053 *Length -= sizeof( FILE_INTERNAL_INFORMATION);
1055 ntStatus = STATUS_SUCCESS;
1062 AFSQueryEaInfo( IN PIRP Irp,
1063 IN AFSDirectoryCB *DirectoryCB,
1064 IN OUT PFILE_EA_INFORMATION Buffer,
1065 IN OUT PLONG Length)
1068 UNREFERENCED_PARAMETER(Irp);
1069 UNREFERENCED_PARAMETER(DirectoryCB);
1070 NTSTATUS ntStatus = STATUS_INFO_LENGTH_MISMATCH;
1072 RtlZeroMemory( Buffer,
1075 if( *Length >= sizeof( FILE_EA_INFORMATION))
1080 *Length -= sizeof( FILE_EA_INFORMATION);
1082 ntStatus = STATUS_SUCCESS;
1089 AFSQueryPositionInfo( IN PIRP Irp,
1091 IN OUT PFILE_POSITION_INFORMATION Buffer,
1092 IN OUT PLONG Length)
1095 UNREFERENCED_PARAMETER(Fcb);
1096 NTSTATUS ntStatus = STATUS_INFO_LENGTH_MISMATCH;
1097 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1099 if( *Length >= sizeof( FILE_POSITION_INFORMATION))
1102 RtlZeroMemory( Buffer,
1105 Buffer->CurrentByteOffset.QuadPart = pIrpSp->FileObject->CurrentByteOffset.QuadPart;
1107 *Length -= sizeof( FILE_POSITION_INFORMATION);
1109 ntStatus = STATUS_SUCCESS;
1116 AFSQueryNameInfo( IN PIRP Irp,
1117 IN AFSDirectoryCB *DirectoryCB,
1118 IN OUT PFILE_NAME_INFORMATION Buffer,
1119 IN OUT PLONG Length)
1122 UNREFERENCED_PARAMETER(DirectoryCB);
1123 NTSTATUS ntStatus = STATUS_INFO_LENGTH_MISMATCH;
1124 AFSFcb *pFcb = NULL;
1125 AFSCcb *pCcb = NULL;
1126 IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1128 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
1130 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
1132 if( *Length >= FIELD_OFFSET( FILE_NAME_INFORMATION, FileName))
1135 RtlZeroMemory( Buffer,
1138 *Length -= FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
1140 ntStatus = AFSGetFullFileName( pFcb,
1142 &Buffer->FileNameLength,
1151 AFSQueryShortNameInfo( IN PIRP Irp,
1152 IN AFSDirectoryCB *DirectoryCB,
1153 IN OUT PFILE_NAME_INFORMATION Buffer,
1154 IN OUT PLONG Length)
1157 UNREFERENCED_PARAMETER(Irp);
1158 NTSTATUS ntStatus = STATUS_INFO_LENGTH_MISMATCH;
1159 ULONG ulCopyLength = 0;
1161 RtlZeroMemory( Buffer,
1164 if( DirectoryCB->NameInformation.ShortNameLength == 0)
1168 // The short name IS the long name
1171 if( *Length >= (LONG)FIELD_OFFSET( FILE_NAME_INFORMATION, FileName))
1174 if( *Length >= (LONG)(FIELD_OFFSET( FILE_NAME_INFORMATION, FileName) + (LONG)DirectoryCB->NameInformation.FileName.Length))
1177 ulCopyLength = (LONG)DirectoryCB->NameInformation.FileName.Length;
1179 ntStatus = STATUS_SUCCESS;
1184 ulCopyLength = *Length - FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
1186 ntStatus = STATUS_BUFFER_OVERFLOW;
1189 Buffer->FileNameLength = DirectoryCB->NameInformation.FileName.Length;
1191 *Length -= FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
1193 if( ulCopyLength > 0)
1196 RtlCopyMemory( Buffer->FileName,
1197 DirectoryCB->NameInformation.FileName.Buffer,
1200 *Length -= ulCopyLength;
1207 if( *Length >= (LONG)FIELD_OFFSET( FILE_NAME_INFORMATION, FileName))
1210 if( *Length >= (LONG)(FIELD_OFFSET( FILE_NAME_INFORMATION, FileName) + (LONG)DirectoryCB->NameInformation.FileName.Length))
1213 ulCopyLength = (LONG)DirectoryCB->NameInformation.ShortNameLength;
1215 ntStatus = STATUS_SUCCESS;
1220 ulCopyLength = *Length - FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
1222 ntStatus = STATUS_BUFFER_OVERFLOW;
1225 Buffer->FileNameLength = DirectoryCB->NameInformation.ShortNameLength;
1227 *Length -= FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
1229 if( ulCopyLength > 0)
1232 RtlCopyMemory( Buffer->FileName,
1233 DirectoryCB->NameInformation.ShortName,
1234 Buffer->FileNameLength);
1236 *Length -= ulCopyLength;
1245 AFSQueryNetworkInfo( IN PIRP Irp,
1246 IN AFSDirectoryCB *DirectoryCB,
1247 IN OUT PFILE_NETWORK_OPEN_INFORMATION Buffer,
1248 IN OUT PLONG Length)
1251 NTSTATUS ntStatus = STATUS_INFO_LENGTH_MISMATCH;
1252 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1253 AFSFcb *pFcb = NULL;
1254 AFSCcb *pCcb = NULL;
1255 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1256 AFSFileInfoCB stFileInfo;
1257 AFSDirectoryCB *pParentDirectoryCB = NULL;
1258 UNICODE_STRING uniParentPath;
1259 ULONG ulFileAttribs = 0;
1261 RtlZeroMemory( Buffer,
1264 if( *Length >= sizeof( FILE_NETWORK_OPEN_INFORMATION))
1267 ulFileAttribs = DirectoryCB->ObjectInformation->FileAttributes;
1269 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
1270 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
1272 if( DirectoryCB->ObjectInformation->FileType == AFS_FILE_TYPE_SYMLINK)
1275 pParentDirectoryCB = AFSGetParentEntry( pCcb->NameArray);
1277 AFSRetrieveParentPath( &pCcb->FullFileName,
1280 RtlZeroMemory( &stFileInfo,
1281 sizeof( AFSFileInfoCB));
1284 // Can't hold the Fcb while evaluating the path, leads to lock inversion
1287 AFSReleaseResource( &pFcb->NPFcb->Resource);
1290 // Its a reparse point regardless of whether the file attributes
1291 // can be retrieved for the target.
1294 if ( ulFileAttribs == FILE_ATTRIBUTE_NORMAL)
1297 ulFileAttribs = FILE_ATTRIBUTE_REPARSE_POINT;
1302 ulFileAttribs |= FILE_ATTRIBUTE_REPARSE_POINT;
1305 if( NT_SUCCESS( AFSRetrieveFileAttributes( pParentDirectoryCB,
1313 if ( stFileInfo.FileAttributes & FILE_ATTRIBUTE_DIRECTORY)
1316 ulFileAttribs |= FILE_ATTRIBUTE_DIRECTORY;
1320 AFSAcquireShared( &pFcb->NPFcb->Resource,
1324 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1325 AFS_TRACE_LEVEL_VERBOSE_2,
1326 "AFSQueryNetworkInfo %wZ Type 0x%x Attrib 0x%x -> 0x%x\n",
1327 &pCcb->DirectoryCB->NameInformation.FileName,
1328 pFcb->ObjectInformation->FileType,
1329 pFcb->ObjectInformation->FileAttributes,
1332 Buffer->CreationTime.QuadPart = DirectoryCB->ObjectInformation->CreationTime.QuadPart;
1333 Buffer->LastAccessTime.QuadPart = DirectoryCB->ObjectInformation->LastAccessTime.QuadPart;
1334 Buffer->LastWriteTime.QuadPart = DirectoryCB->ObjectInformation->LastWriteTime.QuadPart;
1335 Buffer->ChangeTime.QuadPart = DirectoryCB->ObjectInformation->ChangeTime.QuadPart;
1337 Buffer->AllocationSize.QuadPart = DirectoryCB->ObjectInformation->AllocationSize.QuadPart;
1338 Buffer->EndOfFile.QuadPart = DirectoryCB->ObjectInformation->EndOfFile.QuadPart;
1340 Buffer->FileAttributes = ulFileAttribs;
1342 if( DirectoryCB->NameInformation.FileName.Buffer[ 0] == L'.' &&
1343 BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_HIDE_DOT_NAMES))
1346 if ( Buffer->FileAttributes != FILE_ATTRIBUTE_NORMAL)
1349 Buffer->FileAttributes |= FILE_ATTRIBUTE_HIDDEN;
1354 Buffer->FileAttributes = FILE_ATTRIBUTE_HIDDEN;
1358 *Length -= sizeof( FILE_NETWORK_OPEN_INFORMATION);
1360 ntStatus = STATUS_SUCCESS;
1367 AFSQueryStreamInfo( IN PIRP Irp,
1368 IN AFSDirectoryCB *DirectoryCB,
1369 IN OUT FILE_STREAM_INFORMATION *Buffer,
1370 IN OUT PLONG Length)
1373 UNREFERENCED_PARAMETER(Irp);
1374 NTSTATUS ntStatus = STATUS_INFO_LENGTH_MISMATCH;
1375 ULONG ulCopyLength = 0;
1377 if( *Length >= FIELD_OFFSET( FILE_STREAM_INFORMATION, StreamName))
1380 RtlZeroMemory( Buffer,
1383 Buffer->NextEntryOffset = 0;
1386 if( !BooleanFlagOn( DirectoryCB->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_DIRECTORY))
1389 if( *Length >= (LONG)(FIELD_OFFSET( FILE_STREAM_INFORMATION, StreamName) + 14)) // ::$DATA
1394 ntStatus = STATUS_SUCCESS;
1399 ulCopyLength = *Length - FIELD_OFFSET( FILE_STREAM_INFORMATION, StreamName);
1401 ntStatus = STATUS_BUFFER_OVERFLOW;
1404 Buffer->StreamNameLength = 14; // ::$DATA
1406 Buffer->StreamSize.QuadPart = DirectoryCB->ObjectInformation->EndOfFile.QuadPart;
1408 Buffer->StreamAllocationSize.QuadPart = DirectoryCB->ObjectInformation->AllocationSize.QuadPart;
1410 *Length -= FIELD_OFFSET( FILE_STREAM_INFORMATION, StreamName);
1412 if( ulCopyLength > 0)
1415 RtlCopyMemory( Buffer->StreamName,
1419 *Length -= ulCopyLength;
1425 Buffer->StreamNameLength = 0; // No stream for a directory
1427 // The response size is zero
1429 ntStatus = STATUS_SUCCESS;
1437 AFSQueryAttribTagInfo( IN PIRP Irp,
1438 IN AFSDirectoryCB *DirectoryCB,
1439 IN OUT FILE_ATTRIBUTE_TAG_INFORMATION *Buffer,
1440 IN OUT PLONG Length)
1443 NTSTATUS ntStatus = STATUS_INFO_LENGTH_MISMATCH;
1444 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1445 AFSFcb *pFcb = NULL;
1446 AFSCcb *pCcb = NULL;
1447 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1448 AFSFileInfoCB stFileInfo;
1449 AFSDirectoryCB *pParentDirectoryCB = NULL;
1450 UNICODE_STRING uniParentPath;
1451 ULONG ulFileAttribs = 0;
1453 if( *Length >= sizeof( FILE_ATTRIBUTE_TAG_INFORMATION))
1456 RtlZeroMemory( Buffer,
1459 ulFileAttribs = DirectoryCB->ObjectInformation->FileAttributes;
1461 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
1462 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
1464 if( DirectoryCB->ObjectInformation->FileType == AFS_FILE_TYPE_SYMLINK)
1467 pParentDirectoryCB = AFSGetParentEntry( pCcb->NameArray);
1469 AFSRetrieveParentPath( &pCcb->FullFileName,
1472 RtlZeroMemory( &stFileInfo,
1473 sizeof( AFSFileInfoCB));
1476 // Can't hold the Fcb while evaluating the path, leads to lock inversion
1479 AFSReleaseResource( &pFcb->NPFcb->Resource);
1482 // Its a reparse point regardless of whether the file attributes
1483 // can be retrieved for the target.
1486 if ( ulFileAttribs == FILE_ATTRIBUTE_NORMAL)
1489 ulFileAttribs = FILE_ATTRIBUTE_REPARSE_POINT;
1494 ulFileAttribs |= FILE_ATTRIBUTE_REPARSE_POINT;
1497 if( NT_SUCCESS( AFSRetrieveFileAttributes( pParentDirectoryCB,
1505 if ( stFileInfo.FileAttributes & FILE_ATTRIBUTE_DIRECTORY)
1508 ulFileAttribs |= FILE_ATTRIBUTE_DIRECTORY;
1512 AFSAcquireShared( &pFcb->NPFcb->Resource,
1516 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1517 AFS_TRACE_LEVEL_VERBOSE_2,
1518 "AFSAttribTagInfo %wZ Type 0x%x Attrib 0x%x -> 0x%x\n",
1519 &pCcb->DirectoryCB->NameInformation.FileName,
1520 pFcb->ObjectInformation->FileType,
1521 pFcb->ObjectInformation->FileAttributes,
1524 Buffer->FileAttributes = ulFileAttribs;
1526 if( DirectoryCB->NameInformation.FileName.Buffer[ 0] == L'.' &&
1527 BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_HIDE_DOT_NAMES))
1530 if ( Buffer->FileAttributes != FILE_ATTRIBUTE_NORMAL)
1533 Buffer->FileAttributes |= FILE_ATTRIBUTE_HIDDEN;
1538 Buffer->FileAttributes = FILE_ATTRIBUTE_HIDDEN;
1542 if ( DirectoryCB->ObjectInformation->FileType == AFS_FILE_TYPE_MOUNTPOINT)
1545 Buffer->ReparseTag = IO_REPARSE_TAG_SURROGATE|IO_REPARSE_TAG_OPENAFS_DFS;
1547 else if( BooleanFlagOn( DirectoryCB->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_REPARSE_POINT))
1550 Buffer->ReparseTag = IO_REPARSE_TAG_SYMLINK;
1553 *Length -= sizeof( FILE_ATTRIBUTE_TAG_INFORMATION);
1555 ntStatus = STATUS_SUCCESS;
1562 AFSQueryRemoteProtocolInfo( IN PIRP Irp,
1563 IN AFSDirectoryCB *DirectoryCB,
1564 IN OUT FILE_REMOTE_PROTOCOL_INFORMATION *Buffer,
1565 IN OUT PLONG Length)
1568 UNREFERENCED_PARAMETER(Irp);
1569 UNREFERENCED_PARAMETER(DirectoryCB);
1570 NTSTATUS ntStatus = STATUS_INFO_LENGTH_MISMATCH;
1572 if( *Length >= sizeof( FILE_REMOTE_PROTOCOL_INFORMATION))
1575 RtlZeroMemory( Buffer,
1578 Buffer->StructureVersion = 1;
1580 Buffer->StructureSize = sizeof(FILE_REMOTE_PROTOCOL_INFORMATION);
1582 Buffer->Protocol = WNNC_NET_OPENAFS;
1584 Buffer->ProtocolMajorVersion = 3;
1586 Buffer->ProtocolMinorVersion = 0;
1588 Buffer->ProtocolRevision = 0;
1590 *Length -= sizeof( FILE_REMOTE_PROTOCOL_INFORMATION);
1592 ntStatus = STATUS_SUCCESS;
1599 AFSQueryPhysicalNameInfo( IN PIRP Irp,
1600 IN AFSDirectoryCB *DirectoryCB,
1601 IN OUT PFILE_NETWORK_PHYSICAL_NAME_INFORMATION Buffer,
1602 IN OUT PLONG Length)
1605 UNREFERENCED_PARAMETER(DirectoryCB);
1606 NTSTATUS ntStatus = STATUS_INFO_LENGTH_MISMATCH;
1607 AFSFcb *pFcb = NULL;
1608 AFSCcb *pCcb = NULL;
1609 IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1611 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
1613 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
1615 if( *Length >= FIELD_OFFSET( FILE_NETWORK_PHYSICAL_NAME_INFORMATION, FileName))
1618 RtlZeroMemory( Buffer,
1621 *Length -= FIELD_OFFSET( FILE_NETWORK_PHYSICAL_NAME_INFORMATION, FileName);
1623 ntStatus = AFSGetFullFileName( pFcb,
1625 &Buffer->FileNameLength,
1634 AFSSetBasicInfo( IN PIRP Irp,
1635 IN AFSDirectoryCB *DirectoryCB,
1636 OUT BOOLEAN *bUpdateFileInfo)
1638 NTSTATUS ntStatus = STATUS_SUCCESS;
1639 PFILE_BASIC_INFORMATION pBuffer;
1640 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1641 ULONG ulNotifyFilter = 0;
1642 AFSCcb *pCcb = NULL;
1647 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
1649 pBuffer = (PFILE_BASIC_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
1651 pCcb->FileUnwindInfo.FileAttributes = (ULONG)-1;
1653 if( pBuffer->FileAttributes != (ULONGLONG)0)
1657 // Make sure that the reparse point attribute is not modified.
1658 // Fail if the RP attribute is requested but it is not
1659 // already a RP. Otherwise, ignore it.
1662 if ( !BooleanFlagOn( DirectoryCB->ObjectInformation->FileAttributes,
1663 FILE_ATTRIBUTE_REPARSE_POINT) &&
1664 BooleanFlagOn( pBuffer->FileAttributes,
1665 FILE_ATTRIBUTE_REPARSE_POINT))
1668 try_return( ntStatus = STATUS_INVALID_PARAMETER);
1672 // Make sure that the directory attribute is not modified.
1673 // Fail if the D attribute is requested but it is not
1674 // already a directory. Otherwise, ignore it.
1677 if ( !BooleanFlagOn( DirectoryCB->ObjectInformation->FileAttributes,
1678 FILE_ATTRIBUTE_DIRECTORY) &&
1679 BooleanFlagOn( pBuffer->FileAttributes,
1680 FILE_ATTRIBUTE_DIRECTORY))
1683 try_return( ntStatus = STATUS_INVALID_PARAMETER);
1687 // Save the original value
1690 pCcb->FileUnwindInfo.FileAttributes = DirectoryCB->ObjectInformation->FileAttributes;
1692 if( BooleanFlagOn( pBuffer->FileAttributes, FILE_ATTRIBUTE_READONLY))
1696 // Set the readonly flag.
1699 if ( !BooleanFlagOn( DirectoryCB->ObjectInformation->FileAttributes,
1700 FILE_ATTRIBUTE_READONLY))
1703 if ( DirectoryCB->ObjectInformation->FileAttributes == FILE_ATTRIBUTE_NORMAL)
1706 DirectoryCB->ObjectInformation->FileAttributes = FILE_ATTRIBUTE_READONLY;
1711 DirectoryCB->ObjectInformation->FileAttributes |= FILE_ATTRIBUTE_READONLY;
1714 ulNotifyFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
1716 SetFlag( DirectoryCB->ObjectInformation->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED);
1722 // Reset the readonly flag.
1725 if ( BooleanFlagOn( DirectoryCB->ObjectInformation->FileAttributes,
1726 FILE_ATTRIBUTE_READONLY))
1729 DirectoryCB->ObjectInformation->FileAttributes &= ~FILE_ATTRIBUTE_READONLY;
1731 if ( DirectoryCB->ObjectInformation->FileAttributes == 0)
1734 DirectoryCB->ObjectInformation->FileAttributes = FILE_ATTRIBUTE_NORMAL;
1737 ulNotifyFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
1739 SetFlag( DirectoryCB->ObjectInformation->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED);
1744 pCcb->FileUnwindInfo.CreationTime.QuadPart = (ULONGLONG)-1;
1746 if( pBuffer->CreationTime.QuadPart != (ULONGLONG)-1 &&
1747 pBuffer->CreationTime.QuadPart != (ULONGLONG)0)
1750 pCcb->FileUnwindInfo.CreationTime.QuadPart = DirectoryCB->ObjectInformation->CreationTime.QuadPart;
1752 DirectoryCB->ObjectInformation->CreationTime.QuadPart = pBuffer->CreationTime.QuadPart;
1754 ulNotifyFilter |= FILE_NOTIFY_CHANGE_CREATION;
1756 SetFlag( DirectoryCB->ObjectInformation->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_CREATE_TIME);
1759 pCcb->FileUnwindInfo.LastAccessTime.QuadPart = (ULONGLONG)-1;
1761 if( pBuffer->LastAccessTime.QuadPart != (ULONGLONG)-1 &&
1762 pBuffer->LastAccessTime.QuadPart != (ULONGLONG)0)
1765 pCcb->FileUnwindInfo.LastAccessTime.QuadPart = DirectoryCB->ObjectInformation->LastAccessTime.QuadPart;
1767 DirectoryCB->ObjectInformation->LastAccessTime.QuadPart = pBuffer->LastAccessTime.QuadPart;
1769 ulNotifyFilter |= FILE_NOTIFY_CHANGE_LAST_ACCESS;
1771 SetFlag( DirectoryCB->ObjectInformation->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_ACCESS_TIME);
1774 pCcb->FileUnwindInfo.LastWriteTime.QuadPart = (ULONGLONG)-1;
1776 if( pBuffer->LastWriteTime.QuadPart != (ULONGLONG)-1 &&
1777 pBuffer->LastWriteTime.QuadPart != (ULONGLONG)0)
1780 pCcb->FileUnwindInfo.LastWriteTime.QuadPart = DirectoryCB->ObjectInformation->LastWriteTime.QuadPart;
1782 DirectoryCB->ObjectInformation->LastWriteTime.QuadPart = pBuffer->LastWriteTime.QuadPart;
1784 ulNotifyFilter |= FILE_NOTIFY_CHANGE_LAST_WRITE;
1786 SetFlag( DirectoryCB->ObjectInformation->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_LAST_WRITE_TIME);
1788 SetFlag( pCcb->Flags, CCB_FLAG_LAST_WRITE_TIME_SET);
1790 } else if ( pBuffer->LastWriteTime.QuadPart == (ULONGLONG)-1) {
1792 SetFlag( pCcb->Flags, CCB_FLAG_LAST_WRITE_TIME_SET);
1795 pCcb->FileUnwindInfo.ChangeTime.QuadPart = (ULONGLONG)-1;
1797 if( pBuffer->ChangeTime.QuadPart != (ULONGLONG)-1 &&
1798 pBuffer->ChangeTime.QuadPart != (ULONGLONG)0)
1801 pCcb->FileUnwindInfo.ChangeTime.QuadPart = DirectoryCB->ObjectInformation->ChangeTime.QuadPart;
1803 DirectoryCB->ObjectInformation->ChangeTime.QuadPart = pBuffer->ChangeTime.QuadPart;
1805 ulNotifyFilter |= FILE_NOTIFY_CHANGE_LAST_ACCESS;
1807 SetFlag( DirectoryCB->ObjectInformation->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_CHANGE_TIME);
1810 if( ulNotifyFilter > 0)
1813 *bUpdateFileInfo = TRUE;
1815 if( BooleanFlagOn( DirectoryCB->ObjectInformation->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
1818 AFSObjectInfoCB * pParentObjectInfo = AFSFindObjectInfo( DirectoryCB->ObjectInformation->VolumeCB,
1819 &DirectoryCB->ObjectInformation->ParentFileId,
1822 if ( pParentObjectInfo != NULL)
1824 AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
1826 (ULONG)ulNotifyFilter,
1827 (ULONG)FILE_ACTION_MODIFIED);
1829 AFSReleaseObjectInfo( &pParentObjectInfo);
1843 AFSSetDispositionInfo( IN PIRP Irp,
1844 IN AFSDirectoryCB *DirectoryCB)
1846 NTSTATUS ntStatus = STATUS_SUCCESS;
1847 PFILE_DISPOSITION_INFORMATION pBuffer;
1848 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1849 AFSFcb *pFcb = NULL;
1850 AFSCcb *pCcb = NULL;
1855 pBuffer = (PFILE_DISPOSITION_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
1857 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
1859 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
1862 // Can't delete the root
1865 if( pFcb->Header.NodeTypeCode == AFS_ROOT_FCB)
1868 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1869 AFS_TRACE_LEVEL_ERROR,
1870 "AFSSetDispositionInfo Attempt to delete root entry\n"));
1872 try_return( ntStatus = STATUS_CANNOT_DELETE);
1876 // If the file is read only then do not allow the delete
1879 if( BooleanFlagOn( DirectoryCB->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_READONLY))
1882 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1883 AFS_TRACE_LEVEL_ERROR,
1884 "AFSSetDispositionInfo Attempt to delete read only entry %wZ\n",
1885 &DirectoryCB->NameInformation.FileName));
1887 try_return( ntStatus = STATUS_CANNOT_DELETE);
1890 if( pBuffer->DeleteFile)
1894 // Check if the caller can delete the file
1897 ntStatus = AFSNotifyDelete( DirectoryCB,
1901 if( !NT_SUCCESS( ntStatus))
1904 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1905 AFS_TRACE_LEVEL_ERROR,
1906 "AFSSetDispositionInfo Cannot delete entry %wZ Status %08lX\n",
1907 &DirectoryCB->NameInformation.FileName,
1910 try_return( ntStatus);
1913 if( pFcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB)
1917 // Reduce the Link count in the object information block
1918 // to correspond with the deletion of the directory entry.
1921 pFcb->ObjectInformation->Links--;
1924 // Check if this is a directory that there are not currently other opens
1927 if( pFcb->ObjectInformation->Specific.Directory.ChildOpenHandleCount > 0)
1930 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1931 AFS_TRACE_LEVEL_ERROR,
1932 "AFSSetDispositionInfo Attempt to delete directory %wZ with open %u handles\n",
1933 &DirectoryCB->NameInformation.FileName,
1934 pFcb->ObjectInformation->Specific.Directory.ChildOpenHandleCount));
1936 try_return( ntStatus = STATUS_DIRECTORY_NOT_EMPTY);
1940 // Make sure the directory is enumerated before checking to see if it is empty.
1943 if( !BooleanFlagOn( pFcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
1946 AFSAcquireExcl( pFcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
1949 if( !BooleanFlagOn( pFcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
1952 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1953 AFS_TRACE_LEVEL_VERBOSE,
1954 "AFSSetDispositionInfo Enumerating parent FID %08lX-%08lX-%08lX-%08lX\n",
1955 pFcb->ObjectInformation->FileId.Cell,
1956 pFcb->ObjectInformation->FileId.Volume,
1957 pFcb->ObjectInformation->FileId.Vnode,
1958 pFcb->ObjectInformation->FileId.Unique));
1960 ntStatus = AFSEnumerateDirectory( &pCcb->AuthGroup,
1961 pFcb->ObjectInformation,
1964 if( !NT_SUCCESS( ntStatus))
1967 AFSReleaseResource( pFcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
1969 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1970 AFS_TRACE_LEVEL_ERROR,
1971 "AFSSetDispositionInfo Failed to enumerate parent FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
1972 pFcb->ObjectInformation->FileId.Cell,
1973 pFcb->ObjectInformation->FileId.Volume,
1974 pFcb->ObjectInformation->FileId.Vnode,
1975 pFcb->ObjectInformation->FileId.Unique,
1978 try_return( ntStatus);
1982 AFSReleaseResource( pFcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
1985 if( !AFSIsDirectoryEmptyForDelete( pFcb))
1988 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1989 AFS_TRACE_LEVEL_ERROR,
1990 "AFSSetDispositionInfo Attempt to delete non-empty directory %wZ\n",
1991 &DirectoryCB->NameInformation.FileName));
1993 try_return( ntStatus = STATUS_DIRECTORY_NOT_EMPTY);
1996 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1997 AFS_TRACE_LEVEL_VERBOSE,
1998 "AFSSetDispositionInfo Setting PENDING_DELETE on DirEntry %p Name %wZ\n",
2000 &DirectoryCB->NameInformation.FileName));
2002 SetFlag( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
2004 else if( pFcb->Header.NodeTypeCode == AFS_FILE_FCB)
2008 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
2009 AFS_TRACE_LEVEL_VERBOSE,
2010 "AFSSetDispositionInfo Acquiring Fcb lock %p EXCL %08lX\n",
2011 &pFcb->NPFcb->Resource,
2012 PsGetCurrentThread()));
2014 AFSAcquireExcl( &pFcb->NPFcb->Resource,
2017 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
2018 AFS_TRACE_LEVEL_VERBOSE,
2019 "AFSSetDispositionInfo Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
2020 &pFcb->NPFcb->SectionObjectResource,
2021 PsGetCurrentThread()));
2023 AFSAcquireExcl( &pFcb->NPFcb->SectionObjectResource,
2030 // Attempt to flush any outstanding data
2033 bMmFlushed = MmFlushImageSection( &pFcb->NPFcb->SectionObjectPointers,
2040 // Set PENDING_DELETE before CcPurgeCacheSection to avoid a
2041 // deadlock with Trend Micro's Enterprise anti-virus product
2042 // which attempts to open the file which is being deleted.
2045 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2046 AFS_TRACE_LEVEL_VERBOSE,
2047 "AFSSetDispositionInfo Setting PENDING_DELETE on DirEntry %p Name %wZ\n",
2049 &DirectoryCB->NameInformation.FileName));
2051 SetFlag( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
2054 // Purge the cache as well
2057 if( pFcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
2060 if ( !CcPurgeCacheSection( &pFcb->NPFcb->SectionObjectPointers,
2066 SetFlag( pFcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
2071 __except( EXCEPTION_EXECUTE_HANDLER)
2076 ntStatus = GetExceptionCode();
2080 "EXCEPTION - AFSSetDispositionInfo MmFlushImageSection failed FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
2081 pFcb->ObjectInformation->FileId.Cell,
2082 pFcb->ObjectInformation->FileId.Volume,
2083 pFcb->ObjectInformation->FileId.Vnode,
2084 pFcb->ObjectInformation->FileId.Unique,
2088 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
2089 AFS_TRACE_LEVEL_VERBOSE,
2090 "AFSSetDispositionInfo Releasing Fcb SectionObject lock %p EXCL %08lX\n",
2091 &pFcb->NPFcb->SectionObjectResource,
2092 PsGetCurrentThread()));
2094 AFSReleaseResource( &pFcb->NPFcb->SectionObjectResource);
2096 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
2097 AFS_TRACE_LEVEL_VERBOSE,
2098 "AFSSetDispositionInfo Releasing Fcb lock %p EXCL %08lX\n",
2099 &pFcb->NPFcb->Resource,
2100 PsGetCurrentThread()));
2102 AFSReleaseResource( &pFcb->NPFcb->Resource);
2107 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2108 AFS_TRACE_LEVEL_ERROR,
2109 "AFSSetDispositionInfo Failed to flush image section for delete Entry %wZ\n",
2110 &DirectoryCB->NameInformation.FileName));
2112 try_return( ntStatus = STATUS_CANNOT_DELETE);
2115 else if( pFcb->Header.NodeTypeCode == AFS_SYMBOLIC_LINK_FCB ||
2116 pFcb->Header.NodeTypeCode == AFS_MOUNT_POINT_FCB ||
2117 pFcb->Header.NodeTypeCode == AFS_DFS_LINK_FCB ||
2118 pFcb->Header.NodeTypeCode == AFS_INVALID_FCB)
2121 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2122 AFS_TRACE_LEVEL_VERBOSE,
2123 "AFSSetDispositionInfo Setting PENDING_DELETE on DirEntry %p Name %wZ\n",
2125 &DirectoryCB->NameInformation.FileName));
2127 SetFlag( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
2133 ClearFlag( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
2137 // OK, should be good to go, set the flag in the file object
2140 pIrpSp->FileObject->DeletePending = pBuffer->DeleteFile;
2151 AFSSetFileLinkInfo( IN PIRP Irp)
2154 NTSTATUS ntStatus = STATUS_SUCCESS;
2155 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
2156 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2157 PFILE_LINK_INFORMATION pFileLinkInfo = NULL;
2158 PFILE_OBJECT pSrcFileObj = NULL;
2159 PFILE_OBJECT pTargetFileObj = pIrpSp->Parameters.SetFile.FileObject;
2160 AFSFcb *pSrcFcb = NULL, *pTargetDcb = NULL;
2161 AFSCcb *pSrcCcb = NULL, *pTargetDirCcb = NULL;
2162 AFSObjectInfoCB *pSrcObject = NULL;
2163 AFSObjectInfoCB *pSrcParentObject = NULL, *pTargetParentObject = NULL;
2164 UNICODE_STRING uniSourceName, uniTargetName;
2165 UNICODE_STRING uniFullTargetName, uniTargetParentName;
2166 BOOLEAN bCommonParent = FALSE;
2167 AFSDirectoryCB *pTargetDirEntry = NULL;
2168 AFSDirectoryCB *pNewTargetDirEntry = NULL;
2170 BOOLEAN bTargetEntryExists = FALSE;
2172 BOOLEAN bReleaseTargetDirLock = FALSE;
2173 ULONG ulNotificationAction = 0, ulNotifyFilter = 0;
2178 pSrcFileObj = pIrpSp->FileObject;
2180 pSrcFcb = (AFSFcb *)pSrcFileObj->FsContext;
2181 pSrcCcb = (AFSCcb *)pSrcFileObj->FsContext2;
2183 pSrcObject = pSrcFcb->ObjectInformation;
2185 if ( BooleanFlagOn( pSrcObject->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
2188 pSrcParentObject = AFSFindObjectInfo( pSrcObject->VolumeCB,
2189 &pSrcObject->ParentFileId,
2193 if( pSrcParentObject == NULL)
2196 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2197 AFS_TRACE_LEVEL_ERROR,
2198 "AFSSetFileLinkInfo Unable to resolve SrcParentObject (INVALID_PARAMETER)\n"));
2202 try_return( ntStatus = STATUS_INVALID_PARAMETER);
2205 pFileLinkInfo = (PFILE_LINK_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
2208 // Perform some basic checks to ensure FS integrity
2211 if( pSrcFcb->Header.NodeTypeCode != AFS_FILE_FCB)
2214 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2215 AFS_TRACE_LEVEL_ERROR,
2216 "AFSSetFileLinkInfo Attempt to non-file (INVALID_PARAMETER)\n"));
2218 try_return( ntStatus = STATUS_INVALID_PARAMETER);
2221 if( pTargetFileObj == NULL)
2224 if ( pFileLinkInfo->RootDirectory)
2228 // The target directory is provided by HANDLE
2229 // RootDirectory is only set when the target directory is not the same
2230 // as the source directory.
2232 // AFS only supports hard links within a single directory.
2234 // The IOManager should translate any Handle to a FileObject for us.
2235 // However, the failure to receive a FileObject is treated as a fatal
2239 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2240 AFS_TRACE_LEVEL_ERROR,
2241 "AFSSetFileLinkInfo Attempt to link %wZ to alternate directory by handle INVALID_PARAMETER\n",
2242 &pSrcCcb->DirectoryCB->NameInformation.FileName));
2244 try_return( ntStatus = STATUS_INVALID_PARAMETER);
2249 uniFullTargetName.Length = (USHORT)pFileLinkInfo->FileNameLength;
2251 uniFullTargetName.Buffer = (PWSTR)&pFileLinkInfo->FileName;
2253 AFSRetrieveFinalComponent( &uniFullTargetName,
2256 AFSRetrieveParentPath( &uniFullTargetName,
2257 &uniTargetParentName);
2259 if ( uniTargetParentName.Length == 0)
2263 // This is a simple rename. Here the target directory is the same as the source parent directory
2264 // and the name is retrieved from the system buffer information
2267 pTargetParentObject = pSrcParentObject;
2272 // uniTargetParentName contains the directory the renamed object
2273 // will be moved to. Must obtain the TargetParentObject.
2276 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2277 AFS_TRACE_LEVEL_ERROR,
2278 "AFSSetFileLinkInfo Attempt to link %wZ to alternate directory %wZ (NOT_SAME_DEVICE)\n",
2279 &pSrcCcb->DirectoryCB->NameInformation.FileName,
2280 &uniFullTargetName));
2282 try_return( ntStatus = STATUS_NOT_SAME_DEVICE);
2286 pTargetDcb = pTargetParentObject->Fcb;
2292 // So here we have the target directory taken from the targetfile object
2295 pTargetDcb = (AFSFcb *)pTargetFileObj->FsContext;
2297 pTargetDirCcb = (AFSCcb *)pTargetFileObj->FsContext2;
2299 pTargetParentObject = (AFSObjectInfoCB *)pTargetDcb->ObjectInformation;
2302 // Grab the target name which we setup in the IRP_MJ_CREATE handler. By how we set this up
2303 // it is only the target component of the rename operation
2306 uniTargetName = *((PUNICODE_STRING)&pTargetFileObj->FileName);
2310 // The quick check to see if they are self linking.
2311 // Do the names match? Only do this where the parent directories are
2315 if( pTargetParentObject == pSrcParentObject)
2318 if( FsRtlAreNamesEqual( &uniTargetName,
2323 try_return( ntStatus = STATUS_SUCCESS);
2326 bCommonParent = TRUE;
2332 // We do not allow cross-volume hard links
2335 if( pTargetParentObject->VolumeCB != pSrcObject->VolumeCB)
2338 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2339 AFS_TRACE_LEVEL_ERROR,
2340 "AFSSetFileLinkInfo Attempt to link to different volume %wZ\n",
2341 &pSrcCcb->DirectoryCB->NameInformation.FileName));
2343 try_return( ntStatus = STATUS_NOT_SAME_DEVICE);
2347 ulTargetCRC = AFSGenerateCRC( &uniTargetName,
2350 AFSAcquireExcl( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock,
2353 bReleaseTargetDirLock = TRUE;
2355 AFSLocateCaseSensitiveDirEntry( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
2359 if( pTargetDirEntry == NULL)
2363 // Missed so perform a case insensitive lookup
2366 ulTargetCRC = AFSGenerateCRC( &uniTargetName,
2369 AFSLocateCaseInsensitiveDirEntry( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
2374 if ( !BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
2375 pTargetDirEntry == NULL && RtlIsNameLegalDOS8Dot3( &uniTargetName,
2380 // Try the short name
2382 AFSLocateShortNameDirEntry( pTargetParentObject->Specific.Directory.ShortNameTree,
2388 // Increment our ref count on the dir entry
2391 if( pTargetDirEntry != NULL)
2394 ASSERT( BooleanFlagOn( pTargetDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_PARENT_FID) &&
2395 AFSIsEqualFID( &pTargetParentObject->FileId, &pTargetDirEntry->ObjectInformation->ParentFileId));
2397 lCount = InterlockedIncrement( &pTargetDirEntry->DirOpenReferenceCount);
2399 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2400 AFS_TRACE_LEVEL_VERBOSE,
2401 "AFSSetFileLinkInfo Increment count on %wZ DE %p Ccb %p Cnt %d\n",
2402 &pTargetDirEntry->NameInformation.FileName,
2407 ASSERT( lCount >= 0);
2409 if( !pFileLinkInfo->ReplaceIfExists)
2412 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2413 AFS_TRACE_LEVEL_ERROR,
2414 "AFSSetFileLinkInfo Attempt to link with target collision %wZ Target %wZ\n",
2415 &pSrcCcb->DirectoryCB->NameInformation.FileName,
2416 &pTargetDirEntry->NameInformation.FileName));
2418 try_return( ntStatus = STATUS_OBJECT_NAME_COLLISION);
2421 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING | AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2422 AFS_TRACE_LEVEL_ERROR,
2423 "AFSSetFileLinkInfo Target %wZ exists DE %p Count %d, performing delete of target\n",
2424 &pTargetDirEntry->NameInformation.FileName,
2429 // Pull the directory entry from the parent
2432 AFSRemoveDirNodeFromParent( pTargetParentObject,
2436 bTargetEntryExists = TRUE;
2440 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2441 AFS_TRACE_LEVEL_VERBOSE,
2442 "AFSSetFileLinkInfo Target does NOT exist, normal linking\n"));
2446 // OK, this is a simple rename. Issue the rename
2447 // request to the service.
2450 ntStatus = AFSNotifyHardLink( pSrcObject,
2451 &pSrcCcb->AuthGroup,
2453 pTargetDcb->ObjectInformation,
2454 pSrcCcb->DirectoryCB,
2456 pFileLinkInfo->ReplaceIfExists,
2457 &pNewTargetDirEntry);
2459 if( ntStatus != STATUS_REPARSE &&
2460 !NT_SUCCESS( ntStatus))
2463 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2464 AFS_TRACE_LEVEL_ERROR,
2465 "AFSSetFileLinkInfo Failed link of %wZ to target %wZ Status %08lX\n",
2466 &pSrcCcb->DirectoryCB->NameInformation.FileName,
2470 try_return( ntStatus);
2473 if ( ntStatus != STATUS_REPARSE)
2476 AFSInsertDirectoryNode( pTargetDcb->ObjectInformation,
2482 // Send notification for the target link file
2485 if( bTargetEntryExists || pNewTargetDirEntry)
2488 ulNotificationAction = FILE_ACTION_MODIFIED;
2493 ulNotificationAction = FILE_ACTION_ADDED;
2496 AFSFsRtlNotifyFullReportChange( pTargetParentObject,
2498 (ULONG)ulNotifyFilter,
2499 (ULONG)ulNotificationAction);
2503 if( !NT_SUCCESS( ntStatus))
2506 if( bTargetEntryExists)
2509 AFSInsertDirectoryNode( pTargetParentObject,
2515 if( pTargetDirEntry != NULL)
2519 // Release DirOpenReferenceCount obtained above
2522 lCount = InterlockedDecrement( &pTargetDirEntry->DirOpenReferenceCount);
2524 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2525 AFS_TRACE_LEVEL_VERBOSE,
2526 "AFSSetFileLinkInfo Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
2527 &pTargetDirEntry->NameInformation.FileName,
2532 ASSERT( lCount >= 0);
2535 if( pNewTargetDirEntry != NULL)
2539 // Release DirOpenReferenceCount obtained from AFSNotifyHardLink
2542 lCount = InterlockedDecrement( &pNewTargetDirEntry->DirOpenReferenceCount);
2544 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2545 AFS_TRACE_LEVEL_VERBOSE,
2546 "AFSSetFileLinkInfo Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
2547 &pNewTargetDirEntry->NameInformation.FileName,
2552 ASSERT( lCount >= 0);
2555 if( bReleaseTargetDirLock)
2558 AFSReleaseResource( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
2561 if ( pSrcParentObject != NULL)
2564 AFSReleaseObjectInfo( &pSrcParentObject);
2568 // No need to release pTargetParentObject as it is either a copy of pSrcParentObject
2569 // or (AFSFcb *)pTargetFileObj->FsContext->ObjectInformation
2572 pTargetParentObject = NULL;
2579 AFSSetRenameInfo( IN PIRP Irp)
2582 NTSTATUS ntStatus = STATUS_SUCCESS;
2583 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
2584 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2585 AFSFcb *pSrcFcb = NULL, *pTargetDcb = NULL, *pTargetFcb = NULL;
2586 AFSCcb *pSrcCcb = NULL, *pTargetDirCcb = NULL;
2587 PFILE_OBJECT pSrcFileObj = pIrpSp->FileObject;
2588 PFILE_OBJECT pTargetFileObj = pIrpSp->Parameters.SetFile.FileObject;
2589 PFILE_OBJECT pTargetParentFileObj = NULL;
2590 PFILE_RENAME_INFORMATION pRenameInfo = NULL;
2591 UNICODE_STRING uniTargetName, uniSourceName, uniTargetParentName;
2592 BOOLEAN bReplaceIfExists = FALSE;
2593 UNICODE_STRING uniShortName;
2594 AFSDirectoryCB *pTargetDirEntry = NULL;
2595 ULONG ulTargetCRC = 0;
2596 BOOLEAN bTargetEntryExists = FALSE;
2597 AFSObjectInfoCB *pSrcObject = NULL;
2598 AFSObjectInfoCB *pSrcParentObject = NULL, *pTargetParentObject = NULL;
2600 ULONG ulNotificationAction = 0, ulNotifyFilter = 0;
2601 UNICODE_STRING uniFullTargetName;
2602 BOOLEAN bCommonParent = FALSE;
2603 BOOLEAN bReleaseTargetDirLock = FALSE;
2604 BOOLEAN bReleaseSourceDirLock = FALSE;
2605 BOOLEAN bDereferenceTargetParentObject = FALSE;
2606 PERESOURCE pSourceDirLock = NULL;
2612 bReplaceIfExists = pIrpSp->Parameters.SetFile.ReplaceIfExists;
2614 pRenameInfo = (PFILE_RENAME_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
2616 pSrcFcb = (AFSFcb *)pSrcFileObj->FsContext;
2617 pSrcCcb = (AFSCcb *)pSrcFileObj->FsContext2;
2619 pSrcObject = pSrcFcb->ObjectInformation;
2621 if ( BooleanFlagOn( pSrcObject->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
2624 pSrcParentObject = AFSFindObjectInfo( pSrcObject->VolumeCB,
2625 &pSrcObject->ParentFileId,
2629 if( pSrcParentObject == NULL)
2632 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2633 AFS_TRACE_LEVEL_ERROR,
2634 "AFSSetRenameInfo Unable to resolve SrcParentObject (INVALID_PARAMETER)\n"));
2638 try_return( ntStatus = STATUS_INVALID_PARAMETER);
2642 // Perform some basic checks to ensure FS integrity
2645 if( pSrcFcb->Header.NodeTypeCode == AFS_ROOT_FCB)
2649 // Can't rename the root directory
2652 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2653 AFS_TRACE_LEVEL_ERROR,
2654 "AFSSetRenameInfo Attempt to rename root entry\n"));
2656 try_return( ntStatus = STATUS_INVALID_PARAMETER);
2659 if( pSrcFcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB)
2663 // If there are any open children then fail the rename
2666 if( pSrcObject->Specific.Directory.ChildOpenHandleCount > 0)
2669 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2670 AFS_TRACE_LEVEL_ERROR,
2671 "AFSSetRenameInfo Attempt to rename directory with open children %wZ\n",
2672 &pSrcCcb->DirectoryCB->NameInformation.FileName));
2674 try_return( ntStatus = STATUS_ACCESS_DENIED);
2680 // Extract off the final component name from the Fcb
2683 uniSourceName.Length = (USHORT)pSrcCcb->DirectoryCB->NameInformation.FileName.Length;
2684 uniSourceName.MaximumLength = uniSourceName.Length;
2686 uniSourceName.Buffer = pSrcCcb->DirectoryCB->NameInformation.FileName.Buffer;
2689 // Resolve the target fileobject
2692 if( pTargetFileObj == NULL)
2695 if ( pRenameInfo->RootDirectory)
2698 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2699 AFS_TRACE_LEVEL_ERROR,
2700 "AFSSetRenameInfo Handle provided but no FileObject ntStatus INVALID_PARAMETER\n"));
2702 try_return( ntStatus = STATUS_INVALID_PARAMETER);
2707 uniFullTargetName.Length = (USHORT)pRenameInfo->FileNameLength;
2709 uniFullTargetName.Buffer = (PWSTR)&pRenameInfo->FileName;
2711 AFSRetrieveFinalComponent( &uniFullTargetName,
2714 AFSRetrieveParentPath( &uniFullTargetName,
2715 &uniTargetParentName);
2717 if ( uniTargetParentName.Length == 0)
2721 // This is a simple rename. Here the target directory is the same as the source parent directory
2722 // and the name is retrieved from the system buffer information
2725 pTargetParentObject = pSrcParentObject;
2730 // uniTargetParentName contains the directory the renamed object
2731 // will be moved to. Must obtain the TargetParentObject.
2734 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2735 AFS_TRACE_LEVEL_ERROR,
2736 "AFSSetRenameInfo Attempt to move %wZ to %wZ -- not yet supported (NOT_SAME_DEVICE)\n",
2737 &pSrcCcb->DirectoryCB->NameInformation.FileName,
2738 &uniFullTargetName));
2740 try_return( ntStatus = STATUS_NOT_SAME_DEVICE);
2744 pTargetDcb = pTargetParentObject->Fcb;
2750 // So here we have the target directory taken from the targetfile object
2753 pTargetDcb = (AFSFcb *)pTargetFileObj->FsContext;
2755 pTargetDirCcb = (AFSCcb *)pTargetFileObj->FsContext2;
2757 pTargetParentObject = (AFSObjectInfoCB *)pTargetDcb->ObjectInformation;
2760 // Grab the target name which we setup in the IRP_MJ_CREATE handler. By how we set this up
2761 // it is only the target component of the rename operation
2764 uniTargetName = *((PUNICODE_STRING)&pTargetFileObj->FileName);
2768 // The quick check to see if they are not really performing a rename
2769 // Do the names match? Only do this where the parent directories are
2773 if( pTargetParentObject == pSrcParentObject)
2776 if( FsRtlAreNamesEqual( &uniTargetName,
2781 try_return( ntStatus = STATUS_SUCCESS);
2784 bCommonParent = TRUE;
2789 bCommonParent = FALSE;
2793 // We do not allow cross-volume renames to occur
2796 if( pTargetParentObject->VolumeCB != pSrcObject->VolumeCB)
2799 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2800 AFS_TRACE_LEVEL_ERROR,
2801 "AFSSetRenameInfo Attempt to rename directory to different volume %wZ\n",
2802 &pSrcCcb->DirectoryCB->NameInformation.FileName));
2804 try_return( ntStatus = STATUS_NOT_SAME_DEVICE);
2807 ulTargetCRC = AFSGenerateCRC( &uniTargetName,
2810 AFSAcquireExcl( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock,
2813 bReleaseTargetDirLock = TRUE;
2815 if( pTargetParentObject != pSrcParentObject)
2817 AFSAcquireExcl( pSrcParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock,
2820 bReleaseSourceDirLock = TRUE;
2822 pSourceDirLock = pSrcParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock;
2825 AFSLocateCaseSensitiveDirEntry( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
2829 if( pTargetDirEntry == NULL)
2833 // Missed so perform a case insensitive lookup
2836 ulTargetCRC = AFSGenerateCRC( &uniTargetName,
2839 AFSLocateCaseInsensitiveDirEntry( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
2844 if ( !BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
2845 pTargetDirEntry == NULL && RtlIsNameLegalDOS8Dot3( &uniTargetName,
2850 // Try the short name
2852 AFSLocateShortNameDirEntry( pTargetParentObject->Specific.Directory.ShortNameTree,
2858 // Increment our ref count on the dir entry
2861 if( pTargetDirEntry != NULL)
2864 ASSERT( BooleanFlagOn( pTargetDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_PARENT_FID) &&
2865 AFSIsEqualFID( &pTargetParentObject->FileId, &pTargetDirEntry->ObjectInformation->ParentFileId));
2867 lCount = InterlockedIncrement( &pTargetDirEntry->DirOpenReferenceCount);
2869 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2870 AFS_TRACE_LEVEL_VERBOSE,
2871 "AFSSetRenameInfo Increment count on %wZ DE %p Ccb %p Cnt %d\n",
2872 &pTargetDirEntry->NameInformation.FileName,
2877 ASSERT( lCount >= 0);
2879 if( !bReplaceIfExists)
2882 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2883 AFS_TRACE_LEVEL_ERROR,
2884 "AFSSetRenameInfo Attempt to rename directory with target collision %wZ Target %wZ\n",
2885 &pSrcCcb->DirectoryCB->NameInformation.FileName,
2886 &pTargetDirEntry->NameInformation.FileName));
2888 try_return( ntStatus = STATUS_OBJECT_NAME_COLLISION);
2891 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING | AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2892 AFS_TRACE_LEVEL_ERROR,
2893 "AFSSetRenameInfo Target %wZ exists DE %p Count %d, performing delete of target\n",
2894 &pTargetDirEntry->NameInformation.FileName,
2899 // Pull the directory entry from the parent
2902 AFSRemoveDirNodeFromParent( pTargetParentObject,
2906 bTargetEntryExists = TRUE;
2910 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2911 AFS_TRACE_LEVEL_VERBOSE,
2912 "AFSSetRenameInfo Target does NOT exist, normal rename\n"));
2916 // We need to remove the DirEntry from the parent node, update the index
2917 // and reinsert it into the parent tree. Note that for entries with the
2918 // same parent we do not pull the node from the enumeration list
2921 AFSRemoveDirNodeFromParent( pSrcParentObject,
2922 pSrcCcb->DirectoryCB,
2926 // OK, this is a simple rename. Issue the rename
2927 // request to the service.
2930 ntStatus = AFSNotifyRename( pSrcObject,
2931 &pSrcCcb->AuthGroup,
2933 pTargetDcb->ObjectInformation,
2934 pSrcCcb->DirectoryCB,
2938 if( !NT_SUCCESS( ntStatus))
2942 // Attempt to re-insert the directory entry
2945 AFSInsertDirectoryNode( pSrcParentObject,
2946 pSrcCcb->DirectoryCB,
2949 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2950 AFS_TRACE_LEVEL_ERROR,
2951 "AFSSetRenameInfo Failed rename of %wZ to target %wZ Status %08lX\n",
2952 &pSrcCcb->DirectoryCB->NameInformation.FileName,
2956 try_return( ntStatus);
2960 // Set the notification up for the source file
2963 if( pSrcParentObject == pTargetParentObject &&
2964 !bTargetEntryExists)
2967 ulNotificationAction = FILE_ACTION_RENAMED_OLD_NAME;
2972 ulNotificationAction = FILE_ACTION_REMOVED;
2975 if( pSrcObject->FileType == AFS_FILE_TYPE_DIRECTORY)
2978 ulNotifyFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
2983 ulNotifyFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
2986 AFSFsRtlNotifyFullReportChange( pSrcParentObject,
2988 (ULONG)ulNotifyFilter,
2989 (ULONG)ulNotificationAction);
2992 // Update the name in the dir entry.
2995 ntStatus = AFSUpdateDirEntryName( pSrcCcb->DirectoryCB,
2998 if( !NT_SUCCESS( ntStatus))
3002 // Attempt to re-insert the directory entry
3005 AFSInsertDirectoryNode( pSrcParentObject,
3006 pSrcCcb->DirectoryCB,
3009 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3010 AFS_TRACE_LEVEL_ERROR,
3011 "AFSSetRenameInfo Failed update of dir entry %wZ to target %wZ Status %08lX\n",
3012 &pSrcCcb->DirectoryCB->NameInformation.FileName,
3016 try_return( ntStatus);
3020 // Update the object information block, if needed
3023 if( !AFSIsEqualFID( &pSrcObject->FileId,
3027 AFSAcquireExcl( pSrcObject->VolumeCB->ObjectInfoTree.TreeLock,
3031 // Remove the old information entry
3034 AFSRemoveHashEntry( &pSrcObject->VolumeCB->ObjectInfoTree.TreeHead,
3035 &pSrcObject->TreeEntry);
3037 RtlCopyMemory( &pSrcObject->FileId,
3039 sizeof( AFSFileID));
3042 // Insert the entry into the new object table.
3045 pSrcObject->TreeEntry.HashIndex = AFSCreateLowIndex( &pSrcObject->FileId);
3047 if( pSrcObject->VolumeCB->ObjectInfoTree.TreeHead == NULL)
3050 pSrcObject->VolumeCB->ObjectInfoTree.TreeHead = &pSrcObject->TreeEntry;
3055 if ( !NT_SUCCESS( AFSInsertHashEntry( pSrcObject->VolumeCB->ObjectInfoTree.TreeHead,
3056 &pSrcObject->TreeEntry)))
3060 // Lost a race, an ObjectInfo object already exists for this FID.
3061 // Let this copy be garbage collected.
3064 ClearFlag( pSrcObject->Flags, AFS_OBJECT_INSERTED_HASH_TREE);
3068 AFSReleaseResource( pSrcObject->VolumeCB->ObjectInfoTree.TreeLock);
3072 // Update the hash values for the name trees.
3075 pSrcCcb->DirectoryCB->CaseSensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pSrcCcb->DirectoryCB->NameInformation.FileName,
3078 pSrcCcb->DirectoryCB->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pSrcCcb->DirectoryCB->NameInformation.FileName,
3081 if( !BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
3082 pSrcCcb->DirectoryCB->NameInformation.ShortNameLength > 0 &&
3083 !RtlIsNameLegalDOS8Dot3( &pSrcCcb->DirectoryCB->NameInformation.FileName,
3088 uniShortName.Length = pSrcCcb->DirectoryCB->NameInformation.ShortNameLength;
3089 uniShortName.MaximumLength = uniShortName.Length;
3090 uniShortName.Buffer = pSrcCcb->DirectoryCB->NameInformation.ShortName;
3092 pSrcCcb->DirectoryCB->Type.Data.ShortNameTreeEntry.HashIndex = AFSGenerateCRC( &uniShortName,
3095 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3096 AFS_TRACE_LEVEL_VERBOSE,
3097 "AFSSetRenameInfo Initialized short name hash for %wZ longname %wZ\n",
3099 &pSrcCcb->DirectoryCB->NameInformation.FileName));
3104 pSrcCcb->DirectoryCB->Type.Data.ShortNameTreeEntry.HashIndex = 0;
3111 // Update the file index for the object in the new parent
3114 pSrcCcb->DirectoryCB->FileIndex = (ULONG)InterlockedIncrement( &pTargetParentObject->Specific.Directory.DirectoryNodeHdr.ContentIndex);
3118 // Re-insert the directory entry
3121 AFSInsertDirectoryNode( pTargetParentObject,
3122 pSrcCcb->DirectoryCB,
3126 // Update the parent pointer in the source object if they are different
3129 if( pSrcParentObject != pTargetParentObject)
3132 lCount = InterlockedDecrement( &pSrcParentObject->Specific.Directory.ChildOpenHandleCount);
3134 lCount = InterlockedDecrement( &pSrcParentObject->Specific.Directory.ChildOpenReferenceCount);
3136 lCount = InterlockedIncrement( &pTargetParentObject->Specific.Directory.ChildOpenHandleCount);
3138 lCount = InterlockedIncrement( &pTargetParentObject->Specific.Directory.ChildOpenReferenceCount);
3142 // Guaranteed to be in the same volume
3145 AFSAcquireExcl( pSrcParentObject->VolumeCB->ObjectInfoTree.TreeLock,
3148 lCount = AFSObjectInfoIncrement( pTargetParentObject,
3149 AFS_OBJECT_REFERENCE_CHILD);
3151 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
3152 AFS_TRACE_LEVEL_VERBOSE,
3153 "AFSSetRenameInfo Increment count on parent object %p Cnt %d\n",
3154 pTargetParentObject,
3157 lCount = AFSObjectInfoDecrement( pSrcParentObject,
3158 AFS_OBJECT_REFERENCE_CHILD);
3160 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
3161 AFS_TRACE_LEVEL_VERBOSE,
3162 "AFSSetRenameInfo Decrement count on parent object %p Cnt %d\n",
3166 pSrcObject->ParentFileId = pTargetParentObject->FileId;
3168 SetFlag( pSrcObject->Flags, AFS_OBJECT_FLAGS_PARENT_FID);
3170 AFSReleaseResource( pSrcParentObject->VolumeCB->ObjectInfoTree.TreeLock);
3172 ulNotificationAction = FILE_ACTION_ADDED;
3177 ulNotificationAction = FILE_ACTION_RENAMED_NEW_NAME;
3181 // Now update the notification for the target file
3184 AFSFsRtlNotifyFullReportChange( pTargetParentObject,
3186 (ULONG)ulNotifyFilter,
3187 (ULONG)ulNotificationAction);
3190 // If we performed the rename of the target because it existed, we now need to
3191 // delete the tmp target we created above
3194 if( bTargetEntryExists)
3197 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3198 AFS_TRACE_LEVEL_VERBOSE,
3199 "AFSSetRenameInfo Setting DELETE flag in dir entry %p name %wZ\n",
3201 &pTargetDirEntry->NameInformation.FileName));
3203 SetFlag( pTargetDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
3206 // Try and purge the cache map if this is a file
3209 if( pTargetDirEntry->ObjectInformation->FileType == AFS_FILE_TYPE_FILE &&
3210 pTargetDirEntry->ObjectInformation->Fcb != NULL &&
3211 pTargetDirEntry->DirOpenReferenceCount > 1)
3214 pTargetFcb = pTargetDirEntry->ObjectInformation->Fcb;
3217 ASSERT( pTargetDirEntry->DirOpenReferenceCount > 0);
3219 lCount = InterlockedDecrement( &pTargetDirEntry->DirOpenReferenceCount); // The count we added above
3221 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3222 AFS_TRACE_LEVEL_VERBOSE,
3223 "AFSSetRenameInfo Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
3224 &pTargetDirEntry->NameInformation.FileName,
3229 ASSERT( lCount >= 0);
3232 pTargetDirEntry->NameArrayReferenceCount <= 0)
3235 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3236 AFS_TRACE_LEVEL_VERBOSE,
3237 "AFSSetRenameInfo Deleting dir entry %p name %wZ\n",
3239 &pTargetDirEntry->NameInformation.FileName));
3241 AFSDeleteDirEntry( pTargetParentObject,
3245 pTargetDirEntry = NULL;
3247 if ( pTargetFcb != NULL)
3251 // Do not hold TreeLocks across the MmForceSectionClosed() call as
3252 // it can deadlock with Trend Micro's TmPreFlt!TmpQueryFullName
3255 if( bReleaseTargetDirLock)
3257 AFSReleaseResource( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
3259 bReleaseTargetDirLock = FALSE;
3262 if( bReleaseSourceDirLock)
3265 AFSReleaseResource( pSourceDirLock);
3267 bReleaseSourceDirLock = FALSE;
3271 // MmForceSectionClosed() can eventually call back into AFSCleanup
3272 // which will need to acquire Fcb->Resource exclusively. Failure
3273 // to obtain it here before holding the SectionObjectResource will
3274 // permit the locks to be obtained out of order risking a deadlock.
3277 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
3278 AFS_TRACE_LEVEL_VERBOSE,
3279 "AFSSetRenameInfo Acquiring Fcb lock %p EXCL %08lX\n",
3280 &pTargetFcb->NPFcb->Resource,
3281 PsGetCurrentThread()));
3283 AFSAcquireExcl( &pTargetFcb->NPFcb->Resource,
3286 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
3287 AFS_TRACE_LEVEL_VERBOSE,
3288 "AFSSetRenameInfo Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
3289 &pTargetFcb->NPFcb->SectionObjectResource,
3290 PsGetCurrentThread()));
3292 AFSAcquireExcl( &pTargetFcb->NPFcb->SectionObjectResource,
3299 // Close the section in the event it was mapped
3302 if( !MmForceSectionClosed( &pTargetFcb->NPFcb->SectionObjectPointers,
3306 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3307 AFS_TRACE_LEVEL_ERROR,
3308 "AFSSetRenameInfo Failed to delete section for target file %wZ\n",
3312 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
3315 ntStatus = GetExceptionCode();
3319 "EXCEPTION - AFSSetRenameInfo MmForceSectionClosed failed FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
3320 pTargetFcb->ObjectInformation->FileId.Cell,
3321 pTargetFcb->ObjectInformation->FileId.Volume,
3322 pTargetFcb->ObjectInformation->FileId.Vnode,
3323 pTargetFcb->ObjectInformation->FileId.Unique,
3327 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
3328 AFS_TRACE_LEVEL_VERBOSE,
3329 "AFSSetRenameInfo Releasing Fcb SectionObject lock %p EXCL %08lX\n",
3330 &pTargetFcb->NPFcb->SectionObjectResource,
3331 PsGetCurrentThread()));
3333 AFSReleaseResource( &pTargetFcb->NPFcb->SectionObjectResource);
3335 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3336 AFS_TRACE_LEVEL_VERBOSE,
3337 "AFSSetRenameInfo Releasing Fcb lock %p EXCL %08lX\n",
3338 &pTargetFcb->NPFcb->Resource,
3339 PsGetCurrentThread()));
3341 AFSReleaseResource( &pTargetFcb->NPFcb->Resource);
3347 if( !NT_SUCCESS( ntStatus))
3350 if( bTargetEntryExists)
3353 ASSERT( pTargetParentObject != NULL);
3355 AFSInsertDirectoryNode( pTargetParentObject,
3361 if( pTargetDirEntry != NULL)
3364 lCount = InterlockedDecrement( &pTargetDirEntry->DirOpenReferenceCount);
3366 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3367 AFS_TRACE_LEVEL_VERBOSE,
3368 "AFSSetRenameInfo Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
3369 &pTargetDirEntry->NameInformation.FileName,
3374 ASSERT( lCount >= 0);
3377 if( bReleaseTargetDirLock)
3380 AFSReleaseResource( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
3383 if( bReleaseSourceDirLock)
3386 AFSReleaseResource( pSourceDirLock);
3389 if ( bDereferenceTargetParentObject)
3392 ObDereferenceObject( pTargetParentFileObj);
3395 if ( pSrcParentObject != NULL)
3398 AFSReleaseObjectInfo( &pSrcParentObject);
3402 // No need to release pTargetParentObject as it is either a copy of pSrcParentObject
3403 // or (AFSFcb *)pTargetFileObj->FsContext->ObjectInformation
3406 pTargetParentObject = NULL;
3413 AFSSetPositionInfo( IN PIRP Irp,
3414 IN AFSDirectoryCB *DirectoryCB)
3416 UNREFERENCED_PARAMETER(DirectoryCB);
3417 NTSTATUS ntStatus = STATUS_SUCCESS;
3418 PFILE_POSITION_INFORMATION pBuffer;
3419 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
3421 pBuffer = (PFILE_POSITION_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
3423 pIrpSp->FileObject->CurrentByteOffset.QuadPart = pBuffer->CurrentByteOffset.QuadPart;
3429 AFSSetAllocationInfo( IN PIRP Irp,
3430 IN AFSDirectoryCB *DirectoryCB)
3432 UNREFERENCED_PARAMETER(DirectoryCB);
3433 NTSTATUS ntStatus = STATUS_SUCCESS;
3434 PFILE_ALLOCATION_INFORMATION pBuffer;
3435 BOOLEAN bReleasePaging = FALSE;
3436 BOOLEAN bTellCc = FALSE;
3437 BOOLEAN bTellService = FALSE;
3438 BOOLEAN bUserMapped = FALSE;
3439 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
3440 PFILE_OBJECT pFileObject = pIrpSp->FileObject;
3441 AFSFcb *pFcb = NULL;
3442 AFSCcb *pCcb = NULL;
3443 LARGE_INTEGER liSaveAlloc;
3444 LARGE_INTEGER liSaveFileSize;
3445 LARGE_INTEGER liSaveVDL;
3447 pBuffer = (PFILE_ALLOCATION_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
3449 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
3451 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
3454 // save values to put back
3456 liSaveAlloc = pFcb->Header.AllocationSize;
3457 liSaveFileSize = pFcb->Header.FileSize;
3458 liSaveVDL = pFcb->Header.ValidDataLength;
3460 if( pFcb->Header.AllocationSize.QuadPart == pBuffer->AllocationSize.QuadPart ||
3461 pIrpSp->Parameters.SetFile.AdvanceOnly)
3463 return STATUS_SUCCESS ;
3466 if( pFcb->Header.AllocationSize.QuadPart > pBuffer->AllocationSize.QuadPart)
3469 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
3470 AFS_TRACE_LEVEL_VERBOSE,
3471 "AFSSetAllocationInfo Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
3472 &pFcb->NPFcb->SectionObjectResource,
3473 PsGetCurrentThread()));
3475 AFSAcquireExcl( &pFcb->NPFcb->SectionObjectResource,
3481 bUserMapped = !MmCanFileBeTruncated( pFileObject->SectionObjectPointer,
3482 &pBuffer->AllocationSize);
3484 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
3487 bUserMapped = FALSE;
3489 ntStatus = GetExceptionCode();
3493 "EXCEPTION - AFSSetAllocationInfo MmCanFileBeTruncated failed FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
3494 pFcb->ObjectInformation->FileId.Cell,
3495 pFcb->ObjectInformation->FileId.Volume,
3496 pFcb->ObjectInformation->FileId.Vnode,
3497 pFcb->ObjectInformation->FileId.Unique,
3501 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
3502 AFS_TRACE_LEVEL_VERBOSE,
3503 "AFSSetAllocationInfo Releasing Fcb SectionObject lock %p EXCL %08lX\n",
3504 &pFcb->NPFcb->SectionObjectResource,
3505 PsGetCurrentThread()));
3507 AFSReleaseResource( &pFcb->NPFcb->SectionObjectResource);
3510 // Truncating the file
3515 ntStatus = STATUS_USER_MAPPED_FILE ;
3521 // If this is a truncation we need to grab the paging IO resource.
3524 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3525 AFS_TRACE_LEVEL_VERBOSE,
3526 "AFSSetAllocationInfo Acquiring Fcb PagingIo lock %p EXCL %08lX\n",
3527 &pFcb->NPFcb->PagingResource,
3528 PsGetCurrentThread()));
3530 AFSAcquireExcl( &pFcb->NPFcb->PagingResource,
3533 bReleasePaging = TRUE;
3536 // Must drop the Fcb Resource. When changing the file size
3537 // a deadlock can occur with Trend Micro's filter if the file
3538 // size is set to zero.
3541 AFSReleaseResource( &pFcb->NPFcb->Resource);
3543 pFcb->Header.AllocationSize = pBuffer->AllocationSize;
3545 pFcb->ObjectInformation->AllocationSize = pBuffer->AllocationSize;
3548 // Tell Cc that Allocation is moved.
3552 if( pFcb->Header.FileSize.QuadPart > pBuffer->AllocationSize.QuadPart)
3555 // We are pulling the EOF back as well so we need to tell
3558 bTellService = TRUE;
3560 pFcb->Header.FileSize = pBuffer->AllocationSize;
3562 pFcb->ObjectInformation->EndOfFile = pBuffer->AllocationSize;
3570 // Tell Cc if allocation is increased.
3573 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3574 AFS_TRACE_LEVEL_VERBOSE,
3575 "AFSSetAllocationInfo Acquiring Fcb PagingIo lock %p EXCL %08lX\n",
3576 &pFcb->NPFcb->PagingResource,
3577 PsGetCurrentThread()));
3579 AFSAcquireExcl( &pFcb->NPFcb->PagingResource,
3582 bReleasePaging = TRUE;
3585 // Must drop the Fcb Resource. When changing the file size
3586 // a deadlock can occur with Trend Micro's filter if the file
3587 // size is set to zero.
3590 AFSReleaseResource( &pFcb->NPFcb->Resource);
3592 bTellCc = pBuffer->AllocationSize.QuadPart > pFcb->Header.AllocationSize.QuadPart;
3594 pFcb->Header.AllocationSize = pBuffer->AllocationSize;
3596 pFcb->ObjectInformation->AllocationSize = pBuffer->AllocationSize;
3600 // Now Tell the server if we have to
3605 ASSERT( BooleanFlagOn( pFcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_PARENT_FID));
3607 ntStatus = AFSUpdateFileInformation( &pFcb->ObjectInformation->ParentFileId,
3608 pFcb->ObjectInformation,
3612 if (NT_SUCCESS(ntStatus))
3615 // Trim extents if we told the service - the update has done an implicit
3616 // trim at the service.
3620 AFSTrimExtents( pFcb,
3621 &pFcb->Header.FileSize);
3624 KeQuerySystemTime( &pFcb->ObjectInformation->ChangeTime);
3626 SetFlag( pFcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_CHANGE_TIME);
3629 CcIsFileCached( pFileObject))
3631 CcSetFileSizes( pFileObject,
3632 (PCC_FILE_SIZES)&pFcb->Header.AllocationSize);
3636 // Mark the file as modified so as to reflect the change into the last write on close.
3638 SetFlag( pFileObject->Flags, FO_FILE_MODIFIED);
3643 // Put the saved values back
3645 pFcb->Header.ValidDataLength = liSaveVDL;
3646 pFcb->Header.FileSize = liSaveFileSize;
3647 pFcb->Header.AllocationSize = liSaveAlloc;
3648 pFcb->ObjectInformation->EndOfFile = liSaveFileSize;
3649 pFcb->ObjectInformation->AllocationSize = liSaveAlloc;
3655 AFSReleaseResource( &pFcb->NPFcb->PagingResource);
3657 AFSAcquireExcl( &pFcb->NPFcb->Resource,
3665 AFSSetEndOfFileInfo( IN PIRP Irp,
3666 IN AFSDirectoryCB *DirectoryCB)
3668 UNREFERENCED_PARAMETER(DirectoryCB);
3669 NTSTATUS ntStatus = STATUS_SUCCESS;
3670 PFILE_END_OF_FILE_INFORMATION pBuffer;
3671 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
3672 PFILE_OBJECT pFileObject = pIrpSp->FileObject;
3673 LARGE_INTEGER liSaveSize;
3674 LARGE_INTEGER liSaveVDL;
3675 LARGE_INTEGER liSaveAlloc;
3676 BOOLEAN bModified = FALSE;
3677 BOOLEAN bReleasePaging = FALSE;
3678 BOOLEAN bTruncated = FALSE;
3679 BOOLEAN bUserMapped = FALSE;
3680 AFSFcb *pFcb = NULL;
3681 AFSCcb *pCcb = NULL;
3683 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
3685 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
3687 pBuffer = (PFILE_END_OF_FILE_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
3689 liSaveSize = pFcb->Header.FileSize;
3690 liSaveAlloc = pFcb->Header.AllocationSize;
3691 liSaveVDL = pFcb->Header.ValidDataLength;
3693 if( pFcb->Header.FileSize.QuadPart != pBuffer->EndOfFile.QuadPart &&
3694 !pIrpSp->Parameters.SetFile.AdvanceOnly)
3697 if( pBuffer->EndOfFile.QuadPart < pFcb->Header.FileSize.QuadPart)
3700 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
3701 AFS_TRACE_LEVEL_VERBOSE,
3702 "AFSSetEndOfFileInfo Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
3703 &pFcb->NPFcb->SectionObjectResource,
3704 PsGetCurrentThread()));
3706 AFSAcquireExcl( &pFcb->NPFcb->SectionObjectResource,
3712 bUserMapped = !MmCanFileBeTruncated( pFileObject->SectionObjectPointer,
3713 &pBuffer->EndOfFile);
3715 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
3718 bUserMapped = FALSE;
3720 ntStatus = GetExceptionCode();
3724 "EXCEPTION - AFSSetEndOfFileInfo MmCanFileBeTruncated failed FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
3725 pFcb->ObjectInformation->FileId.Cell,
3726 pFcb->ObjectInformation->FileId.Volume,
3727 pFcb->ObjectInformation->FileId.Vnode,
3728 pFcb->ObjectInformation->FileId.Unique,
3732 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
3733 AFS_TRACE_LEVEL_VERBOSE,
3734 "AFSSetEndOfFileInfo Releasing Fcb SectionObject lock %p EXCL %08lX\n",
3735 &pFcb->NPFcb->SectionObjectResource,
3736 PsGetCurrentThread()));
3738 AFSReleaseResource( &pFcb->NPFcb->SectionObjectResource);
3740 // Truncating the file
3744 ntStatus = STATUS_USER_MAPPED_FILE;
3750 // If this is a truncation we need to grab the paging
3753 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3754 AFS_TRACE_LEVEL_VERBOSE,
3755 "AFSSetEndOfFileInfo Acquiring Fcb PagingIo lock %p EXCL %08lX\n",
3756 &pFcb->NPFcb->PagingResource,
3757 PsGetCurrentThread()));
3759 AFSAcquireExcl( &pFcb->NPFcb->PagingResource,
3762 bReleasePaging = TRUE;
3765 // Must drop the Fcb Resource. When changing the file size
3766 // a deadlock can occur with Trend Micro's filter if the file
3767 // size is set to zero.
3770 AFSReleaseResource( &pFcb->NPFcb->Resource);
3772 pFcb->Header.AllocationSize = pBuffer->EndOfFile;
3774 pFcb->Header.FileSize = pBuffer->EndOfFile;
3776 pFcb->ObjectInformation->EndOfFile = pBuffer->EndOfFile;
3778 pFcb->ObjectInformation->AllocationSize = pBuffer->EndOfFile;
3780 if( pFcb->Header.ValidDataLength.QuadPart > pFcb->Header.FileSize.QuadPart)
3783 pFcb->Header.ValidDataLength = pFcb->Header.FileSize;
3795 // extending the file, move EOF
3799 // If this is a truncation we need to grab the paging
3802 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3803 AFS_TRACE_LEVEL_VERBOSE,
3804 "AFSSetEndOfFileInfo Acquiring Fcb PagingIo lock %p EXCL %08lX\n",
3805 &pFcb->NPFcb->PagingResource,
3806 PsGetCurrentThread()));
3808 AFSAcquireExcl( &pFcb->NPFcb->PagingResource,
3811 bReleasePaging = TRUE;
3814 // Must drop the Fcb Resource. When changing the file size
3815 // a deadlock can occur with Trend Micro's filter if the file
3816 // size is set to zero.
3819 AFSReleaseResource( &pFcb->NPFcb->Resource);
3821 pFcb->Header.FileSize = pBuffer->EndOfFile;
3823 pFcb->ObjectInformation->EndOfFile = pBuffer->EndOfFile;
3825 if (pFcb->Header.FileSize.QuadPart > pFcb->Header.AllocationSize.QuadPart)
3828 // And Allocation as needed.
3830 pFcb->Header.AllocationSize = pBuffer->EndOfFile;
3832 pFcb->ObjectInformation->AllocationSize = pBuffer->EndOfFile;
3842 KeQuerySystemTime( &pFcb->ObjectInformation->ChangeTime);
3844 SetFlag( pFcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_CHANGE_TIME);
3850 ASSERT( BooleanFlagOn( pFcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_PARENT_FID));
3852 ntStatus = AFSUpdateFileInformation( &pFcb->ObjectInformation->ParentFileId,
3853 pFcb->ObjectInformation,
3856 if( NT_SUCCESS(ntStatus))
3859 // We are now good to go so tell CC.
3861 CcSetFileSizes( pFileObject,
3862 (PCC_FILE_SIZES)&pFcb->Header.AllocationSize);
3865 // And give up those extents
3870 AFSTrimExtents( pFcb,
3871 &pFcb->Header.FileSize);
3875 // Mark the file as modified so as to reflect the change into the last write on close.
3877 SetFlag( pFileObject->Flags, FO_FILE_MODIFIED);
3881 pFcb->Header.ValidDataLength = liSaveVDL;
3882 pFcb->Header.FileSize = liSaveSize;
3883 pFcb->Header.AllocationSize = liSaveAlloc;
3884 pFcb->ObjectInformation->EndOfFile = liSaveSize;
3885 pFcb->ObjectInformation->AllocationSize = liSaveAlloc;
3892 AFSReleaseResource( &pFcb->NPFcb->PagingResource);
3894 AFSAcquireExcl( &pFcb->NPFcb->Resource,
3902 AFSProcessShareSetInfo( IN IRP *Irp,
3907 UNREFERENCED_PARAMETER(Fcb);
3908 NTSTATUS ntStatus = STATUS_SUCCESS;
3909 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
3910 FILE_INFORMATION_CLASS ulFileInformationClass;
3911 void *pPipeInfo = NULL;
3915 ulFileInformationClass = pIrpSp->Parameters.SetFile.FileInformationClass;
3917 AFSDbgTrace(( AFS_SUBSYSTEM_PIPE_PROCESSING,
3918 AFS_TRACE_LEVEL_VERBOSE,
3919 "AFSProcessShareSetInfo On pipe %wZ Class %08lX\n",
3920 &Ccb->DirectoryCB->NameInformation.FileName,
3921 ulFileInformationClass));
3923 pPipeInfo = AFSLockSystemBuffer( Irp,
3924 pIrpSp->Parameters.SetFile.Length);
3926 if( pPipeInfo == NULL)
3929 AFSDbgTrace(( AFS_SUBSYSTEM_PIPE_PROCESSING,
3930 AFS_TRACE_LEVEL_ERROR,
3931 "AFSProcessShareSetInfo Failed to lock buffer on pipe %wZ\n",
3932 &Ccb->DirectoryCB->NameInformation.FileName));
3934 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
3938 // Send the request to the service
3941 ntStatus = AFSNotifySetPipeInfo( Ccb,
3942 (ULONG)ulFileInformationClass,
3943 pIrpSp->Parameters.SetFile.Length,
3946 if( !NT_SUCCESS( ntStatus))
3949 AFSDbgTrace(( AFS_SUBSYSTEM_PIPE_PROCESSING,
3950 AFS_TRACE_LEVEL_ERROR,
3951 "AFSProcessShareSetInfo Failed to send request to service on pipe %wZ Status %08lX\n",
3952 &Ccb->DirectoryCB->NameInformation.FileName,
3955 try_return( ntStatus);
3958 AFSDbgTrace(( AFS_SUBSYSTEM_PIPE_PROCESSING,
3959 AFS_TRACE_LEVEL_VERBOSE,
3960 "AFSProcessShareSetInfo Completed request on pipe %wZ Class %08lX\n",
3961 &Ccb->DirectoryCB->NameInformation.FileName,
3962 ulFileInformationClass));
3973 AFSProcessShareQueryInfo( IN IRP *Irp,
3978 UNREFERENCED_PARAMETER(Fcb);
3979 NTSTATUS ntStatus = STATUS_SUCCESS;
3980 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
3981 FILE_INFORMATION_CLASS ulFileInformationClass;
3982 void *pPipeInfo = NULL;
3987 ulFileInformationClass = pIrpSp->Parameters.QueryFile.FileInformationClass;
3989 AFSDbgTrace(( AFS_SUBSYSTEM_PIPE_PROCESSING,
3990 AFS_TRACE_LEVEL_VERBOSE,
3991 "AFSProcessShareQueryInfo On pipe %wZ Class %08lX\n",
3992 &Ccb->DirectoryCB->NameInformation.FileName,
3993 ulFileInformationClass));
3995 pPipeInfo = AFSLockSystemBuffer( Irp,
3996 pIrpSp->Parameters.QueryFile.Length);
3998 if( pPipeInfo == NULL)
4001 AFSDbgTrace(( AFS_SUBSYSTEM_PIPE_PROCESSING,
4002 AFS_TRACE_LEVEL_ERROR,
4003 "AFSProcessShareQueryInfo Failed to lock buffer on pipe %wZ\n",
4004 &Ccb->DirectoryCB->NameInformation.FileName));
4006 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4010 // Send the request to the service
4013 ntStatus = AFSNotifyQueryPipeInfo( Ccb,
4014 (ULONG)ulFileInformationClass,
4015 pIrpSp->Parameters.QueryFile.Length,
4017 (ULONG *)&Irp->IoStatus.Information);
4019 if( !NT_SUCCESS( ntStatus))
4022 AFSDbgTrace(( AFS_SUBSYSTEM_PIPE_PROCESSING,
4023 AFS_TRACE_LEVEL_ERROR,
4024 "AFSProcessShareQueryInfo Failed to send request to service on pipe %wZ Status %08lX\n",
4025 &Ccb->DirectoryCB->NameInformation.FileName,
4028 try_return( ntStatus);
4031 AFSDbgTrace(( AFS_SUBSYSTEM_PIPE_PROCESSING,
4032 AFS_TRACE_LEVEL_VERBOSE,
4033 "AFSProcessShareQueryInfo Completed request on pipe %wZ Class %08lX\n",
4034 &Ccb->DirectoryCB->NameInformation.FileName,
4035 ulFileInformationClass));
4046 AFSProcessPIOCtlQueryInfo( IN IRP *Irp,
4049 IN OUT LONG *Length)
4052 UNREFERENCED_PARAMETER(Fcb);
4053 UNREFERENCED_PARAMETER(Ccb);
4054 NTSTATUS ntStatus = STATUS_SUCCESS;
4055 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
4056 FILE_INFORMATION_CLASS ulFileInformationClass;
4061 ulFileInformationClass = pIrpSp->Parameters.QueryFile.FileInformationClass;
4063 switch( ulFileInformationClass)
4066 case FileBasicInformation:
4069 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4070 AFS_TRACE_LEVEL_VERBOSE,
4071 "AFSProcessPIOCtlQueryInfo (FileBasicInformation)\n"));
4073 if ( *Length >= sizeof( FILE_BASIC_INFORMATION))
4075 PFILE_BASIC_INFORMATION pBasic = (PFILE_BASIC_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
4077 pBasic->CreationTime.QuadPart = 0;
4078 pBasic->LastAccessTime.QuadPart = 0;
4079 pBasic->ChangeTime.QuadPart = 0;
4080 pBasic->LastWriteTime.QuadPart = 0;
4081 pBasic->FileAttributes = FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM;
4083 *Length -= sizeof( FILE_BASIC_INFORMATION);
4087 ntStatus = STATUS_BUFFER_TOO_SMALL;
4093 case FileStandardInformation:
4096 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4097 AFS_TRACE_LEVEL_VERBOSE,
4098 "AFSProcessPIOCtlQueryInfo (FileStandardInformation)\n"));
4100 if ( *Length >= sizeof( FILE_STANDARD_INFORMATION))
4102 PFILE_STANDARD_INFORMATION pStandard = (PFILE_STANDARD_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
4104 pStandard->NumberOfLinks = 1;
4105 pStandard->DeletePending = 0;
4106 pStandard->AllocationSize.QuadPart = 0;
4107 pStandard->EndOfFile.QuadPart = 0;
4108 pStandard->Directory = 0;
4110 *Length -= sizeof( FILE_STANDARD_INFORMATION);
4114 ntStatus = STATUS_BUFFER_TOO_SMALL;
4120 case FileNormalizedNameInformation:
4121 case FileNameInformation:
4124 ULONG ulCopyLength = 0;
4125 AFSFcb *pFcb = NULL;
4126 AFSCcb *pCcb = NULL;
4127 USHORT usFullNameLength = 0;
4128 PFILE_NAME_INFORMATION pNameInfo = (PFILE_NAME_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
4129 UNICODE_STRING uniName;
4131 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4132 AFS_TRACE_LEVEL_VERBOSE,
4133 "AFSProcessPIOCtlQueryInfo (FileNameInformation)\n"));
4135 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
4136 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
4138 if( *Length < FIELD_OFFSET( FILE_NAME_INFORMATION, FileName))
4140 ntStatus = STATUS_BUFFER_TOO_SMALL;
4144 RtlZeroMemory( pNameInfo,
4147 usFullNameLength = sizeof( WCHAR) +
4148 AFSServerName.Length +
4149 pCcb->FullFileName.Length;
4151 if( *Length >= (LONG)(FIELD_OFFSET( FILE_NAME_INFORMATION, FileName) + (LONG)usFullNameLength))
4153 ulCopyLength = (LONG)usFullNameLength;
4157 ulCopyLength = *Length - FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
4158 ntStatus = STATUS_BUFFER_OVERFLOW;
4161 pNameInfo->FileNameLength = (ULONG)usFullNameLength;
4163 *Length -= FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
4165 if( ulCopyLength > 0)
4168 pNameInfo->FileName[ 0] = L'\\';
4169 ulCopyLength -= sizeof( WCHAR);
4171 *Length -= sizeof( WCHAR);
4173 if( ulCopyLength >= AFSServerName.Length)
4176 RtlCopyMemory( &pNameInfo->FileName[ 1],
4177 AFSServerName.Buffer,
4178 AFSServerName.Length);
4180 ulCopyLength -= AFSServerName.Length;
4181 *Length -= AFSServerName.Length;
4183 if( ulCopyLength >= pCcb->FullFileName.Length)
4186 RtlCopyMemory( &pNameInfo->FileName[ 1 + (AFSServerName.Length/sizeof( WCHAR))],
4187 pCcb->FullFileName.Buffer,
4188 pCcb->FullFileName.Length);
4190 ulCopyLength -= pCcb->FullFileName.Length;
4191 *Length -= pCcb->FullFileName.Length;
4193 uniName.Length = (USHORT)pNameInfo->FileNameLength;
4194 uniName.MaximumLength = uniName.Length;
4195 uniName.Buffer = pNameInfo->FileName;
4200 RtlCopyMemory( &pNameInfo->FileName[ 1 + (AFSServerName.Length/sizeof( WCHAR))],
4201 pCcb->FullFileName.Buffer,
4204 *Length -= ulCopyLength;
4206 uniName.Length = (USHORT)(sizeof( WCHAR) + AFSServerName.Length + ulCopyLength);
4207 uniName.MaximumLength = uniName.Length;
4208 uniName.Buffer = pNameInfo->FileName;
4211 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4212 AFS_TRACE_LEVEL_VERBOSE,
4213 "AFSProcessPIOCtlQueryInfo (FileNameInformation) Returning %wZ\n",
4221 case FileInternalInformation:
4224 PFILE_INTERNAL_INFORMATION pInternalInfo = (PFILE_INTERNAL_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
4226 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4227 AFS_TRACE_LEVEL_VERBOSE,
4228 "AFSProcessPIOCtlQueryInfo (FileInternalInformation)\n"));
4230 if( *Length >= sizeof( FILE_INTERNAL_INFORMATION))
4233 pInternalInfo->IndexNumber.HighPart = 0;
4235 pInternalInfo->IndexNumber.LowPart = 0;
4237 *Length -= sizeof( FILE_INTERNAL_INFORMATION);
4242 ntStatus = STATUS_BUFFER_TOO_SMALL;
4248 case FileAllInformation:
4250 ntStatus = STATUS_INVALID_PARAMETER;
4252 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4253 AFS_TRACE_LEVEL_WARNING,
4254 "AFSProcessPIOCtlQueryInfo (FileAllInformation) Not Implemented\n"));
4259 case FileEaInformation:
4261 ntStatus = STATUS_INVALID_PARAMETER;
4263 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4264 AFS_TRACE_LEVEL_WARNING,
4265 "AFSProcessPIOCtlQueryInfo (FileEaInformation) Not Implemented\n"));
4270 case FilePositionInformation:
4272 ntStatus = STATUS_INVALID_PARAMETER;
4274 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4275 AFS_TRACE_LEVEL_WARNING,
4276 "AFSProcessPIOCtlQueryInfo (FilePositionInformation) Not Implemented\n"));
4281 case FileAlternateNameInformation:
4283 ntStatus = STATUS_INVALID_PARAMETER;
4285 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4286 AFS_TRACE_LEVEL_WARNING,
4287 "AFSProcessPIOCtlQueryInfo (FileAlternateNameInformation) Not Implemented\n"));
4292 case FileNetworkOpenInformation:
4294 ntStatus = STATUS_INVALID_PARAMETER;
4296 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4297 AFS_TRACE_LEVEL_WARNING,
4298 "AFSProcessPIOCtlQueryInfo (FileNetworkOpenInformation) Not Implemented\n"));
4303 case FileStreamInformation:
4305 ntStatus = STATUS_INVALID_PARAMETER;
4307 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4308 AFS_TRACE_LEVEL_WARNING,
4309 "AFSProcessPIOCtlQueryInfo (FileStreamInformation) Not Implemented\n"));
4314 case FileAttributeTagInformation:
4316 ntStatus = STATUS_INVALID_PARAMETER;
4318 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4319 AFS_TRACE_LEVEL_WARNING,
4320 "AFSProcessPIOCtlQueryInfo (FileAttributeTagInformation) Not Implemented\n"));
4325 case FileRemoteProtocolInformation:
4327 ntStatus = STATUS_INVALID_PARAMETER;
4329 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4330 AFS_TRACE_LEVEL_WARNING,
4331 "AFSProcessPIOCtlQueryInfo (FileRemoteProtocolInformation) Not Implemented\n"));
4336 case FileNetworkPhysicalNameInformation:
4338 ntStatus = STATUS_INVALID_PARAMETER;
4340 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4341 AFS_TRACE_LEVEL_WARNING,
4342 "AFSProcessPIOCtlQueryInfo (FileNetworkPhysicalNameInformation) Not Implemented\n"));
4349 ntStatus = STATUS_INVALID_PARAMETER;
4351 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4352 AFS_TRACE_LEVEL_WARNING,
4353 "AFSProcessPIOCtlQueryInfo Not handling request %08lX\n",
4354 ulFileInformationClass));
4361 AFSDbgTrace(( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4362 AFS_TRACE_LEVEL_VERBOSE,
4363 "AFSProcessPIOCtlQueryInfo ntStatus %08lX\n",