2 * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC.
3 * Copyright (c) 2009, 2010, 2011 Your File System, Inc.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * - Redistributions of source code must retain the above copyright notice,
11 * this list of conditions and the following disclaimer.
12 * - Redistributions in binary form must reproduce the above copyright
14 * this list of conditions and the following disclaimer in the
16 * and/or other materials provided with the distribution.
17 * - Neither the names of Kernel Drivers, LLC and Your File System, Inc.
18 * nor the names of their contributors may be used to endorse or promote
19 * products derived from this software without specific prior written
20 * permission from Kernel Drivers, LLC and Your File System, Inc.
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
24 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
25 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
26 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 // File: AFSFileInfo.cpp
39 #include "AFSCommon.h"
42 // Function: AFSQueryFileInfo
46 // This function is the dispatch handler for the IRP_MJ_QUERY_FILE_INFORMATION request
50 // A status is returned for the function
54 AFSQueryFileInfo( IN PDEVICE_OBJECT LibDeviceObject,
58 UNREFERENCED_PARAMETER(LibDeviceObject);
59 NTSTATUS ntStatus = STATUS_SUCCESS;
60 IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
63 BOOLEAN bReleaseMain = FALSE;
65 FILE_INFORMATION_CLASS stFileInformationClass;
73 // Determine the type of request this request is
76 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
78 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
83 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
84 AFS_TRACE_LEVEL_ERROR,
85 "AFSQueryFileInfo Attempted access (%p) when pFcb == NULL\n",
88 try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST);
91 lLength = (LONG)pIrpSp->Parameters.QueryFile.Length;
92 stFileInformationClass = pIrpSp->Parameters.QueryFile.FileInformationClass;
93 pBuffer = Irp->AssociatedIrp.SystemBuffer;
95 if ( BooleanFlagOn( pFcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY))
98 RtlZeroMemory( &stAuthGroup,
101 AFSRetrieveAuthGroupFnc( (ULONGLONG)PsGetCurrentProcessId(),
102 (ULONGLONG)PsGetCurrentThreadId(),
105 ntStatus = AFSVerifyEntry( &stAuthGroup,
108 if ( NT_SUCCESS( ntStatus))
111 ClearFlag( pFcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY);
116 ntStatus = STATUS_SUCCESS;
121 // Grab the main shared right off the bat
124 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
125 AFS_TRACE_LEVEL_VERBOSE,
126 "AFSQueryFileInfo Acquiring Fcb lock %p SHARED %08lX\n",
127 &pFcb->NPFcb->Resource,
128 PsGetCurrentThread());
130 AFSAcquireShared( &pFcb->NPFcb->Resource,
136 // Don't allow requests against IOCtl nodes
139 if( pFcb->Header.NodeTypeCode == AFS_SPECIAL_SHARE_FCB)
142 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
143 AFS_TRACE_LEVEL_VERBOSE,
144 "AFSQueryFileInfo Processing request against SpecialShare Fcb\n");
146 ntStatus = AFSProcessShareQueryInfo( Irp,
150 try_return( ntStatus);
152 else if( pFcb->Header.NodeTypeCode == AFS_IOCTL_FCB)
154 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
155 AFS_TRACE_LEVEL_VERBOSE,
156 "AFSQueryFileInfo request against PIOCtl Fcb\n");
158 ntStatus = AFSProcessPIOCtlQueryInfo( Irp,
163 try_return( ntStatus);
166 else if( pFcb->Header.NodeTypeCode == AFS_INVALID_FCB)
168 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
169 AFS_TRACE_LEVEL_VERBOSE,
170 "AFSQueryFileInfo request against Invalid Fcb\n");
172 try_return( ntStatus = STATUS_ACCESS_DENIED);
176 // Process the request
179 switch( stFileInformationClass)
182 case FileAllInformation:
185 PFILE_ALL_INFORMATION pAllInfo;
188 // For the all information class we'll typecast a local
189 // pointer to the output buffer and then call the
190 // individual routines to fill in the buffer.
193 pAllInfo = (PFILE_ALL_INFORMATION)pBuffer;
195 ntStatus = AFSQueryBasicInfo( Irp,
197 &pAllInfo->BasicInformation,
200 if( !NT_SUCCESS( ntStatus))
203 try_return( ntStatus);
206 ntStatus = AFSQueryStandardInfo( Irp,
208 &pAllInfo->StandardInformation,
211 if( !NT_SUCCESS( ntStatus))
214 try_return( ntStatus);
217 ntStatus = AFSQueryInternalInfo( Irp,
219 &pAllInfo->InternalInformation,
222 if( !NT_SUCCESS( ntStatus))
225 try_return( ntStatus);
228 ntStatus = AFSQueryEaInfo( Irp,
230 &pAllInfo->EaInformation,
233 if( !NT_SUCCESS( ntStatus))
236 try_return( ntStatus);
239 ntStatus = AFSQueryAccess( Irp,
241 &pAllInfo->AccessInformation,
244 if( !NT_SUCCESS( ntStatus))
247 try_return( ntStatus);
250 ntStatus = AFSQueryPositionInfo( Irp,
252 &pAllInfo->PositionInformation,
255 if( !NT_SUCCESS( ntStatus))
258 try_return( ntStatus);
261 ntStatus = AFSQueryMode( Irp,
263 &pAllInfo->ModeInformation,
266 if( !NT_SUCCESS( ntStatus))
269 try_return( ntStatus);
272 ntStatus = AFSQueryAlignment( Irp,
274 &pAllInfo->AlignmentInformation,
277 if( !NT_SUCCESS( ntStatus))
280 try_return( ntStatus);
283 ntStatus = AFSQueryNameInfo( Irp,
285 &pAllInfo->NameInformation,
288 if( !NT_SUCCESS( ntStatus))
291 try_return( ntStatus);
297 case FileBasicInformation:
300 ntStatus = AFSQueryBasicInfo( Irp,
302 (PFILE_BASIC_INFORMATION)pBuffer,
308 case FileStandardInformation:
311 ntStatus = AFSQueryStandardInfo( Irp,
313 (PFILE_STANDARD_INFORMATION)pBuffer,
319 case FileInternalInformation:
322 ntStatus = AFSQueryInternalInfo( Irp,
324 (PFILE_INTERNAL_INFORMATION)pBuffer,
330 case FileEaInformation:
333 ntStatus = AFSQueryEaInfo( Irp,
335 (PFILE_EA_INFORMATION)pBuffer,
341 case FilePositionInformation:
344 ntStatus = AFSQueryPositionInfo( Irp,
346 (PFILE_POSITION_INFORMATION)pBuffer,
352 case FileNormalizedNameInformation:
353 case FileNameInformation:
356 ntStatus = AFSQueryNameInfo( Irp,
358 (PFILE_NAME_INFORMATION)pBuffer,
364 case FileAlternateNameInformation:
367 ntStatus = AFSQueryShortNameInfo( Irp,
369 (PFILE_NAME_INFORMATION)pBuffer,
375 case FileNetworkOpenInformation:
378 ntStatus = AFSQueryNetworkInfo( Irp,
380 (PFILE_NETWORK_OPEN_INFORMATION)pBuffer,
386 case FileStreamInformation:
389 ntStatus = AFSQueryStreamInfo( Irp,
391 (FILE_STREAM_INFORMATION *)pBuffer,
398 case FileAttributeTagInformation:
401 ntStatus = AFSQueryAttribTagInfo( Irp,
403 (FILE_ATTRIBUTE_TAG_INFORMATION *)pBuffer,
409 case FileRemoteProtocolInformation:
412 ntStatus = AFSQueryRemoteProtocolInfo( Irp,
414 (FILE_REMOTE_PROTOCOL_INFORMATION *)pBuffer,
420 case FileNetworkPhysicalNameInformation:
423 ntStatus = AFSQueryPhysicalNameInfo( Irp,
425 (FILE_NETWORK_PHYSICAL_NAME_INFORMATION *)pBuffer,
433 ntStatus = STATUS_INVALID_PARAMETER;
440 Irp->IoStatus.Information = pIrpSp->Parameters.QueryFile.Length - lLength;
445 AFSReleaseResource( &pFcb->NPFcb->Resource);
448 if( !NT_SUCCESS( ntStatus) &&
449 ntStatus != STATUS_INVALID_PARAMETER &&
450 ntStatus != STATUS_BUFFER_OVERFLOW)
454 pCcb->DirectoryCB != NULL)
457 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
458 AFS_TRACE_LEVEL_ERROR,
459 "AFSQueryFileInfo Failed to process request for %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
460 &pCcb->DirectoryCB->NameInformation.FileName,
461 pCcb->DirectoryCB->ObjectInformation->FileId.Cell,
462 pCcb->DirectoryCB->ObjectInformation->FileId.Volume,
463 pCcb->DirectoryCB->ObjectInformation->FileId.Vnode,
464 pCcb->DirectoryCB->ObjectInformation->FileId.Unique,
469 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
474 "EXCEPTION - AFSQueryFileInfo\n");
476 AFSDumpTraceFilesFnc();
478 ntStatus = STATUS_UNSUCCESSFUL;
483 AFSReleaseResource( &pFcb->NPFcb->Resource);
487 AFSCompleteRequest( Irp,
494 // Function: AFSSetFileInfo
498 // This function is the dispatch handler for the IRP_MJ_SET_FILE_INFORMATION request
502 // A status is returned for the function
506 AFSSetFileInfo( IN PDEVICE_OBJECT LibDeviceObject,
510 UNREFERENCED_PARAMETER(LibDeviceObject);
511 NTSTATUS ntStatus = STATUS_SUCCESS;
512 IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
515 FILE_INFORMATION_CLASS FileInformationClass;
516 BOOLEAN bCanQueueRequest = FALSE;
517 PFILE_OBJECT pFileObject = NULL;
518 BOOLEAN bReleaseMain = FALSE;
519 BOOLEAN bUpdateFileInfo = FALSE;
520 AFSFileID stParentFileId;
525 pFileObject = pIrpSp->FileObject;
527 pFcb = (AFSFcb *)pFileObject->FsContext;
528 pCcb = (AFSCcb *)pFileObject->FsContext2;
533 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
534 AFS_TRACE_LEVEL_ERROR,
535 "AFSSetFileInfo Attempted access (%p) when pFcb == NULL\n",
538 try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST);
541 bCanQueueRequest = !(IoIsOperationSynchronous( Irp) | (KeGetCurrentIrql() != PASSIVE_LEVEL));
542 FileInformationClass = pIrpSp->Parameters.SetFile.FileInformationClass;
548 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
549 AFS_TRACE_LEVEL_VERBOSE,
550 "AFSSetFileInfo Acquiring Fcb lock %p EXCL %08lX\n",
551 &pFcb->NPFcb->Resource,
552 PsGetCurrentThread());
554 AFSAcquireExcl( &pFcb->NPFcb->Resource,
560 // Don't allow requests against IOCtl nodes
563 if( pFcb->Header.NodeTypeCode == AFS_IOCTL_FCB)
566 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
567 AFS_TRACE_LEVEL_ERROR,
568 "AFSSetFileInfo Failing request against PIOCtl Fcb\n");
570 try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST);
572 else if( pFcb->Header.NodeTypeCode == AFS_SPECIAL_SHARE_FCB)
575 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
576 AFS_TRACE_LEVEL_VERBOSE,
577 "AFSSetFileInfo Processing request against SpecialShare Fcb\n");
579 ntStatus = AFSProcessShareSetInfo( Irp,
583 try_return( ntStatus);
586 if( BooleanFlagOn( pFcb->ObjectInformation->VolumeCB->VolumeInformation.Characteristics, FILE_READ_ONLY_DEVICE))
589 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
590 AFS_TRACE_LEVEL_ERROR,
591 "AFSSetFileInfo Request failed due to read only volume\n",
594 try_return( ntStatus = STATUS_MEDIA_WRITE_PROTECTED);
597 if( pFcb->Header.NodeTypeCode == AFS_INVALID_FCB &&
598 FileInformationClass != FileDispositionInformation)
600 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
601 AFS_TRACE_LEVEL_VERBOSE,
602 "AFSSetFileInfo request against Invalid Fcb\n");
604 try_return( ntStatus = STATUS_ACCESS_DENIED);
608 // Ensure rename operations are synchronous
611 if( FileInformationClass == FileRenameInformation)
614 bCanQueueRequest = FALSE;
618 // Store away the parent fid
621 RtlZeroMemory( &stParentFileId,
624 if( BooleanFlagOn( pFcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
627 stParentFileId = pFcb->ObjectInformation->ParentFileId;
631 // Process the request
634 switch( FileInformationClass)
637 case FileBasicInformation:
640 bUpdateFileInfo = TRUE;
642 ntStatus = AFSSetBasicInfo( Irp,
648 case FileDispositionInformation:
651 ntStatus = AFSSetDispositionInfo( Irp,
657 case FileRenameInformation:
660 ntStatus = AFSSetRenameInfo( Irp);
665 case FilePositionInformation:
668 ntStatus = AFSSetPositionInfo( Irp,
674 case FileLinkInformation:
677 ntStatus = AFSSetFileLinkInfo( Irp);
682 case FileAllocationInformation:
685 ntStatus = AFSSetAllocationInfo( Irp,
691 case FileEndOfFileInformation:
694 ntStatus = AFSSetEndOfFileInfo( Irp,
702 ntStatus = STATUS_INVALID_PARAMETER;
712 AFSReleaseResource( &pFcb->NPFcb->Resource);
715 if( NT_SUCCESS( ntStatus) &&
719 ntStatus = AFSUpdateFileInformation( &stParentFileId,
720 pFcb->ObjectInformation,
723 if( !NT_SUCCESS( ntStatus))
726 AFSAcquireExcl( &pFcb->NPFcb->Resource,
730 // Unwind the update and fail the request
733 AFSUnwindFileInfo( pFcb,
736 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
737 AFS_TRACE_LEVEL_ERROR,
738 "AFSSetFileInfo Failed to send file info update to service request for %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
739 &pCcb->DirectoryCB->NameInformation.FileName,
740 pCcb->DirectoryCB->ObjectInformation->FileId.Cell,
741 pCcb->DirectoryCB->ObjectInformation->FileId.Volume,
742 pCcb->DirectoryCB->ObjectInformation->FileId.Vnode,
743 pCcb->DirectoryCB->ObjectInformation->FileId.Unique,
746 AFSReleaseResource( &pFcb->NPFcb->Resource);
750 if( !NT_SUCCESS( ntStatus))
754 pCcb->DirectoryCB != NULL)
757 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
758 AFS_TRACE_LEVEL_ERROR,
759 "AFSSetFileInfo Failed to process request for %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
760 &pCcb->DirectoryCB->NameInformation.FileName,
761 pCcb->DirectoryCB->ObjectInformation->FileId.Cell,
762 pCcb->DirectoryCB->ObjectInformation->FileId.Volume,
763 pCcb->DirectoryCB->ObjectInformation->FileId.Vnode,
764 pCcb->DirectoryCB->ObjectInformation->FileId.Unique,
769 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
774 "EXCEPTION - AFSSetFileInfo\n");
776 AFSDumpTraceFilesFnc();
778 ntStatus = STATUS_UNSUCCESSFUL;
783 AFSReleaseResource( &pFcb->NPFcb->Resource);
787 AFSCompleteRequest( Irp,
794 // Function: AFSQueryBasicInfo
798 // This function is the handler for the query basic information request
802 // A status is returned for the function
806 AFSQueryBasicInfo( IN PIRP Irp,
807 IN AFSDirectoryCB *DirectoryCB,
808 IN OUT PFILE_BASIC_INFORMATION Buffer,
811 NTSTATUS ntStatus = STATUS_SUCCESS;
812 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
813 ULONG ulFileAttribs = 0;
816 IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
817 AFSFileInfoCB stFileInfo;
818 AFSDirectoryCB *pParentDirectoryCB = NULL;
819 UNICODE_STRING uniParentPath;
821 if( *Length >= sizeof( FILE_BASIC_INFORMATION))
824 RtlZeroMemory( Buffer,
827 ulFileAttribs = DirectoryCB->ObjectInformation->FileAttributes;
829 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
830 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
832 if( DirectoryCB->ObjectInformation->FileType == AFS_FILE_TYPE_SYMLINK)
835 pParentDirectoryCB = AFSGetParentEntry( pCcb->NameArray);
837 AFSRetrieveParentPath( &pCcb->FullFileName,
840 RtlZeroMemory( &stFileInfo,
841 sizeof( AFSFileInfoCB));
844 // Can't hold the Fcb while evaluating the path, leads to lock inversion
847 AFSReleaseResource( &pFcb->NPFcb->Resource);
849 if( NT_SUCCESS( AFSRetrieveFileAttributes( pParentDirectoryCB,
857 if ( ulFileAttribs == FILE_ATTRIBUTE_NORMAL)
860 ulFileAttribs = FILE_ATTRIBUTE_REPARSE_POINT;
865 ulFileAttribs |= FILE_ATTRIBUTE_REPARSE_POINT;
868 if ( stFileInfo.FileAttributes & FILE_ATTRIBUTE_DIRECTORY)
871 ulFileAttribs |= FILE_ATTRIBUTE_DIRECTORY;
875 AFSAcquireShared( &pFcb->NPFcb->Resource,
880 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
881 AFS_TRACE_LEVEL_VERBOSE_2,
882 "AFSQueryBasicInfo %wZ Type 0x%x Attrib 0x%x -> 0x%x\n",
883 &pCcb->DirectoryCB->NameInformation.FileName,
884 pCcb->DirectoryCB->ObjectInformation->FileType,
885 pCcb->DirectoryCB->ObjectInformation->FileAttributes,
888 Buffer->CreationTime = DirectoryCB->ObjectInformation->CreationTime;
889 Buffer->LastAccessTime = DirectoryCB->ObjectInformation->LastAccessTime;
890 Buffer->LastWriteTime = DirectoryCB->ObjectInformation->LastWriteTime;
891 Buffer->ChangeTime = DirectoryCB->ObjectInformation->ChangeTime;
892 Buffer->FileAttributes = ulFileAttribs;
894 if( DirectoryCB->NameInformation.FileName.Buffer[ 0] == L'.' &&
895 BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_HIDE_DOT_NAMES))
898 if ( Buffer->FileAttributes != FILE_ATTRIBUTE_NORMAL)
900 Buffer->FileAttributes |= FILE_ATTRIBUTE_HIDDEN;
904 Buffer->FileAttributes = FILE_ATTRIBUTE_HIDDEN;
908 *Length -= sizeof( FILE_BASIC_INFORMATION);
913 ntStatus = STATUS_BUFFER_TOO_SMALL;
920 AFSQueryStandardInfo( IN PIRP Irp,
921 IN AFSDirectoryCB *DirectoryCB,
922 IN OUT PFILE_STANDARD_INFORMATION Buffer,
926 NTSTATUS ntStatus = STATUS_SUCCESS;
929 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
930 AFSFileInfoCB stFileInfo;
931 AFSDirectoryCB *pParentDirectoryCB = NULL;
932 UNICODE_STRING uniParentPath;
933 ULONG ulFileAttribs = 0;
935 if( *Length >= sizeof( FILE_STANDARD_INFORMATION))
938 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
939 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
941 RtlZeroMemory( Buffer,
944 Buffer->NumberOfLinks = 1;
945 Buffer->DeletePending = BooleanFlagOn( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
947 Buffer->AllocationSize.QuadPart = (ULONGLONG)((DirectoryCB->ObjectInformation->AllocationSize.QuadPart/PAGE_SIZE) + 1) * PAGE_SIZE;
949 Buffer->EndOfFile = DirectoryCB->ObjectInformation->EndOfFile;
951 ulFileAttribs = DirectoryCB->ObjectInformation->FileAttributes;
953 if( DirectoryCB->ObjectInformation->FileType == AFS_FILE_TYPE_SYMLINK)
956 pParentDirectoryCB = AFSGetParentEntry( pCcb->NameArray);
958 AFSRetrieveParentPath( &pCcb->FullFileName,
961 RtlZeroMemory( &stFileInfo,
962 sizeof( AFSFileInfoCB));
965 // Can't hold the Fcb while evaluating the path, leads to lock inversion
968 AFSReleaseResource( &pFcb->NPFcb->Resource);
970 if( NT_SUCCESS( AFSRetrieveFileAttributes( pParentDirectoryCB,
978 if ( ulFileAttribs == FILE_ATTRIBUTE_NORMAL)
981 ulFileAttribs = FILE_ATTRIBUTE_REPARSE_POINT;
986 ulFileAttribs |= FILE_ATTRIBUTE_REPARSE_POINT;
989 if ( stFileInfo.FileAttributes & FILE_ATTRIBUTE_DIRECTORY)
992 ulFileAttribs |= FILE_ATTRIBUTE_DIRECTORY;
996 AFSAcquireShared( &pFcb->NPFcb->Resource,
1000 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1001 AFS_TRACE_LEVEL_VERBOSE_2,
1002 "AFSQueryStandardInfo %wZ Type 0x%x Attrib 0x%x -> 0x%x\n",
1003 &pCcb->DirectoryCB->NameInformation.FileName,
1004 pCcb->DirectoryCB->ObjectInformation->FileType,
1005 pCcb->DirectoryCB->ObjectInformation->FileAttributes,
1008 Buffer->Directory = BooleanFlagOn( ulFileAttribs, FILE_ATTRIBUTE_DIRECTORY);
1010 *Length -= sizeof( FILE_STANDARD_INFORMATION);
1015 ntStatus = STATUS_BUFFER_TOO_SMALL;
1022 AFSQueryInternalInfo( IN PIRP Irp,
1024 IN OUT PFILE_INTERNAL_INFORMATION Buffer,
1025 IN OUT PLONG Length)
1028 UNREFERENCED_PARAMETER(Irp);
1029 NTSTATUS ntStatus = STATUS_SUCCESS;
1031 if( *Length >= sizeof( FILE_INTERNAL_INFORMATION))
1034 Buffer->IndexNumber.HighPart = Fcb->ObjectInformation->FileId.Volume;
1036 Buffer->IndexNumber.LowPart = Fcb->ObjectInformation->FileId.Vnode;
1038 *Length -= sizeof( FILE_INTERNAL_INFORMATION);
1043 ntStatus = STATUS_BUFFER_TOO_SMALL;
1050 AFSQueryEaInfo( IN PIRP Irp,
1051 IN AFSDirectoryCB *DirectoryCB,
1052 IN OUT PFILE_EA_INFORMATION Buffer,
1053 IN OUT PLONG Length)
1056 UNREFERENCED_PARAMETER(Irp);
1057 UNREFERENCED_PARAMETER(DirectoryCB);
1058 NTSTATUS ntStatus = STATUS_SUCCESS;
1060 RtlZeroMemory( Buffer,
1063 if( *Length >= sizeof( FILE_EA_INFORMATION))
1068 *Length -= sizeof( FILE_EA_INFORMATION);
1073 ntStatus = STATUS_BUFFER_TOO_SMALL;
1080 AFSQueryPositionInfo( IN PIRP Irp,
1082 IN OUT PFILE_POSITION_INFORMATION Buffer,
1083 IN OUT PLONG Length)
1086 UNREFERENCED_PARAMETER(Fcb);
1087 NTSTATUS ntStatus = STATUS_SUCCESS;
1088 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1090 if( *Length >= sizeof( FILE_POSITION_INFORMATION))
1093 RtlZeroMemory( Buffer,
1096 Buffer->CurrentByteOffset.QuadPart = pIrpSp->FileObject->CurrentByteOffset.QuadPart;
1098 *Length -= sizeof( FILE_POSITION_INFORMATION);
1103 ntStatus = STATUS_BUFFER_TOO_SMALL;
1110 AFSQueryAccess( IN PIRP Irp,
1112 IN OUT PFILE_ACCESS_INFORMATION Buffer,
1113 IN OUT PLONG Length)
1116 UNREFERENCED_PARAMETER(Irp);
1117 UNREFERENCED_PARAMETER(Fcb);
1118 NTSTATUS ntStatus = STATUS_SUCCESS;
1120 if( *Length >= sizeof( FILE_ACCESS_INFORMATION))
1123 RtlZeroMemory( Buffer,
1126 Buffer->AccessFlags = 0;
1128 *Length -= sizeof( FILE_ACCESS_INFORMATION);
1133 ntStatus = STATUS_BUFFER_TOO_SMALL;
1140 AFSQueryMode( IN PIRP Irp,
1142 IN OUT PFILE_MODE_INFORMATION Buffer,
1143 IN OUT PLONG Length)
1146 UNREFERENCED_PARAMETER(Irp);
1147 UNREFERENCED_PARAMETER(Fcb);
1148 NTSTATUS ntStatus = STATUS_SUCCESS;
1150 if( *Length >= sizeof( FILE_MODE_INFORMATION))
1153 RtlZeroMemory( Buffer,
1158 *Length -= sizeof( FILE_MODE_INFORMATION);
1163 ntStatus = STATUS_BUFFER_TOO_SMALL;
1170 AFSQueryAlignment( IN PIRP Irp,
1172 IN OUT PFILE_ALIGNMENT_INFORMATION Buffer,
1173 IN OUT PLONG Length)
1176 UNREFERENCED_PARAMETER(Irp);
1177 UNREFERENCED_PARAMETER(Fcb);
1178 NTSTATUS ntStatus = STATUS_SUCCESS;
1180 if( *Length >= sizeof( FILE_ALIGNMENT_INFORMATION))
1183 RtlZeroMemory( Buffer,
1186 Buffer->AlignmentRequirement = 1;
1188 *Length -= sizeof( FILE_ALIGNMENT_INFORMATION);
1193 ntStatus = STATUS_BUFFER_TOO_SMALL;
1200 AFSQueryNameInfo( IN PIRP Irp,
1201 IN AFSDirectoryCB *DirectoryCB,
1202 IN OUT PFILE_NAME_INFORMATION Buffer,
1203 IN OUT PLONG Length)
1206 UNREFERENCED_PARAMETER(DirectoryCB);
1207 NTSTATUS ntStatus = STATUS_SUCCESS;
1208 ULONG ulCopyLength = 0;
1209 ULONG cchCopied = 0;
1210 AFSFcb *pFcb = NULL;
1211 AFSCcb *pCcb = NULL;
1212 IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1213 BOOLEAN bAddLeadingSlash = FALSE;
1214 BOOLEAN bAddTrailingSlash = FALSE;
1215 USHORT usFullNameLength = 0;
1217 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
1219 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
1221 if( *Length >= FIELD_OFFSET( FILE_NAME_INFORMATION, FileName))
1224 RtlZeroMemory( Buffer,
1227 if( pCcb->FullFileName.Length == 0 ||
1228 pCcb->FullFileName.Buffer[ 0] != L'\\')
1230 bAddLeadingSlash = TRUE;
1233 if( pFcb->ObjectInformation->FileType == AFS_FILE_TYPE_DIRECTORY &&
1234 pCcb->FullFileName.Length > 0 &&
1235 pCcb->FullFileName.Buffer[ (pCcb->FullFileName.Length/sizeof( WCHAR)) - 1] != L'\\')
1237 bAddTrailingSlash = TRUE;
1240 usFullNameLength = sizeof( WCHAR) +
1241 AFSServerName.Length +
1242 pCcb->FullFileName.Length;
1244 if( bAddLeadingSlash)
1246 usFullNameLength += sizeof( WCHAR);
1249 if( bAddTrailingSlash)
1251 usFullNameLength += sizeof( WCHAR);
1254 if( *Length >= (LONG)(FIELD_OFFSET( FILE_NAME_INFORMATION, FileName) + (LONG)usFullNameLength))
1257 ulCopyLength = (LONG)usFullNameLength;
1262 ulCopyLength = *Length - FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
1264 ntStatus = STATUS_BUFFER_OVERFLOW;
1267 Buffer->FileNameLength = (ULONG)usFullNameLength;
1269 *Length -= FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
1271 if( ulCopyLength > 0)
1274 Buffer->FileName[ 0] = L'\\';
1275 ulCopyLength -= sizeof( WCHAR);
1277 *Length -= sizeof( WCHAR);
1280 if( ulCopyLength >= AFSServerName.Length)
1283 RtlCopyMemory( &Buffer->FileName[ 1],
1284 AFSServerName.Buffer,
1285 AFSServerName.Length);
1287 ulCopyLength -= AFSServerName.Length;
1288 *Length -= AFSServerName.Length;
1289 cchCopied += AFSServerName.Length/sizeof( WCHAR);
1291 if ( ulCopyLength > 0 &&
1295 Buffer->FileName[ cchCopied] = L'\\';
1297 ulCopyLength -= sizeof( WCHAR);
1298 *Length -= sizeof( WCHAR);
1302 if( ulCopyLength >= pCcb->FullFileName.Length)
1305 RtlCopyMemory( &Buffer->FileName[ cchCopied],
1306 pCcb->FullFileName.Buffer,
1307 pCcb->FullFileName.Length);
1309 ulCopyLength -= pCcb->FullFileName.Length;
1310 *Length -= pCcb->FullFileName.Length;
1311 cchCopied += pCcb->FullFileName.Length/sizeof( WCHAR);
1313 if( ulCopyLength > 0 &&
1316 Buffer->FileName[ cchCopied] = L'\\';
1318 *Length -= sizeof( WCHAR);
1324 RtlCopyMemory( &Buffer->FileName[ cchCopied],
1325 pCcb->FullFileName.Buffer,
1328 *Length -= ulCopyLength;
1336 ntStatus = STATUS_BUFFER_TOO_SMALL;
1343 AFSQueryShortNameInfo( IN PIRP Irp,
1344 IN AFSDirectoryCB *DirectoryCB,
1345 IN OUT PFILE_NAME_INFORMATION Buffer,
1346 IN OUT PLONG Length)
1349 UNREFERENCED_PARAMETER(Irp);
1350 NTSTATUS ntStatus = STATUS_BUFFER_TOO_SMALL;
1351 ULONG ulCopyLength = 0;
1353 RtlZeroMemory( Buffer,
1356 if( DirectoryCB->NameInformation.ShortNameLength == 0)
1360 // The short name IS the long name
1363 if( *Length >= (LONG)FIELD_OFFSET( FILE_NAME_INFORMATION, FileName))
1366 if( *Length >= (LONG)(FIELD_OFFSET( FILE_NAME_INFORMATION, FileName) + (LONG)DirectoryCB->NameInformation.FileName.Length))
1369 ulCopyLength = (LONG)DirectoryCB->NameInformation.FileName.Length;
1371 ntStatus = STATUS_SUCCESS;
1376 ulCopyLength = *Length - FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
1378 ntStatus = STATUS_BUFFER_OVERFLOW;
1381 Buffer->FileNameLength = DirectoryCB->NameInformation.FileName.Length;
1383 *Length -= FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
1385 if( ulCopyLength > 0)
1388 RtlCopyMemory( Buffer->FileName,
1389 DirectoryCB->NameInformation.FileName.Buffer,
1392 *Length -= ulCopyLength;
1399 if( *Length >= (LONG)FIELD_OFFSET( FILE_NAME_INFORMATION, FileName))
1402 if( *Length >= (LONG)(FIELD_OFFSET( FILE_NAME_INFORMATION, FileName) + (LONG)DirectoryCB->NameInformation.FileName.Length))
1405 ulCopyLength = (LONG)DirectoryCB->NameInformation.ShortNameLength;
1407 ntStatus = STATUS_SUCCESS;
1412 ulCopyLength = *Length - FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
1414 ntStatus = STATUS_BUFFER_OVERFLOW;
1417 Buffer->FileNameLength = DirectoryCB->NameInformation.ShortNameLength;
1419 *Length -= FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
1421 if( ulCopyLength > 0)
1424 RtlCopyMemory( Buffer->FileName,
1425 DirectoryCB->NameInformation.ShortName,
1426 Buffer->FileNameLength);
1428 *Length -= ulCopyLength;
1437 AFSQueryNetworkInfo( IN PIRP Irp,
1438 IN AFSDirectoryCB *DirectoryCB,
1439 IN OUT PFILE_NETWORK_OPEN_INFORMATION Buffer,
1440 IN OUT PLONG Length)
1443 NTSTATUS ntStatus = STATUS_SUCCESS;
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 RtlZeroMemory( Buffer,
1456 if( *Length >= sizeof( FILE_NETWORK_OPEN_INFORMATION))
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);
1481 if( NT_SUCCESS( AFSRetrieveFileAttributes( pParentDirectoryCB,
1489 if ( ulFileAttribs == FILE_ATTRIBUTE_NORMAL)
1492 ulFileAttribs = FILE_ATTRIBUTE_REPARSE_POINT;
1497 ulFileAttribs |= FILE_ATTRIBUTE_REPARSE_POINT;
1500 if ( stFileInfo.FileAttributes & FILE_ATTRIBUTE_DIRECTORY)
1503 ulFileAttribs |= FILE_ATTRIBUTE_DIRECTORY;
1507 AFSAcquireShared( &pFcb->NPFcb->Resource,
1511 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1512 AFS_TRACE_LEVEL_VERBOSE_2,
1513 "AFSQueryNetworkInfo %wZ Type 0x%x Attrib 0x%x -> 0x%x\n",
1514 &pCcb->DirectoryCB->NameInformation.FileName,
1515 pCcb->DirectoryCB->ObjectInformation->FileType,
1516 pCcb->DirectoryCB->ObjectInformation->FileAttributes,
1519 Buffer->CreationTime.QuadPart = DirectoryCB->ObjectInformation->CreationTime.QuadPart;
1520 Buffer->LastAccessTime.QuadPart = DirectoryCB->ObjectInformation->LastAccessTime.QuadPart;
1521 Buffer->LastWriteTime.QuadPart = DirectoryCB->ObjectInformation->LastWriteTime.QuadPart;
1522 Buffer->ChangeTime.QuadPart = DirectoryCB->ObjectInformation->ChangeTime.QuadPart;
1524 Buffer->AllocationSize.QuadPart = DirectoryCB->ObjectInformation->AllocationSize.QuadPart;
1525 Buffer->EndOfFile.QuadPart = DirectoryCB->ObjectInformation->EndOfFile.QuadPart;
1527 Buffer->FileAttributes = ulFileAttribs;
1529 if( DirectoryCB->NameInformation.FileName.Buffer[ 0] == L'.' &&
1530 BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_HIDE_DOT_NAMES))
1533 if ( Buffer->FileAttributes != FILE_ATTRIBUTE_NORMAL)
1536 Buffer->FileAttributes |= FILE_ATTRIBUTE_HIDDEN;
1541 Buffer->FileAttributes = FILE_ATTRIBUTE_HIDDEN;
1545 *Length -= sizeof( FILE_NETWORK_OPEN_INFORMATION);
1550 ntStatus = STATUS_BUFFER_TOO_SMALL;
1557 AFSQueryStreamInfo( IN PIRP Irp,
1558 IN AFSDirectoryCB *DirectoryCB,
1559 IN OUT FILE_STREAM_INFORMATION *Buffer,
1560 IN OUT PLONG Length)
1563 UNREFERENCED_PARAMETER(Irp);
1564 NTSTATUS ntStatus = STATUS_BUFFER_TOO_SMALL;
1565 ULONG ulCopyLength = 0;
1567 if( *Length >= FIELD_OFFSET( FILE_STREAM_INFORMATION, StreamName))
1570 RtlZeroMemory( Buffer,
1573 Buffer->NextEntryOffset = 0;
1576 if( !BooleanFlagOn( DirectoryCB->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_DIRECTORY))
1579 if( *Length >= (LONG)(FIELD_OFFSET( FILE_STREAM_INFORMATION, StreamName) + 14)) // ::$DATA
1584 ntStatus = STATUS_SUCCESS;
1589 ulCopyLength = *Length - FIELD_OFFSET( FILE_STREAM_INFORMATION, StreamName);
1591 ntStatus = STATUS_BUFFER_OVERFLOW;
1594 Buffer->StreamNameLength = 14; // ::$DATA
1596 Buffer->StreamSize.QuadPart = DirectoryCB->ObjectInformation->EndOfFile.QuadPart;
1598 Buffer->StreamAllocationSize.QuadPart = DirectoryCB->ObjectInformation->AllocationSize.QuadPart;
1600 *Length -= FIELD_OFFSET( FILE_STREAM_INFORMATION, StreamName);
1602 if( ulCopyLength > 0)
1605 RtlCopyMemory( Buffer->StreamName,
1609 *Length -= ulCopyLength;
1615 Buffer->StreamNameLength = 0; // No stream for a directory
1617 // The response size is zero
1619 ntStatus = STATUS_SUCCESS;
1627 AFSQueryAttribTagInfo( IN PIRP Irp,
1628 IN AFSDirectoryCB *DirectoryCB,
1629 IN OUT FILE_ATTRIBUTE_TAG_INFORMATION *Buffer,
1630 IN OUT PLONG Length)
1633 NTSTATUS ntStatus = STATUS_BUFFER_TOO_SMALL;
1634 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1635 AFSFcb *pFcb = NULL;
1636 AFSCcb *pCcb = NULL;
1637 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1638 AFSFileInfoCB stFileInfo;
1639 AFSDirectoryCB *pParentDirectoryCB = NULL;
1640 UNICODE_STRING uniParentPath;
1641 ULONG ulFileAttribs = 0;
1643 if( *Length >= sizeof( FILE_ATTRIBUTE_TAG_INFORMATION))
1646 RtlZeroMemory( Buffer,
1649 ulFileAttribs = DirectoryCB->ObjectInformation->FileAttributes;
1651 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
1652 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
1654 if( DirectoryCB->ObjectInformation->FileType == AFS_FILE_TYPE_SYMLINK)
1657 pParentDirectoryCB = AFSGetParentEntry( pCcb->NameArray);
1659 AFSRetrieveParentPath( &pCcb->FullFileName,
1662 RtlZeroMemory( &stFileInfo,
1663 sizeof( AFSFileInfoCB));
1666 // Can't hold the Fcb while evaluating the path, leads to lock inversion
1669 AFSReleaseResource( &pFcb->NPFcb->Resource);
1671 if( NT_SUCCESS( AFSRetrieveFileAttributes( pParentDirectoryCB,
1679 if ( ulFileAttribs == FILE_ATTRIBUTE_NORMAL)
1682 ulFileAttribs = FILE_ATTRIBUTE_REPARSE_POINT;
1687 ulFileAttribs |= FILE_ATTRIBUTE_REPARSE_POINT;
1690 if ( stFileInfo.FileAttributes & FILE_ATTRIBUTE_DIRECTORY)
1693 ulFileAttribs |= FILE_ATTRIBUTE_DIRECTORY;
1697 AFSAcquireShared( &pFcb->NPFcb->Resource,
1701 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1702 AFS_TRACE_LEVEL_VERBOSE_2,
1703 "AFSAttribTagInfo %wZ Type 0x%x Attrib 0x%x -> 0x%x\n",
1704 &pCcb->DirectoryCB->NameInformation.FileName,
1705 pCcb->DirectoryCB->ObjectInformation->FileType,
1706 pCcb->DirectoryCB->ObjectInformation->FileAttributes,
1709 Buffer->FileAttributes = ulFileAttribs;
1711 if( DirectoryCB->NameInformation.FileName.Buffer[ 0] == L'.' &&
1712 BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_HIDE_DOT_NAMES))
1715 if ( Buffer->FileAttributes != FILE_ATTRIBUTE_NORMAL)
1718 Buffer->FileAttributes |= FILE_ATTRIBUTE_HIDDEN;
1723 Buffer->FileAttributes = FILE_ATTRIBUTE_HIDDEN;
1727 if( BooleanFlagOn( DirectoryCB->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_REPARSE_POINT))
1729 Buffer->ReparseTag = IO_REPARSE_TAG_SURROGATE|IO_REPARSE_TAG_OPENAFS_DFS;
1732 *Length -= sizeof( FILE_ATTRIBUTE_TAG_INFORMATION);
1734 ntStatus = STATUS_SUCCESS;
1741 AFSQueryRemoteProtocolInfo( IN PIRP Irp,
1742 IN AFSDirectoryCB *DirectoryCB,
1743 IN OUT FILE_REMOTE_PROTOCOL_INFORMATION *Buffer,
1744 IN OUT PLONG Length)
1747 UNREFERENCED_PARAMETER(Irp);
1748 UNREFERENCED_PARAMETER(DirectoryCB);
1749 NTSTATUS ntStatus = STATUS_BUFFER_TOO_SMALL;
1751 if( *Length >= sizeof( FILE_REMOTE_PROTOCOL_INFORMATION))
1754 RtlZeroMemory( Buffer,
1757 Buffer->StructureVersion = 1;
1759 Buffer->StructureSize = sizeof(FILE_REMOTE_PROTOCOL_INFORMATION);
1761 Buffer->Protocol = WNNC_NET_OPENAFS;
1763 Buffer->ProtocolMajorVersion = 3;
1765 Buffer->ProtocolMinorVersion = 0;
1767 Buffer->ProtocolRevision = 0;
1769 *Length -= sizeof( FILE_REMOTE_PROTOCOL_INFORMATION);
1771 ntStatus = STATUS_SUCCESS;
1778 AFSQueryPhysicalNameInfo( IN PIRP Irp,
1779 IN AFSDirectoryCB *DirectoryCB,
1780 IN OUT PFILE_NETWORK_PHYSICAL_NAME_INFORMATION Buffer,
1781 IN OUT PLONG Length)
1784 UNREFERENCED_PARAMETER(DirectoryCB);
1785 NTSTATUS ntStatus = STATUS_SUCCESS;
1786 ULONG ulCopyLength = 0;
1787 ULONG cchCopied = 0;
1788 AFSFcb *pFcb = NULL;
1789 AFSCcb *pCcb = NULL;
1790 IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1791 BOOLEAN bAddLeadingSlash = FALSE;
1792 USHORT usFullNameLength = 0;
1794 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
1796 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
1798 if( *Length >= FIELD_OFFSET( FILE_NETWORK_PHYSICAL_NAME_INFORMATION, FileName))
1801 RtlZeroMemory( Buffer,
1804 if( pCcb->FullFileName.Length == 0 ||
1805 pCcb->FullFileName.Buffer[ 0] != L'\\')
1807 bAddLeadingSlash = TRUE;
1810 usFullNameLength = pCcb->FullFileName.Length;
1812 if( bAddLeadingSlash)
1814 usFullNameLength += sizeof( WCHAR);
1817 if( *Length >= (LONG)(FIELD_OFFSET( FILE_NETWORK_PHYSICAL_NAME_INFORMATION, FileName) + (LONG)usFullNameLength))
1819 ulCopyLength = (LONG)usFullNameLength;
1824 ulCopyLength = *Length - FIELD_OFFSET( FILE_NETWORK_PHYSICAL_NAME_INFORMATION, FileName);
1826 ntStatus = STATUS_BUFFER_OVERFLOW;
1829 Buffer->FileNameLength = (ULONG)usFullNameLength;
1831 *Length -= FIELD_OFFSET( FILE_NETWORK_PHYSICAL_NAME_INFORMATION, FileName);
1833 if( ulCopyLength > 0)
1836 if( bAddLeadingSlash)
1839 Buffer->FileName[ cchCopied] = L'\\';
1841 ulCopyLength -= sizeof( WCHAR);
1842 *Length -= sizeof( WCHAR);
1846 if( ulCopyLength >= pCcb->FullFileName.Length)
1849 RtlCopyMemory( &Buffer->FileName[ cchCopied],
1850 pCcb->FullFileName.Buffer,
1851 pCcb->FullFileName.Length);
1853 ulCopyLength -= pCcb->FullFileName.Length;
1854 *Length -= pCcb->FullFileName.Length;
1855 cchCopied += pCcb->FullFileName.Length/sizeof( WCHAR);
1860 RtlCopyMemory( &Buffer->FileName[ cchCopied],
1861 pCcb->FullFileName.Buffer,
1864 *Length -= ulCopyLength;
1871 ntStatus = STATUS_BUFFER_TOO_SMALL;
1878 AFSSetBasicInfo( IN PIRP Irp,
1879 IN AFSDirectoryCB *DirectoryCB)
1881 NTSTATUS ntStatus = STATUS_SUCCESS;
1882 PFILE_BASIC_INFORMATION pBuffer;
1883 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1884 ULONG ulNotifyFilter = 0;
1885 AFSCcb *pCcb = NULL;
1890 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
1892 pBuffer = (PFILE_BASIC_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
1894 pCcb->FileUnwindInfo.FileAttributes = (ULONG)-1;
1896 if( pBuffer->FileAttributes != (ULONGLONG)0)
1899 if( DirectoryCB->ObjectInformation->Fcb->Header.NodeTypeCode == AFS_FILE_FCB &&
1900 BooleanFlagOn( pBuffer->FileAttributes, FILE_ATTRIBUTE_DIRECTORY))
1903 try_return( ntStatus = STATUS_INVALID_PARAMETER);
1906 if( DirectoryCB->ObjectInformation->Fcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB)
1909 pBuffer->FileAttributes |= FILE_ATTRIBUTE_DIRECTORY;
1912 pCcb->FileUnwindInfo.FileAttributes = DirectoryCB->ObjectInformation->FileAttributes;
1914 DirectoryCB->ObjectInformation->FileAttributes = pBuffer->FileAttributes;
1916 ulNotifyFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
1918 SetFlag( DirectoryCB->ObjectInformation->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED);
1921 pCcb->FileUnwindInfo.CreationTime.QuadPart = (ULONGLONG)-1;
1923 if( pBuffer->CreationTime.QuadPart != (ULONGLONG)-1 &&
1924 pBuffer->CreationTime.QuadPart != (ULONGLONG)0)
1927 pCcb->FileUnwindInfo.CreationTime.QuadPart = DirectoryCB->ObjectInformation->CreationTime.QuadPart;
1929 DirectoryCB->ObjectInformation->CreationTime.QuadPart = pBuffer->CreationTime.QuadPart;
1931 ulNotifyFilter |= FILE_NOTIFY_CHANGE_CREATION;
1933 SetFlag( DirectoryCB->ObjectInformation->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_CREATE_TIME);
1936 pCcb->FileUnwindInfo.LastAccessTime.QuadPart = (ULONGLONG)-1;
1938 if( pBuffer->LastAccessTime.QuadPart != (ULONGLONG)-1 &&
1939 pBuffer->LastAccessTime.QuadPart != (ULONGLONG)0)
1942 pCcb->FileUnwindInfo.LastAccessTime.QuadPart = DirectoryCB->ObjectInformation->LastAccessTime.QuadPart;
1944 DirectoryCB->ObjectInformation->LastAccessTime.QuadPart = pBuffer->LastAccessTime.QuadPart;
1946 ulNotifyFilter |= FILE_NOTIFY_CHANGE_LAST_ACCESS;
1948 SetFlag( DirectoryCB->ObjectInformation->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_ACCESS_TIME);
1951 pCcb->FileUnwindInfo.LastWriteTime.QuadPart = (ULONGLONG)-1;
1953 if( pBuffer->LastWriteTime.QuadPart != (ULONGLONG)-1 &&
1954 pBuffer->LastWriteTime.QuadPart != (ULONGLONG)0)
1957 pCcb->FileUnwindInfo.LastWriteTime.QuadPart = DirectoryCB->ObjectInformation->LastWriteTime.QuadPart;
1959 DirectoryCB->ObjectInformation->LastWriteTime.QuadPart = pBuffer->LastWriteTime.QuadPart;
1961 ulNotifyFilter |= FILE_NOTIFY_CHANGE_LAST_WRITE;
1963 SetFlag( DirectoryCB->ObjectInformation->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_LAST_WRITE_TIME);
1966 pCcb->FileUnwindInfo.ChangeTime.QuadPart = (ULONGLONG)-1;
1968 if( pBuffer->ChangeTime.QuadPart != (ULONGLONG)-1 &&
1969 pBuffer->ChangeTime.QuadPart != (ULONGLONG)0)
1972 pCcb->FileUnwindInfo.ChangeTime.QuadPart = DirectoryCB->ObjectInformation->ChangeTime.QuadPart;
1974 DirectoryCB->ObjectInformation->ChangeTime.QuadPart = pBuffer->ChangeTime.QuadPart;
1976 ulNotifyFilter |= FILE_NOTIFY_CHANGE_LAST_ACCESS;
1978 SetFlag( DirectoryCB->ObjectInformation->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_CHANGE_TIME);
1981 if( ulNotifyFilter > 0)
1984 if( BooleanFlagOn( DirectoryCB->ObjectInformation->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
1987 AFSObjectInfoCB * pParentObjectInfo = AFSFindObjectInfo( DirectoryCB->ObjectInformation->VolumeCB,
1988 &DirectoryCB->ObjectInformation->ParentFileId);
1990 if ( pParentObjectInfo != NULL)
1992 AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
1994 (ULONG)ulNotifyFilter,
1995 (ULONG)FILE_ACTION_MODIFIED);
1997 AFSReleaseObjectInfo( &pParentObjectInfo);
2011 AFSSetDispositionInfo( IN PIRP Irp,
2012 IN AFSDirectoryCB *DirectoryCB)
2014 NTSTATUS ntStatus = STATUS_SUCCESS;
2015 PFILE_DISPOSITION_INFORMATION pBuffer;
2016 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2017 AFSFcb *pFcb = NULL;
2018 AFSCcb *pCcb = NULL;
2023 pBuffer = (PFILE_DISPOSITION_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
2025 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
2027 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
2030 // Can't delete the root
2033 if( pFcb->Header.NodeTypeCode == AFS_ROOT_FCB)
2036 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2037 AFS_TRACE_LEVEL_ERROR,
2038 "AFSSetDispositionInfo Attempt to delete root entry\n");
2040 try_return( ntStatus = STATUS_CANNOT_DELETE);
2044 // If the file is read only then do not allow the delete
2047 if( BooleanFlagOn( DirectoryCB->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_READONLY))
2050 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2051 AFS_TRACE_LEVEL_ERROR,
2052 "AFSSetDispositionInfo Attempt to delete read only entry %wZ\n",
2053 &DirectoryCB->NameInformation.FileName);
2055 try_return( ntStatus = STATUS_CANNOT_DELETE);
2058 if( pBuffer->DeleteFile)
2062 // Check if the caller can delete the file
2065 ntStatus = AFSNotifyDelete( DirectoryCB,
2069 if( !NT_SUCCESS( ntStatus))
2072 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2073 AFS_TRACE_LEVEL_ERROR,
2074 "AFSSetDispositionInfo Cannot delete entry %wZ Status %08lX\n",
2075 &DirectoryCB->NameInformation.FileName,
2078 try_return( ntStatus);
2081 if( pFcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB)
2085 // Reduce the Link count in the object information block
2086 // to correspond with the deletion of the directory entry.
2089 pFcb->ObjectInformation->Links--;
2092 // Check if this is a directory that there are not currently other opens
2095 if( pFcb->ObjectInformation->Specific.Directory.ChildOpenHandleCount > 0)
2098 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2099 AFS_TRACE_LEVEL_ERROR,
2100 "AFSSetDispositionInfo Attempt to delete directory %wZ with open %u handles\n",
2101 &DirectoryCB->NameInformation.FileName,
2102 pFcb->ObjectInformation->Specific.Directory.ChildOpenHandleCount);
2104 try_return( ntStatus = STATUS_DIRECTORY_NOT_EMPTY);
2107 if( !AFSIsDirectoryEmptyForDelete( pFcb))
2110 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2111 AFS_TRACE_LEVEL_ERROR,
2112 "AFSSetDispositionInfo Attempt to delete non-empty directory %wZ\n",
2113 &DirectoryCB->NameInformation.FileName);
2115 try_return( ntStatus = STATUS_DIRECTORY_NOT_EMPTY);
2118 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2119 AFS_TRACE_LEVEL_VERBOSE,
2120 "AFSSetDispositionInfo Setting PENDING_DELETE on DirEntry %p Name %wZ\n",
2122 &DirectoryCB->NameInformation.FileName);
2124 SetFlag( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
2126 else if( pFcb->Header.NodeTypeCode == AFS_FILE_FCB)
2130 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2131 AFS_TRACE_LEVEL_VERBOSE,
2132 "AFSSetDispositionInfo Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
2133 &pFcb->NPFcb->SectionObjectResource,
2134 PsGetCurrentThread());
2136 AFSAcquireExcl( &pFcb->NPFcb->SectionObjectResource,
2140 // Attempt to flush any outstanding data
2143 bMmFlushed = MmFlushImageSection( &pFcb->NPFcb->SectionObjectPointers,
2150 // Set PENDING_DELETE before CcPurgeCacheSection to avoid a
2151 // deadlock with Trend Micro's Enterprise anti-virus product
2152 // which attempts to open the file which is being deleted.
2155 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2156 AFS_TRACE_LEVEL_VERBOSE,
2157 "AFSSetDispositionInfo Setting PENDING_DELETE on DirEntry %p Name %wZ\n",
2159 &DirectoryCB->NameInformation.FileName);
2161 SetFlag( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
2164 // Purge the cache as well
2167 if( pFcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
2170 if ( !CcPurgeCacheSection( &pFcb->NPFcb->SectionObjectPointers,
2176 SetFlag( pFcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
2181 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2182 AFS_TRACE_LEVEL_VERBOSE,
2183 "AFSSetDispositionInfo Releasing Fcb SectionObject lock %p EXCL %08lX\n",
2184 &pFcb->NPFcb->SectionObjectResource,
2185 PsGetCurrentThread());
2187 AFSReleaseResource( &pFcb->NPFcb->SectionObjectResource);
2192 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2193 AFS_TRACE_LEVEL_ERROR,
2194 "AFSSetDispositionInfo Failed to flush image section for delete Entry %wZ\n",
2195 &DirectoryCB->NameInformation.FileName);
2197 try_return( ntStatus = STATUS_CANNOT_DELETE);
2204 ClearFlag( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
2208 // OK, should be good to go, set the flag in the file object
2211 pIrpSp->FileObject->DeletePending = pBuffer->DeleteFile;
2222 AFSSetFileLinkInfo( IN PIRP Irp)
2225 NTSTATUS ntStatus = STATUS_SUCCESS;
2226 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
2227 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2228 PFILE_LINK_INFORMATION pFileLinkInfo = NULL;
2229 PFILE_OBJECT pSrcFileObj = NULL;
2230 PFILE_OBJECT pTargetFileObj = pIrpSp->Parameters.SetFile.FileObject;
2231 AFSFcb *pSrcFcb = NULL, *pTargetDcb = NULL;
2232 AFSCcb *pSrcCcb = NULL, *pTargetDirCcb = NULL;
2233 AFSObjectInfoCB *pSrcObject = NULL;
2234 AFSObjectInfoCB *pSrcParentObject = NULL, *pTargetParentObject = NULL;
2235 UNICODE_STRING uniSourceName, uniTargetName;
2236 UNICODE_STRING uniFullTargetName, uniTargetParentName;
2237 BOOLEAN bCommonParent = FALSE;
2238 AFSDirectoryCB *pTargetDirEntry = NULL;
2239 AFSDirectoryCB *pNewTargetDirEntry = NULL;
2241 BOOLEAN bTargetEntryExists = FALSE;
2243 BOOLEAN bReleaseTargetDirLock = FALSE;
2244 ULONG ulNotificationAction = 0, ulNotifyFilter = 0;
2249 pSrcFileObj = pIrpSp->FileObject;
2251 pSrcFcb = (AFSFcb *)pSrcFileObj->FsContext;
2252 pSrcCcb = (AFSCcb *)pSrcFileObj->FsContext2;
2254 pSrcObject = pSrcFcb->ObjectInformation;
2256 if ( BooleanFlagOn( pSrcFcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
2259 pSrcParentObject = AFSFindObjectInfo( pSrcFcb->ObjectInformation->VolumeCB,
2260 &pSrcFcb->ObjectInformation->ParentFileId);
2263 pFileLinkInfo = (PFILE_LINK_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
2266 // Perform some basic checks to ensure FS integrity
2269 if( pSrcFcb->Header.NodeTypeCode != AFS_FILE_FCB)
2272 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2273 AFS_TRACE_LEVEL_ERROR,
2274 "AFSSetFileLinkInfo Attempt to non-file (INVALID_PARAMETER)\n");
2276 try_return( ntStatus = STATUS_INVALID_PARAMETER);
2279 if( pTargetFileObj == NULL)
2282 if ( pFileLinkInfo->RootDirectory)
2286 // The target directory is provided by HANDLE
2287 // RootDirectory is only set when the target directory is not the same
2288 // as the source directory.
2290 // AFS only supports hard links within a single directory.
2292 // The IOManager should translate any Handle to a FileObject for us.
2293 // However, the failure to receive a FileObject is treated as a fatal
2297 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2298 AFS_TRACE_LEVEL_ERROR,
2299 "AFSSetFileLinkInfo Attempt to link %wZ to alternate directory by handle INVALID_PARAMETER\n",
2300 &pSrcCcb->DirectoryCB->NameInformation.FileName);
2302 try_return( ntStatus = STATUS_INVALID_PARAMETER);
2307 uniFullTargetName.Length = (USHORT)pFileLinkInfo->FileNameLength;
2309 uniFullTargetName.Buffer = (PWSTR)&pFileLinkInfo->FileName;
2311 AFSRetrieveFinalComponent( &uniFullTargetName,
2314 AFSRetrieveParentPath( &uniFullTargetName,
2315 &uniTargetParentName);
2317 if ( uniTargetParentName.Length == 0)
2321 // This is a simple rename. Here the target directory is the same as the source parent directory
2322 // and the name is retrieved from the system buffer information
2325 pTargetParentObject = pSrcParentObject;
2330 // uniTargetParentName contains the directory the renamed object
2331 // will be moved to. Must obtain the TargetParentObject.
2334 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2335 AFS_TRACE_LEVEL_ERROR,
2336 "AFSSetFileLinkInfo Attempt to link %wZ to alternate directory %wZ (NOT_SAME_DEVICE)\n",
2337 &pSrcCcb->DirectoryCB->NameInformation.FileName,
2338 &uniFullTargetName);
2340 try_return( ntStatus = STATUS_NOT_SAME_DEVICE);
2344 pTargetDcb = pTargetParentObject->Fcb;
2350 // So here we have the target directory taken from the targetfile object
2353 pTargetDcb = (AFSFcb *)pTargetFileObj->FsContext;
2355 pTargetDirCcb = (AFSCcb *)pTargetFileObj->FsContext2;
2357 pTargetParentObject = (AFSObjectInfoCB *)pTargetDcb->ObjectInformation;
2360 // Grab the target name which we setup in the IRP_MJ_CREATE handler. By how we set this up
2361 // it is only the target component of the rename operation
2364 uniTargetName = *((PUNICODE_STRING)&pTargetFileObj->FileName);
2368 // The quick check to see if they are self linking.
2369 // Do the names match? Only do this where the parent directories are
2373 if( pTargetParentObject == pSrcParentObject)
2376 if( FsRtlAreNamesEqual( &uniTargetName,
2381 try_return( ntStatus = STATUS_SUCCESS);
2384 bCommonParent = TRUE;
2390 // We do not allow cross-volume hard links
2393 if( pTargetParentObject->VolumeCB != pSrcObject->VolumeCB)
2396 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2397 AFS_TRACE_LEVEL_ERROR,
2398 "AFSSetFileLinkInfo Attempt to link to different volume %wZ\n",
2399 &pSrcCcb->DirectoryCB->NameInformation.FileName);
2401 try_return( ntStatus = STATUS_NOT_SAME_DEVICE);
2405 ulTargetCRC = AFSGenerateCRC( &uniTargetName,
2408 AFSAcquireExcl( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock,
2411 bReleaseTargetDirLock = TRUE;
2413 AFSLocateCaseSensitiveDirEntry( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
2417 if( pTargetDirEntry == NULL)
2421 // Missed so perform a case insensitive lookup
2424 ulTargetCRC = AFSGenerateCRC( &uniTargetName,
2427 AFSLocateCaseInsensitiveDirEntry( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
2432 if ( !BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
2433 pTargetDirEntry == NULL && RtlIsNameLegalDOS8Dot3( &uniTargetName,
2438 // Try the short name
2440 AFSLocateShortNameDirEntry( pTargetParentObject->Specific.Directory.ShortNameTree,
2446 // Increment our ref count on the dir entry
2449 if( pTargetDirEntry != NULL)
2452 ASSERT( BooleanFlagOn( pTargetDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_PARENT_FID) &&
2453 AFSIsEqualFID( &pTargetParentObject->FileId, &pTargetDirEntry->ObjectInformation->ParentFileId));
2455 lCount = InterlockedIncrement( &pTargetDirEntry->DirOpenReferenceCount);
2457 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2458 AFS_TRACE_LEVEL_VERBOSE,
2459 "AFSSetFileLinkInfo Increment count on %wZ DE %p Ccb %p Cnt %d\n",
2460 &pTargetDirEntry->NameInformation.FileName,
2465 ASSERT( lCount >= 0);
2467 if( !pFileLinkInfo->ReplaceIfExists)
2470 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2471 AFS_TRACE_LEVEL_ERROR,
2472 "AFSSetFileLinkInfo Attempt to link with target collision %wZ Target %wZ\n",
2473 &pSrcCcb->DirectoryCB->NameInformation.FileName,
2474 &pTargetDirEntry->NameInformation.FileName);
2476 try_return( ntStatus = STATUS_OBJECT_NAME_COLLISION);
2479 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING | AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2480 AFS_TRACE_LEVEL_ERROR,
2481 "AFSSetFileLinkInfo Target %wZ exists DE %p Count %d, performing delete of target\n",
2482 &pTargetDirEntry->NameInformation.FileName,
2487 // Pull the directory entry from the parent
2490 AFSRemoveDirNodeFromParent( pTargetParentObject,
2494 bTargetEntryExists = TRUE;
2498 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2499 AFS_TRACE_LEVEL_VERBOSE,
2500 "AFSSetFileLinkInfo Target does NOT exist, normal linking\n");
2504 // OK, this is a simple rename. Issue the rename
2505 // request to the service.
2508 ntStatus = AFSNotifyHardLink( pSrcFcb->ObjectInformation,
2509 &pSrcCcb->AuthGroup,
2511 pTargetDcb->ObjectInformation,
2512 pSrcCcb->DirectoryCB,
2514 pFileLinkInfo->ReplaceIfExists,
2515 &pNewTargetDirEntry);
2517 if( ntStatus != STATUS_REPARSE &&
2518 !NT_SUCCESS( ntStatus))
2521 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2522 AFS_TRACE_LEVEL_ERROR,
2523 "AFSSetFileLinkInfo Failed link of %wZ to target %wZ Status %08lX\n",
2524 &pSrcCcb->DirectoryCB->NameInformation.FileName,
2528 try_return( ntStatus);
2531 if ( ntStatus != STATUS_REPARSE)
2534 AFSInsertDirectoryNode( pTargetDcb->ObjectInformation,
2540 // Send notification for the target link file
2543 if( bTargetEntryExists || pNewTargetDirEntry)
2546 ulNotificationAction = FILE_ACTION_MODIFIED;
2551 ulNotificationAction = FILE_ACTION_ADDED;
2554 AFSFsRtlNotifyFullReportChange( pTargetParentObject,
2556 (ULONG)ulNotifyFilter,
2557 (ULONG)ulNotificationAction);
2561 if( !NT_SUCCESS( ntStatus))
2564 if( bTargetEntryExists)
2567 AFSInsertDirectoryNode( pTargetParentObject,
2573 if( pTargetDirEntry != NULL)
2577 // Release DirOpenReferenceCount obtained above
2580 lCount = InterlockedDecrement( &pTargetDirEntry->DirOpenReferenceCount);
2582 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2583 AFS_TRACE_LEVEL_VERBOSE,
2584 "AFSSetFileLinkInfo Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
2585 &pTargetDirEntry->NameInformation.FileName,
2590 ASSERT( lCount >= 0);
2593 if( pNewTargetDirEntry != NULL)
2597 // Release DirOpenReferenceCount obtained from AFSNotifyHardLink
2600 lCount = InterlockedDecrement( &pNewTargetDirEntry->DirOpenReferenceCount);
2602 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2603 AFS_TRACE_LEVEL_VERBOSE,
2604 "AFSSetFileLinkInfo Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
2605 &pNewTargetDirEntry->NameInformation.FileName,
2610 ASSERT( lCount >= 0);
2613 if( bReleaseTargetDirLock)
2616 AFSReleaseResource( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
2619 if ( pSrcParentObject != NULL)
2622 AFSReleaseObjectInfo( &pSrcParentObject);
2626 // No need to release pTargetParentObject as it is either a copy of pSrcParentObject
2627 // or (AFSFcb *)pTargetFileObj->FsContext->ObjectInformation
2630 pTargetParentObject = NULL;
2637 AFSSetRenameInfo( IN PIRP Irp)
2640 NTSTATUS ntStatus = STATUS_SUCCESS;
2641 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
2642 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2643 AFSFcb *pSrcFcb = NULL, *pTargetDcb = NULL, *pTargetFcb = NULL;
2644 AFSCcb *pSrcCcb = NULL, *pTargetDirCcb = NULL;
2645 PFILE_OBJECT pSrcFileObj = pIrpSp->FileObject;
2646 PFILE_OBJECT pTargetFileObj = pIrpSp->Parameters.SetFile.FileObject;
2647 PFILE_OBJECT pTargetParentFileObj = NULL;
2648 PFILE_RENAME_INFORMATION pRenameInfo = NULL;
2649 UNICODE_STRING uniTargetName, uniSourceName, uniTargetParentName;
2650 BOOLEAN bReplaceIfExists = FALSE;
2651 UNICODE_STRING uniShortName;
2652 AFSDirectoryCB *pTargetDirEntry = NULL;
2653 ULONG ulTargetCRC = 0;
2654 BOOLEAN bTargetEntryExists = FALSE;
2655 AFSObjectInfoCB *pSrcObject = NULL;
2656 AFSObjectInfoCB *pSrcParentObject = NULL, *pTargetParentObject = NULL;
2658 ULONG ulNotificationAction = 0, ulNotifyFilter = 0;
2659 UNICODE_STRING uniFullTargetName;
2660 BOOLEAN bCommonParent = FALSE;
2661 BOOLEAN bReleaseTargetDirLock = FALSE;
2662 BOOLEAN bReleaseSourceDirLock = FALSE;
2663 BOOLEAN bDereferenceTargetParentObject = FALSE;
2664 PERESOURCE pSourceDirLock = NULL;
2670 bReplaceIfExists = pIrpSp->Parameters.SetFile.ReplaceIfExists;
2672 pRenameInfo = (PFILE_RENAME_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
2674 pSrcFcb = (AFSFcb *)pSrcFileObj->FsContext;
2675 pSrcCcb = (AFSCcb *)pSrcFileObj->FsContext2;
2677 pSrcObject = pSrcFcb->ObjectInformation;
2679 if ( BooleanFlagOn( pSrcFcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
2682 pSrcParentObject = AFSFindObjectInfo( pSrcFcb->ObjectInformation->VolumeCB,
2683 &pSrcFcb->ObjectInformation->ParentFileId);
2687 // Perform some basic checks to ensure FS integrity
2690 if( pSrcFcb->Header.NodeTypeCode == AFS_ROOT_FCB)
2694 // Can't rename the root directory
2697 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2698 AFS_TRACE_LEVEL_ERROR,
2699 "AFSSetRenameInfo Attempt to rename root entry\n");
2701 try_return( ntStatus = STATUS_INVALID_PARAMETER);
2704 if( pSrcFcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB)
2708 // If there are any open children then fail the rename
2711 if( pSrcFcb->ObjectInformation->Specific.Directory.ChildOpenHandleCount > 0)
2714 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2715 AFS_TRACE_LEVEL_ERROR,
2716 "AFSSetRenameInfo Attempt to rename directory with open children %wZ\n",
2717 &pSrcCcb->DirectoryCB->NameInformation.FileName);
2719 try_return( ntStatus = STATUS_ACCESS_DENIED);
2725 // Extract off the final component name from the Fcb
2728 uniSourceName.Length = (USHORT)pSrcCcb->DirectoryCB->NameInformation.FileName.Length;
2729 uniSourceName.MaximumLength = uniSourceName.Length;
2731 uniSourceName.Buffer = pSrcCcb->DirectoryCB->NameInformation.FileName.Buffer;
2734 // Resolve the target fileobject
2737 if( pTargetFileObj == NULL)
2740 if ( pRenameInfo->RootDirectory)
2743 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2744 AFS_TRACE_LEVEL_ERROR,
2745 "AFSSetRenameInfo Handle provided but no FileObject ntStatus INVALID_PARAMETER\n");
2747 try_return( ntStatus = STATUS_INVALID_PARAMETER);
2752 uniFullTargetName.Length = (USHORT)pRenameInfo->FileNameLength;
2754 uniFullTargetName.Buffer = (PWSTR)&pRenameInfo->FileName;
2756 AFSRetrieveFinalComponent( &uniFullTargetName,
2759 AFSRetrieveParentPath( &uniFullTargetName,
2760 &uniTargetParentName);
2762 if ( uniTargetParentName.Length == 0)
2766 // This is a simple rename. Here the target directory is the same as the source parent directory
2767 // and the name is retrieved from the system buffer information
2770 pTargetParentObject = pSrcParentObject;
2775 // uniTargetParentName contains the directory the renamed object
2776 // will be moved to. Must obtain the TargetParentObject.
2779 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2780 AFS_TRACE_LEVEL_ERROR,
2781 "AFSSetRenameInfo Attempt to move %wZ to %wZ -- not yet supported (NOT_SAME_DEVICE)\n",
2782 &pSrcCcb->DirectoryCB->NameInformation.FileName,
2783 &uniFullTargetName);
2785 try_return( ntStatus = STATUS_NOT_SAME_DEVICE);
2789 pTargetDcb = pTargetParentObject->Fcb;
2795 // So here we have the target directory taken from the targetfile object
2798 pTargetDcb = (AFSFcb *)pTargetFileObj->FsContext;
2800 pTargetDirCcb = (AFSCcb *)pTargetFileObj->FsContext2;
2802 pTargetParentObject = (AFSObjectInfoCB *)pTargetDcb->ObjectInformation;
2805 // Grab the target name which we setup in the IRP_MJ_CREATE handler. By how we set this up
2806 // it is only the target component of the rename operation
2809 uniTargetName = *((PUNICODE_STRING)&pTargetFileObj->FileName);
2813 // The quick check to see if they are not really performing a rename
2814 // Do the names match? Only do this where the parent directories are
2818 if( pTargetParentObject == pSrcParentObject)
2821 if( FsRtlAreNamesEqual( &uniTargetName,
2826 try_return( ntStatus = STATUS_SUCCESS);
2829 bCommonParent = TRUE;
2834 bCommonParent = FALSE;
2838 // We do not allow cross-volume renames to occur
2841 if( pTargetParentObject->VolumeCB != pSrcObject->VolumeCB)
2844 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2845 AFS_TRACE_LEVEL_ERROR,
2846 "AFSSetRenameInfo Attempt to rename directory to different volume %wZ\n",
2847 &pSrcCcb->DirectoryCB->NameInformation.FileName);
2849 try_return( ntStatus = STATUS_NOT_SAME_DEVICE);
2852 ulTargetCRC = AFSGenerateCRC( &uniTargetName,
2855 AFSAcquireExcl( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock,
2858 bReleaseTargetDirLock = TRUE;
2860 if( pTargetParentObject != pSrcParentObject)
2862 AFSAcquireExcl( pSrcParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock,
2865 bReleaseSourceDirLock = TRUE;
2867 pSourceDirLock = pSrcParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock;
2870 AFSLocateCaseSensitiveDirEntry( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
2874 if( pTargetDirEntry == NULL)
2878 // Missed so perform a case insensitive lookup
2881 ulTargetCRC = AFSGenerateCRC( &uniTargetName,
2884 AFSLocateCaseInsensitiveDirEntry( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
2889 if ( !BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
2890 pTargetDirEntry == NULL && RtlIsNameLegalDOS8Dot3( &uniTargetName,
2895 // Try the short name
2897 AFSLocateShortNameDirEntry( pTargetParentObject->Specific.Directory.ShortNameTree,
2903 // Increment our ref count on the dir entry
2906 if( pTargetDirEntry != NULL)
2909 ASSERT( BooleanFlagOn( pTargetDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_PARENT_FID) &&
2910 AFSIsEqualFID( &pTargetParentObject->FileId, &pTargetDirEntry->ObjectInformation->ParentFileId));
2912 lCount = InterlockedIncrement( &pTargetDirEntry->DirOpenReferenceCount);
2914 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2915 AFS_TRACE_LEVEL_VERBOSE,
2916 "AFSSetRenameInfo Increment count on %wZ DE %p Ccb %p Cnt %d\n",
2917 &pTargetDirEntry->NameInformation.FileName,
2922 ASSERT( lCount >= 0);
2924 if( !bReplaceIfExists)
2927 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2928 AFS_TRACE_LEVEL_ERROR,
2929 "AFSSetRenameInfo Attempt to rename directory with target collision %wZ Target %wZ\n",
2930 &pSrcCcb->DirectoryCB->NameInformation.FileName,
2931 &pTargetDirEntry->NameInformation.FileName);
2933 try_return( ntStatus = STATUS_OBJECT_NAME_COLLISION);
2936 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING | AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2937 AFS_TRACE_LEVEL_ERROR,
2938 "AFSSetRenameInfo Target %wZ exists DE %p Count %d, performing delete of target\n",
2939 &pTargetDirEntry->NameInformation.FileName,
2944 // Pull the directory entry from the parent
2947 AFSRemoveDirNodeFromParent( pTargetParentObject,
2951 bTargetEntryExists = TRUE;
2955 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2956 AFS_TRACE_LEVEL_VERBOSE,
2957 "AFSSetRenameInfo Target does NOT exist, normal rename\n");
2961 // We need to remove the DirEntry from the parent node, update the index
2962 // and reinsert it into the parent tree. Note that for entries with the
2963 // same parent we do not pull the node from the enumeration list
2966 AFSRemoveDirNodeFromParent( pSrcParentObject,
2967 pSrcCcb->DirectoryCB,
2971 // OK, this is a simple rename. Issue the rename
2972 // request to the service.
2975 ntStatus = AFSNotifyRename( pSrcFcb->ObjectInformation,
2976 &pSrcCcb->AuthGroup,
2978 pTargetDcb->ObjectInformation,
2979 pSrcCcb->DirectoryCB,
2983 if( !NT_SUCCESS( ntStatus))
2987 // Attempt to re-insert the directory entry
2990 AFSInsertDirectoryNode( pSrcParentObject,
2991 pSrcCcb->DirectoryCB,
2994 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2995 AFS_TRACE_LEVEL_ERROR,
2996 "AFSSetRenameInfo Failed rename of %wZ to target %wZ Status %08lX\n",
2997 &pSrcCcb->DirectoryCB->NameInformation.FileName,
3001 try_return( ntStatus);
3005 // Set the notification up for the source file
3008 if( pSrcParentObject == pTargetParentObject &&
3009 !bTargetEntryExists)
3012 ulNotificationAction = FILE_ACTION_RENAMED_OLD_NAME;
3017 ulNotificationAction = FILE_ACTION_REMOVED;
3020 if( pSrcCcb->DirectoryCB->ObjectInformation->FileType == AFS_FILE_TYPE_DIRECTORY)
3023 ulNotifyFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
3028 ulNotifyFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
3031 AFSFsRtlNotifyFullReportChange( pSrcParentObject,
3033 (ULONG)ulNotifyFilter,
3034 (ULONG)ulNotificationAction);
3037 // Update the name in the dir entry.
3040 ntStatus = AFSUpdateDirEntryName( pSrcCcb->DirectoryCB,
3043 if( !NT_SUCCESS( ntStatus))
3047 // Attempt to re-insert the directory entry
3050 AFSInsertDirectoryNode( pSrcParentObject,
3051 pSrcCcb->DirectoryCB,
3054 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3055 AFS_TRACE_LEVEL_ERROR,
3056 "AFSSetRenameInfo Failed update of dir entry %wZ to target %wZ Status %08lX\n",
3057 &pSrcCcb->DirectoryCB->NameInformation.FileName,
3061 try_return( ntStatus);
3065 // Update the object information block, if needed
3068 if( !AFSIsEqualFID( &pSrcObject->FileId,
3072 AFSAcquireExcl( pSrcObject->VolumeCB->ObjectInfoTree.TreeLock,
3076 // Remove the old information entry
3079 AFSRemoveHashEntry( &pSrcObject->VolumeCB->ObjectInfoTree.TreeHead,
3080 &pSrcObject->TreeEntry);
3082 RtlCopyMemory( &pSrcObject->FileId,
3084 sizeof( AFSFileID));
3087 // Insert the entry into the new object table.
3090 pSrcObject->TreeEntry.HashIndex = AFSCreateLowIndex( &pSrcObject->FileId);
3092 if( pSrcObject->VolumeCB->ObjectInfoTree.TreeHead == NULL)
3095 pSrcObject->VolumeCB->ObjectInfoTree.TreeHead = &pSrcObject->TreeEntry;
3100 if ( !NT_SUCCESS( AFSInsertHashEntry( pSrcObject->VolumeCB->ObjectInfoTree.TreeHead,
3101 &pSrcObject->TreeEntry)))
3105 // Lost a race, an ObjectInfo object already exists for this FID.
3106 // Let this copy be garbage collected.
3109 ClearFlag( pSrcObject->Flags, AFS_OBJECT_INSERTED_HASH_TREE);
3113 AFSReleaseResource( pSrcObject->VolumeCB->ObjectInfoTree.TreeLock);
3117 // Update the hash values for the name trees.
3120 pSrcCcb->DirectoryCB->CaseSensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pSrcCcb->DirectoryCB->NameInformation.FileName,
3123 pSrcCcb->DirectoryCB->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pSrcCcb->DirectoryCB->NameInformation.FileName,
3126 if( !BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
3127 pSrcCcb->DirectoryCB->NameInformation.ShortNameLength > 0 &&
3128 !RtlIsNameLegalDOS8Dot3( &pSrcCcb->DirectoryCB->NameInformation.FileName,
3133 uniShortName.Length = pSrcCcb->DirectoryCB->NameInformation.ShortNameLength;
3134 uniShortName.MaximumLength = uniShortName.Length;
3135 uniShortName.Buffer = pSrcCcb->DirectoryCB->NameInformation.ShortName;
3137 pSrcCcb->DirectoryCB->Type.Data.ShortNameTreeEntry.HashIndex = AFSGenerateCRC( &uniShortName,
3140 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3141 AFS_TRACE_LEVEL_VERBOSE,
3142 "AFSSetRenameInfo Initialized short name hash for %wZ longname %wZ\n",
3144 &pSrcCcb->DirectoryCB->NameInformation.FileName);
3149 pSrcCcb->DirectoryCB->Type.Data.ShortNameTreeEntry.HashIndex = 0;
3156 // Update the file index for the object in the new parent
3159 pSrcCcb->DirectoryCB->FileIndex = (ULONG)InterlockedIncrement( &pTargetParentObject->Specific.Directory.DirectoryNodeHdr.ContentIndex);
3163 // Re-insert the directory entry
3166 AFSInsertDirectoryNode( pTargetParentObject,
3167 pSrcCcb->DirectoryCB,
3171 // Update the parent pointer in the source object if they are different
3174 if( pSrcParentObject != pTargetParentObject)
3177 lCount = InterlockedDecrement( &pSrcParentObject->Specific.Directory.ChildOpenHandleCount);
3179 lCount = InterlockedDecrement( &pSrcParentObject->Specific.Directory.ChildOpenReferenceCount);
3181 lCount = InterlockedIncrement( &pTargetParentObject->Specific.Directory.ChildOpenHandleCount);
3183 lCount = InterlockedIncrement( &pTargetParentObject->Specific.Directory.ChildOpenReferenceCount);
3185 lCount = AFSObjectInfoIncrement( pTargetParentObject,
3186 AFS_OBJECT_REFERENCE_CHILD);
3188 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
3189 AFS_TRACE_LEVEL_VERBOSE,
3190 "AFSSetRenameInfo Increment count on parent object %p Cnt %d\n",
3191 pTargetParentObject,
3194 lCount = AFSObjectInfoDecrement( pSrcParentObject,
3195 AFS_OBJECT_REFERENCE_CHILD);
3197 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
3198 AFS_TRACE_LEVEL_VERBOSE,
3199 "AFSSetRenameInfo Decrement count on parent object %p Cnt %d\n",
3203 pSrcCcb->DirectoryCB->ObjectInformation->ParentFileId = pTargetParentObject->FileId;
3205 SetFlag( pSrcCcb->DirectoryCB->ObjectInformation->Flags, AFS_OBJECT_FLAGS_PARENT_FID);
3207 pSrcParentObject = pTargetParentObject;
3209 ulNotificationAction = FILE_ACTION_ADDED;
3214 ulNotificationAction = FILE_ACTION_RENAMED_NEW_NAME;
3218 // Now update the notification for the target file
3221 AFSFsRtlNotifyFullReportChange( pTargetParentObject,
3223 (ULONG)ulNotifyFilter,
3224 (ULONG)ulNotificationAction);
3227 // If we performed the rename of the target because it existed, we now need to
3228 // delete the tmp target we created above
3231 if( bTargetEntryExists)
3234 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3235 AFS_TRACE_LEVEL_VERBOSE,
3236 "AFSSetRenameInfo Setting DELETE flag in dir entry %p name %wZ\n",
3238 &pTargetDirEntry->NameInformation.FileName);
3240 SetFlag( pTargetDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
3243 // Try and purge the cache map if this is a file
3246 if( pTargetDirEntry->ObjectInformation->FileType == AFS_FILE_TYPE_FILE &&
3247 pTargetDirEntry->ObjectInformation->Fcb != NULL &&
3248 pTargetDirEntry->DirOpenReferenceCount > 1)
3251 pTargetFcb = pTargetDirEntry->ObjectInformation->Fcb;
3254 ASSERT( pTargetDirEntry->DirOpenReferenceCount > 0);
3256 lCount = InterlockedDecrement( &pTargetDirEntry->DirOpenReferenceCount); // The count we added above
3258 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3259 AFS_TRACE_LEVEL_VERBOSE,
3260 "AFSSetRenameInfo Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
3261 &pTargetDirEntry->NameInformation.FileName,
3266 ASSERT( lCount >= 0);
3271 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3272 AFS_TRACE_LEVEL_VERBOSE,
3273 "AFSSetRenameInfo Deleting dir entry %p name %wZ\n",
3275 &pTargetDirEntry->NameInformation.FileName);
3277 AFSDeleteDirEntry( pTargetParentObject,
3281 pTargetDirEntry = NULL;
3283 if ( pTargetFcb != NULL)
3287 // Do not hold TreeLocks across the MmForceSectionClosed() call as
3288 // it can deadlock with Trend Micro's TmPreFlt!TmpQueryFullName
3291 if( bReleaseTargetDirLock)
3293 AFSReleaseResource( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
3295 bReleaseTargetDirLock = FALSE;
3298 if( bReleaseSourceDirLock)
3301 AFSReleaseResource( pSourceDirLock);
3303 bReleaseSourceDirLock = FALSE;
3307 // MmForceSectionClosed() can eventually call back into AFSCleanup
3308 // which will need to acquire Fcb->Resource exclusively. Failure
3309 // to obtain it here before holding the SectionObjectResource will
3310 // permit the locks to be obtained out of order risking a deadlock.
3313 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3314 AFS_TRACE_LEVEL_VERBOSE,
3315 "AFSSetRenameInfo Acquiring Fcb lock %p EXCL %08lX\n",
3316 &pTargetFcb->NPFcb->Resource,
3317 PsGetCurrentThread());
3319 AFSAcquireExcl( &pTargetFcb->NPFcb->Resource,
3322 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3323 AFS_TRACE_LEVEL_VERBOSE,
3324 "AFSSetRenameInfo Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
3325 &pTargetFcb->NPFcb->SectionObjectResource,
3326 PsGetCurrentThread());
3328 AFSAcquireExcl( &pTargetFcb->NPFcb->SectionObjectResource,
3332 // Close the section in the event it was mapped
3335 if( !MmForceSectionClosed( &pTargetFcb->NPFcb->SectionObjectPointers,
3339 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3340 AFS_TRACE_LEVEL_ERROR,
3341 "AFSSetRenameInfo Failed to delete section for target file %wZ\n",
3345 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3346 AFS_TRACE_LEVEL_VERBOSE,
3347 "AFSSetRenameInfo Releasing Fcb SectionObject lock %p EXCL %08lX\n",
3348 &pTargetFcb->NPFcb->SectionObjectResource,
3349 PsGetCurrentThread());
3351 AFSReleaseResource( &pTargetFcb->NPFcb->SectionObjectResource);
3353 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3354 AFS_TRACE_LEVEL_VERBOSE,
3355 "AFSSetRenameInfo Releasing Fcb lock %p EXCL %08lX\n",
3356 &pTargetFcb->NPFcb->Resource,
3357 PsGetCurrentThread());
3359 AFSReleaseResource( &pTargetFcb->NPFcb->Resource);
3365 if( !NT_SUCCESS( ntStatus))
3368 if( bTargetEntryExists)
3371 ASSERT( pTargetParentObject != NULL);
3373 AFSInsertDirectoryNode( pTargetParentObject,
3379 if( pTargetDirEntry != NULL)
3382 lCount = InterlockedDecrement( &pTargetDirEntry->DirOpenReferenceCount);
3384 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3385 AFS_TRACE_LEVEL_VERBOSE,
3386 "AFSSetRenameInfo Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
3387 &pTargetDirEntry->NameInformation.FileName,
3392 ASSERT( lCount >= 0);
3395 if( bReleaseTargetDirLock)
3398 AFSReleaseResource( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
3401 if( bReleaseSourceDirLock)
3404 AFSReleaseResource( pSourceDirLock);
3407 if ( bDereferenceTargetParentObject)
3410 ObDereferenceObject( pTargetParentFileObj);
3413 if ( pSrcParentObject != NULL)
3416 AFSReleaseObjectInfo( &pSrcParentObject);
3420 // No need to release pTargetParentObject as it is either a copy of pSrcParentObject
3421 // or (AFSFcb *)pTargetFileObj->FsContext->ObjectInformation
3424 pTargetParentObject = NULL;
3431 AFSSetPositionInfo( IN PIRP Irp,
3432 IN AFSDirectoryCB *DirectoryCB)
3434 UNREFERENCED_PARAMETER(DirectoryCB);
3435 NTSTATUS ntStatus = STATUS_SUCCESS;
3436 PFILE_POSITION_INFORMATION pBuffer;
3437 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
3439 pBuffer = (PFILE_POSITION_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
3441 pIrpSp->FileObject->CurrentByteOffset.QuadPart = pBuffer->CurrentByteOffset.QuadPart;
3447 AFSSetAllocationInfo( IN PIRP Irp,
3448 IN AFSDirectoryCB *DirectoryCB)
3450 UNREFERENCED_PARAMETER(DirectoryCB);
3451 NTSTATUS ntStatus = STATUS_SUCCESS;
3452 PFILE_ALLOCATION_INFORMATION pBuffer;
3453 BOOLEAN bReleasePaging = FALSE;
3454 BOOLEAN bTellCc = FALSE;
3455 BOOLEAN bTellService = FALSE;
3456 BOOLEAN bUserMapped = FALSE;
3457 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
3458 PFILE_OBJECT pFileObject = pIrpSp->FileObject;
3459 AFSFcb *pFcb = NULL;
3460 AFSCcb *pCcb = NULL;
3461 LARGE_INTEGER liSaveAlloc;
3462 LARGE_INTEGER liSaveFileSize;
3463 LARGE_INTEGER liSaveVDL;
3465 pBuffer = (PFILE_ALLOCATION_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
3467 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
3469 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
3472 // save values to put back
3474 liSaveAlloc = pFcb->Header.AllocationSize;
3475 liSaveFileSize = pFcb->Header.FileSize;
3476 liSaveVDL = pFcb->Header.ValidDataLength;
3478 if( pFcb->Header.AllocationSize.QuadPart == pBuffer->AllocationSize.QuadPart ||
3479 pIrpSp->Parameters.SetFile.AdvanceOnly)
3481 return STATUS_SUCCESS ;
3484 if( pFcb->Header.AllocationSize.QuadPart > pBuffer->AllocationSize.QuadPart)
3487 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3488 AFS_TRACE_LEVEL_VERBOSE,
3489 "AFSSetAllocationInfo Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
3490 &pFcb->NPFcb->SectionObjectResource,
3491 PsGetCurrentThread());
3493 AFSAcquireExcl( &pFcb->NPFcb->SectionObjectResource,
3496 bUserMapped = !MmCanFileBeTruncated( pFileObject->SectionObjectPointer,
3497 &pBuffer->AllocationSize);
3499 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3500 AFS_TRACE_LEVEL_VERBOSE,
3501 "AFSSetAllocationInfo Releasing Fcb SectionObject lock %p EXCL %08lX\n",
3502 &pFcb->NPFcb->SectionObjectResource,
3503 PsGetCurrentThread());
3505 AFSReleaseResource( &pFcb->NPFcb->SectionObjectResource);
3508 // Truncating the file
3513 ntStatus = STATUS_USER_MAPPED_FILE ;
3519 // If this is a truncation we need to grab the paging IO resource.
3522 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3523 AFS_TRACE_LEVEL_VERBOSE,
3524 "AFSSetAllocationInfo Acquiring Fcb PagingIo lock %p EXCL %08lX\n",
3525 &pFcb->NPFcb->PagingResource,
3526 PsGetCurrentThread());
3528 AFSAcquireExcl( &pFcb->NPFcb->PagingResource,
3531 bReleasePaging = TRUE;
3534 // Must drop the Fcb Resource. When changing the file size
3535 // a deadlock can occur with Trend Micro's filter if the file
3536 // size is set to zero.
3539 AFSReleaseResource( &pFcb->NPFcb->Resource);
3541 pFcb->Header.AllocationSize = pBuffer->AllocationSize;
3543 pFcb->ObjectInformation->AllocationSize = pBuffer->AllocationSize;
3546 // Tell Cc that Allocation is moved.
3550 if( pFcb->Header.FileSize.QuadPart > pBuffer->AllocationSize.QuadPart)
3553 // We are pulling the EOF back as well so we need to tell
3556 bTellService = TRUE;
3558 pFcb->Header.FileSize = pBuffer->AllocationSize;
3560 pFcb->ObjectInformation->EndOfFile = pBuffer->AllocationSize;
3568 // Tell Cc if allocation is increased.
3571 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3572 AFS_TRACE_LEVEL_VERBOSE,
3573 "AFSSetAllocationInfo Acquiring Fcb PagingIo lock %p EXCL %08lX\n",
3574 &pFcb->NPFcb->PagingResource,
3575 PsGetCurrentThread());
3577 AFSAcquireExcl( &pFcb->NPFcb->PagingResource,
3580 bReleasePaging = TRUE;
3583 // Must drop the Fcb Resource. When changing the file size
3584 // a deadlock can occur with Trend Micro's filter if the file
3585 // size is set to zero.
3588 AFSReleaseResource( &pFcb->NPFcb->Resource);
3590 bTellCc = pBuffer->AllocationSize.QuadPart > pFcb->Header.AllocationSize.QuadPart;
3592 pFcb->Header.AllocationSize = pBuffer->AllocationSize;
3594 pFcb->ObjectInformation->AllocationSize = pBuffer->AllocationSize;
3598 // Now Tell the server if we have to
3603 ASSERT( BooleanFlagOn( pFcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_PARENT_FID));
3605 ntStatus = AFSUpdateFileInformation( &pFcb->ObjectInformation->ParentFileId,
3606 pFcb->ObjectInformation,
3610 if (NT_SUCCESS(ntStatus))
3613 // Trim extents if we told the service - the update has done an implicit
3614 // trim at the service.
3618 AFSTrimExtents( pFcb,
3619 &pFcb->Header.FileSize);
3622 KeQuerySystemTime( &pFcb->ObjectInformation->ChangeTime);
3624 SetFlag( pFcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_CHANGE_TIME);
3627 CcIsFileCached( pFileObject))
3629 CcSetFileSizes( pFileObject,
3630 (PCC_FILE_SIZES)&pFcb->Header.AllocationSize);
3636 // Put the saved values back
3638 pFcb->Header.ValidDataLength = liSaveVDL;
3639 pFcb->Header.FileSize = liSaveFileSize;
3640 pFcb->Header.AllocationSize = liSaveAlloc;
3641 pFcb->ObjectInformation->EndOfFile = liSaveFileSize;
3642 pFcb->ObjectInformation->AllocationSize = liSaveAlloc;
3648 AFSReleaseResource( &pFcb->NPFcb->PagingResource);
3650 AFSAcquireExcl( &pFcb->NPFcb->Resource,
3658 AFSSetEndOfFileInfo( IN PIRP Irp,
3659 IN AFSDirectoryCB *DirectoryCB)
3661 UNREFERENCED_PARAMETER(DirectoryCB);
3662 NTSTATUS ntStatus = STATUS_SUCCESS;
3663 PFILE_END_OF_FILE_INFORMATION pBuffer;
3664 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
3665 PFILE_OBJECT pFileObject = pIrpSp->FileObject;
3666 LARGE_INTEGER liSaveSize;
3667 LARGE_INTEGER liSaveVDL;
3668 LARGE_INTEGER liSaveAlloc;
3669 BOOLEAN bModified = FALSE;
3670 BOOLEAN bReleasePaging = FALSE;
3671 BOOLEAN bTruncated = FALSE;
3672 BOOLEAN bUserMapped = FALSE;
3673 AFSFcb *pFcb = NULL;
3674 AFSCcb *pCcb = NULL;
3676 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
3678 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
3680 pBuffer = (PFILE_END_OF_FILE_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
3682 liSaveSize = pFcb->Header.FileSize;
3683 liSaveAlloc = pFcb->Header.AllocationSize;
3684 liSaveVDL = pFcb->Header.ValidDataLength;
3686 if( pFcb->Header.FileSize.QuadPart != pBuffer->EndOfFile.QuadPart &&
3687 !pIrpSp->Parameters.SetFile.AdvanceOnly)
3690 if( pBuffer->EndOfFile.QuadPart < pFcb->Header.FileSize.QuadPart)
3693 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3694 AFS_TRACE_LEVEL_VERBOSE,
3695 "AFSSetEndOfFileInfo Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
3696 &pFcb->NPFcb->SectionObjectResource,
3697 PsGetCurrentThread());
3699 AFSAcquireExcl( &pFcb->NPFcb->SectionObjectResource,
3702 bUserMapped = !MmCanFileBeTruncated( pFileObject->SectionObjectPointer,
3703 &pBuffer->EndOfFile);
3705 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3706 AFS_TRACE_LEVEL_VERBOSE,
3707 "AFSSetEndOfFileInfo Releasing Fcb SectionObject lock %p EXCL %08lX\n",
3708 &pFcb->NPFcb->SectionObjectResource,
3709 PsGetCurrentThread());
3711 AFSReleaseResource( &pFcb->NPFcb->SectionObjectResource);
3713 // Truncating the file
3717 ntStatus = STATUS_USER_MAPPED_FILE;
3723 // If this is a truncation we need to grab the paging
3726 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3727 AFS_TRACE_LEVEL_VERBOSE,
3728 "AFSSetAllocationInfo Acquiring Fcb PagingIo lock %p EXCL %08lX\n",
3729 &pFcb->NPFcb->PagingResource,
3730 PsGetCurrentThread());
3732 AFSAcquireExcl( &pFcb->NPFcb->PagingResource,
3735 bReleasePaging = TRUE;
3738 // Must drop the Fcb Resource. When changing the file size
3739 // a deadlock can occur with Trend Micro's filter if the file
3740 // size is set to zero.
3743 AFSReleaseResource( &pFcb->NPFcb->Resource);
3745 pFcb->Header.AllocationSize = pBuffer->EndOfFile;
3747 pFcb->Header.FileSize = pBuffer->EndOfFile;
3749 pFcb->ObjectInformation->EndOfFile = pBuffer->EndOfFile;
3751 pFcb->ObjectInformation->AllocationSize = pBuffer->EndOfFile;
3753 if( pFcb->Header.ValidDataLength.QuadPart > pFcb->Header.FileSize.QuadPart)
3756 pFcb->Header.ValidDataLength = pFcb->Header.FileSize;
3768 // extending the file, move EOF
3772 // If this is a truncation we need to grab the paging
3775 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3776 AFS_TRACE_LEVEL_VERBOSE,
3777 "AFSSetAllocationInfo Acquiring Fcb PagingIo lock %p EXCL %08lX\n",
3778 &pFcb->NPFcb->PagingResource,
3779 PsGetCurrentThread());
3781 AFSAcquireExcl( &pFcb->NPFcb->PagingResource,
3784 bReleasePaging = TRUE;
3787 // Must drop the Fcb Resource. When changing the file size
3788 // a deadlock can occur with Trend Micro's filter if the file
3789 // size is set to zero.
3792 AFSReleaseResource( &pFcb->NPFcb->Resource);
3794 pFcb->Header.FileSize = pBuffer->EndOfFile;
3796 pFcb->ObjectInformation->EndOfFile = pBuffer->EndOfFile;
3798 if (pFcb->Header.FileSize.QuadPart > pFcb->Header.AllocationSize.QuadPart)
3801 // And Allocation as needed.
3803 pFcb->Header.AllocationSize = pBuffer->EndOfFile;
3805 pFcb->ObjectInformation->AllocationSize = pBuffer->EndOfFile;
3815 KeQuerySystemTime( &pFcb->ObjectInformation->ChangeTime);
3817 SetFlag( pFcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_CHANGE_TIME);
3823 ASSERT( BooleanFlagOn( pFcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_PARENT_FID));
3825 ntStatus = AFSUpdateFileInformation( &pFcb->ObjectInformation->ParentFileId,
3826 pFcb->ObjectInformation,
3829 if( NT_SUCCESS(ntStatus))
3832 // We are now good to go so tell CC.
3834 CcSetFileSizes( pFileObject,
3835 (PCC_FILE_SIZES)&pFcb->Header.AllocationSize);
3838 // And give up those extents
3843 AFSTrimExtents( pFcb,
3844 &pFcb->Header.FileSize);
3849 pFcb->Header.ValidDataLength = liSaveVDL;
3850 pFcb->Header.FileSize = liSaveSize;
3851 pFcb->Header.AllocationSize = liSaveAlloc;
3852 pFcb->ObjectInformation->EndOfFile = liSaveSize;
3853 pFcb->ObjectInformation->AllocationSize = liSaveAlloc;
3860 AFSReleaseResource( &pFcb->NPFcb->PagingResource);
3862 AFSAcquireExcl( &pFcb->NPFcb->Resource,
3870 AFSProcessShareSetInfo( IN IRP *Irp,
3875 UNREFERENCED_PARAMETER(Fcb);
3876 NTSTATUS ntStatus = STATUS_SUCCESS;
3877 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
3878 FILE_INFORMATION_CLASS ulFileInformationClass;
3879 void *pPipeInfo = NULL;
3883 ulFileInformationClass = pIrpSp->Parameters.SetFile.FileInformationClass;
3885 AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
3886 AFS_TRACE_LEVEL_VERBOSE,
3887 "AFSProcessShareSetInfo On pipe %wZ Class %08lX\n",
3888 &Ccb->DirectoryCB->NameInformation.FileName,
3889 ulFileInformationClass);
3891 pPipeInfo = AFSLockSystemBuffer( Irp,
3892 pIrpSp->Parameters.SetFile.Length);
3894 if( pPipeInfo == NULL)
3897 AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
3898 AFS_TRACE_LEVEL_ERROR,
3899 "AFSProcessShareSetInfo Failed to lock buffer on pipe %wZ\n",
3900 &Ccb->DirectoryCB->NameInformation.FileName);
3902 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
3906 // Send the request to the service
3909 ntStatus = AFSNotifySetPipeInfo( Ccb,
3910 (ULONG)ulFileInformationClass,
3911 pIrpSp->Parameters.SetFile.Length,
3914 if( !NT_SUCCESS( ntStatus))
3917 AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
3918 AFS_TRACE_LEVEL_ERROR,
3919 "AFSProcessShareSetInfo Failed to send request to service on pipe %wZ Status %08lX\n",
3920 &Ccb->DirectoryCB->NameInformation.FileName,
3923 try_return( ntStatus);
3926 AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
3927 AFS_TRACE_LEVEL_VERBOSE,
3928 "AFSProcessShareSetInfo Completed request on pipe %wZ Class %08lX\n",
3929 &Ccb->DirectoryCB->NameInformation.FileName,
3930 ulFileInformationClass);
3941 AFSProcessShareQueryInfo( IN IRP *Irp,
3946 UNREFERENCED_PARAMETER(Fcb);
3947 NTSTATUS ntStatus = STATUS_SUCCESS;
3948 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
3949 FILE_INFORMATION_CLASS ulFileInformationClass;
3950 void *pPipeInfo = NULL;
3955 ulFileInformationClass = pIrpSp->Parameters.QueryFile.FileInformationClass;
3957 AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
3958 AFS_TRACE_LEVEL_VERBOSE,
3959 "AFSProcessShareQueryInfo On pipe %wZ Class %08lX\n",
3960 &Ccb->DirectoryCB->NameInformation.FileName,
3961 ulFileInformationClass);
3963 pPipeInfo = AFSLockSystemBuffer( Irp,
3964 pIrpSp->Parameters.QueryFile.Length);
3966 if( pPipeInfo == NULL)
3969 AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
3970 AFS_TRACE_LEVEL_ERROR,
3971 "AFSProcessShareQueryInfo Failed to lock buffer on pipe %wZ\n",
3972 &Ccb->DirectoryCB->NameInformation.FileName);
3974 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
3978 // Send the request to the service
3981 ntStatus = AFSNotifyQueryPipeInfo( Ccb,
3982 (ULONG)ulFileInformationClass,
3983 pIrpSp->Parameters.QueryFile.Length,
3985 (ULONG *)&Irp->IoStatus.Information);
3987 if( !NT_SUCCESS( ntStatus))
3990 AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
3991 AFS_TRACE_LEVEL_ERROR,
3992 "AFSProcessShareQueryInfo Failed to send request to service on pipe %wZ Status %08lX\n",
3993 &Ccb->DirectoryCB->NameInformation.FileName,
3996 try_return( ntStatus);
3999 AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
4000 AFS_TRACE_LEVEL_VERBOSE,
4001 "AFSProcessShareQueryInfo Completed request on pipe %wZ Class %08lX\n",
4002 &Ccb->DirectoryCB->NameInformation.FileName,
4003 ulFileInformationClass);
4014 AFSProcessPIOCtlQueryInfo( IN IRP *Irp,
4017 IN OUT LONG *Length)
4020 UNREFERENCED_PARAMETER(Fcb);
4021 UNREFERENCED_PARAMETER(Ccb);
4022 NTSTATUS ntStatus = STATUS_SUCCESS;
4023 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
4024 FILE_INFORMATION_CLASS ulFileInformationClass;
4029 ulFileInformationClass = pIrpSp->Parameters.QueryFile.FileInformationClass;
4031 switch( ulFileInformationClass)
4034 case FileBasicInformation:
4037 AFSDbgLogMsg( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4038 AFS_TRACE_LEVEL_VERBOSE,
4039 "AFSProcessPIOCtlQueryInfo (FileBasicInformation)\n");
4041 if ( *Length >= sizeof( FILE_BASIC_INFORMATION))
4043 PFILE_BASIC_INFORMATION pBasic = (PFILE_BASIC_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
4045 pBasic->CreationTime.QuadPart = 0;
4046 pBasic->LastAccessTime.QuadPart = 0;
4047 pBasic->ChangeTime.QuadPart = 0;
4048 pBasic->LastWriteTime.QuadPart = 0;
4049 pBasic->FileAttributes = FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM;
4051 *Length -= sizeof( FILE_BASIC_INFORMATION);
4055 ntStatus = STATUS_BUFFER_TOO_SMALL;
4061 case FileStandardInformation:
4064 AFSDbgLogMsg( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4065 AFS_TRACE_LEVEL_VERBOSE,
4066 "AFSProcessPIOCtlQueryInfo (FileStandardInformation)\n");
4068 if ( *Length >= sizeof( FILE_STANDARD_INFORMATION))
4070 PFILE_STANDARD_INFORMATION pStandard = (PFILE_STANDARD_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
4072 pStandard->NumberOfLinks = 1;
4073 pStandard->DeletePending = 0;
4074 pStandard->AllocationSize.QuadPart = 0;
4075 pStandard->EndOfFile.QuadPart = 0;
4076 pStandard->Directory = 0;
4078 *Length -= sizeof( FILE_STANDARD_INFORMATION);
4082 ntStatus = STATUS_BUFFER_TOO_SMALL;
4088 case FileNormalizedNameInformation:
4089 case FileNameInformation:
4092 ULONG ulCopyLength = 0;
4093 AFSFcb *pFcb = NULL;
4094 AFSCcb *pCcb = NULL;
4095 USHORT usFullNameLength = 0;
4096 PFILE_NAME_INFORMATION pNameInfo = (PFILE_NAME_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
4097 UNICODE_STRING uniName;
4099 AFSDbgLogMsg( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4100 AFS_TRACE_LEVEL_VERBOSE,
4101 "AFSProcessPIOCtlQueryInfo (FileNameInformation)\n");
4103 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
4104 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
4106 if( *Length < FIELD_OFFSET( FILE_NAME_INFORMATION, FileName))
4108 ntStatus = STATUS_BUFFER_TOO_SMALL;
4112 RtlZeroMemory( pNameInfo,
4115 usFullNameLength = sizeof( WCHAR) +
4116 AFSServerName.Length +
4117 pCcb->FullFileName.Length;
4119 if( *Length >= (LONG)(FIELD_OFFSET( FILE_NAME_INFORMATION, FileName) + (LONG)usFullNameLength))
4121 ulCopyLength = (LONG)usFullNameLength;
4125 ulCopyLength = *Length - FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
4126 ntStatus = STATUS_BUFFER_OVERFLOW;
4129 pNameInfo->FileNameLength = (ULONG)usFullNameLength;
4131 *Length -= FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
4133 if( ulCopyLength > 0)
4136 pNameInfo->FileName[ 0] = L'\\';
4137 ulCopyLength -= sizeof( WCHAR);
4139 *Length -= sizeof( WCHAR);
4141 if( ulCopyLength >= AFSServerName.Length)
4144 RtlCopyMemory( &pNameInfo->FileName[ 1],
4145 AFSServerName.Buffer,
4146 AFSServerName.Length);
4148 ulCopyLength -= AFSServerName.Length;
4149 *Length -= AFSServerName.Length;
4151 if( ulCopyLength >= pCcb->FullFileName.Length)
4154 RtlCopyMemory( &pNameInfo->FileName[ 1 + (AFSServerName.Length/sizeof( WCHAR))],
4155 pCcb->FullFileName.Buffer,
4156 pCcb->FullFileName.Length);
4158 ulCopyLength -= pCcb->FullFileName.Length;
4159 *Length -= pCcb->FullFileName.Length;
4161 uniName.Length = (USHORT)pNameInfo->FileNameLength;
4162 uniName.MaximumLength = uniName.Length;
4163 uniName.Buffer = pNameInfo->FileName;
4168 RtlCopyMemory( &pNameInfo->FileName[ 1 + (AFSServerName.Length/sizeof( WCHAR))],
4169 pCcb->FullFileName.Buffer,
4172 *Length -= ulCopyLength;
4174 uniName.Length = (USHORT)(sizeof( WCHAR) + AFSServerName.Length + ulCopyLength);
4175 uniName.MaximumLength = uniName.Length;
4176 uniName.Buffer = pNameInfo->FileName;
4179 AFSDbgLogMsg( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4180 AFS_TRACE_LEVEL_VERBOSE,
4181 "AFSProcessPIOCtlQueryInfo (FileNameInformation) Returning %wZ\n",
4189 case FileInternalInformation:
4192 PFILE_INTERNAL_INFORMATION pInternalInfo = (PFILE_INTERNAL_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
4194 AFSDbgLogMsg( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4195 AFS_TRACE_LEVEL_VERBOSE,
4196 "AFSProcessPIOCtlQueryInfo (FileInternalInformation)\n");
4198 if( *Length >= sizeof( FILE_INTERNAL_INFORMATION))
4201 pInternalInfo->IndexNumber.HighPart = 0;
4203 pInternalInfo->IndexNumber.LowPart = 0;
4205 *Length -= sizeof( FILE_INTERNAL_INFORMATION);
4210 ntStatus = STATUS_BUFFER_TOO_SMALL;
4216 case FileAllInformation:
4218 ntStatus = STATUS_INVALID_PARAMETER;
4220 AFSDbgLogMsg( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4221 AFS_TRACE_LEVEL_WARNING,
4222 "AFSProcessPIOCtlQueryInfo (FileAllInformation) Not Implemented\n");
4227 case FileEaInformation:
4229 ntStatus = STATUS_INVALID_PARAMETER;
4231 AFSDbgLogMsg( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4232 AFS_TRACE_LEVEL_WARNING,
4233 "AFSProcessPIOCtlQueryInfo (FileEaInformation) Not Implemented\n");
4238 case FilePositionInformation:
4240 ntStatus = STATUS_INVALID_PARAMETER;
4242 AFSDbgLogMsg( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4243 AFS_TRACE_LEVEL_WARNING,
4244 "AFSProcessPIOCtlQueryInfo (FilePositionInformation) Not Implemented\n");
4249 case FileAlternateNameInformation:
4251 ntStatus = STATUS_INVALID_PARAMETER;
4253 AFSDbgLogMsg( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4254 AFS_TRACE_LEVEL_WARNING,
4255 "AFSProcessPIOCtlQueryInfo (FileAlternateNameInformation) Not Implemented\n");
4260 case FileNetworkOpenInformation:
4262 ntStatus = STATUS_INVALID_PARAMETER;
4264 AFSDbgLogMsg( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4265 AFS_TRACE_LEVEL_WARNING,
4266 "AFSProcessPIOCtlQueryInfo (FileNetworkOpenInformation) Not Implemented\n");
4271 case FileStreamInformation:
4273 ntStatus = STATUS_INVALID_PARAMETER;
4275 AFSDbgLogMsg( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4276 AFS_TRACE_LEVEL_WARNING,
4277 "AFSProcessPIOCtlQueryInfo (FileStreamInformation) Not Implemented\n");
4282 case FileAttributeTagInformation:
4284 ntStatus = STATUS_INVALID_PARAMETER;
4286 AFSDbgLogMsg( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4287 AFS_TRACE_LEVEL_WARNING,
4288 "AFSProcessPIOCtlQueryInfo (FileAttributeTagInformation) Not Implemented\n");
4293 case FileRemoteProtocolInformation:
4295 ntStatus = STATUS_INVALID_PARAMETER;
4297 AFSDbgLogMsg( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4298 AFS_TRACE_LEVEL_WARNING,
4299 "AFSProcessPIOCtlQueryInfo (FileRemoteProtocolInformation) Not Implemented\n");
4304 case FileNetworkPhysicalNameInformation:
4306 ntStatus = STATUS_INVALID_PARAMETER;
4308 AFSDbgLogMsg( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4309 AFS_TRACE_LEVEL_WARNING,
4310 "AFSProcessPIOCtlQueryInfo (FileNetworkPhysicalNameInformation) Not Implemented\n");
4317 ntStatus = STATUS_INVALID_PARAMETER;
4319 AFSDbgLogMsg( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4320 AFS_TRACE_LEVEL_WARNING,
4321 "AFSProcessPIOCtlQueryInfo Not handling request %08lX\n",
4322 ulFileInformationClass);
4329 AFSDbgLogMsg( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
4330 AFS_TRACE_LEVEL_VERBOSE,
4331 "AFSProcessPIOCtlQueryInfo ntStatus %08lX\n",