2 * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC.
3 * Copyright (c) 2009, 2010, 2011 Your File System, Inc.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * - Redistributions of source code must retain the above copyright notice,
11 * this list of conditions and the following disclaimer.
12 * - Redistributions in binary form must reproduce the above copyright
14 * this list of conditions and the following disclaimer in the
16 * and/or other materials provided with the distribution.
17 * - Neither the names of Kernel Drivers, LLC and Your File System, Inc.
18 * nor the names of their contributors may be used to endorse or promote
19 * products derived from this software without specific prior written
20 * permission from Kernel Drivers, LLC and Your File System, Inc.
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
24 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
25 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
26 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 // File: AFSFileInfo.cpp
39 #include "AFSCommon.h"
42 // Function: AFSQueryFileInfo
46 // This function is the dispatch handler for the IRP_MJ_QUERY_FILE_INFORMATION request
50 // A status is returned for the function
54 AFSQueryFileInfo( IN PDEVICE_OBJECT LibDeviceObject,
58 NTSTATUS ntStatus = STATUS_SUCCESS;
59 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
60 ULONG ulRequestType = 0;
61 IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
64 PFILE_OBJECT pFileObject;
65 BOOLEAN bReleaseMain = FALSE;
67 FILE_INFORMATION_CLASS stFileInformationClass;
74 // Determine the type of request this request is
77 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
79 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
84 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
85 AFS_TRACE_LEVEL_ERROR,
86 "AFSQueryFileInfo Attempted access (%08lX) when pFcb == NULL\n",
89 try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST);
92 lLength = (LONG)pIrpSp->Parameters.QueryFile.Length;
93 stFileInformationClass = pIrpSp->Parameters.QueryFile.FileInformationClass;
94 pBuffer = Irp->AssociatedIrp.SystemBuffer;
97 // Grab the main shared right off the bat
100 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
101 AFS_TRACE_LEVEL_VERBOSE,
102 "AFSQueryFileInfo Acquiring Fcb lock %08lX SHARED %08lX\n",
103 &pFcb->NPFcb->Resource,
104 PsGetCurrentThread());
106 AFSAcquireShared( &pFcb->NPFcb->Resource,
112 // Don't allow requests against IOCtl nodes
115 if( pFcb->Header.NodeTypeCode == AFS_SPECIAL_SHARE_FCB)
118 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
119 AFS_TRACE_LEVEL_VERBOSE,
120 "AFSQueryFileInfo Processing request against SpecialShare Fcb\n");
122 ntStatus = AFSProcessShareQueryInfo( Irp,
126 try_return( ntStatus);
128 else if( pFcb->Header.NodeTypeCode == AFS_IOCTL_FCB)
130 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
131 AFS_TRACE_LEVEL_VERBOSE,
132 "AFSQueryFileInfo request against PIOCtl Fcb\n");
134 ntStatus = AFSProcessPIOCtlQueryInfo( Irp,
139 try_return( ntStatus);
143 // Process the request
146 switch( stFileInformationClass)
149 case FileAllInformation:
152 PFILE_ALL_INFORMATION pAllInfo;
155 // For the all information class we'll typecast a local
156 // pointer to the output buffer and then call the
157 // individual routines to fill in the buffer.
160 pAllInfo = (PFILE_ALL_INFORMATION)pBuffer;
162 ntStatus = AFSQueryBasicInfo( Irp,
164 &pAllInfo->BasicInformation,
167 if( !NT_SUCCESS( ntStatus))
170 try_return( ntStatus);
173 ntStatus = AFSQueryStandardInfo( Irp,
175 &pAllInfo->StandardInformation,
178 if( !NT_SUCCESS( ntStatus))
181 try_return( ntStatus);
184 ntStatus = AFSQueryInternalInfo( Irp,
186 &pAllInfo->InternalInformation,
189 if( !NT_SUCCESS( ntStatus))
192 try_return( ntStatus);
195 ntStatus = AFSQueryEaInfo( Irp,
197 &pAllInfo->EaInformation,
200 if( !NT_SUCCESS( ntStatus))
203 try_return( ntStatus);
206 ntStatus = AFSQueryAccess( Irp,
208 &pAllInfo->AccessInformation,
211 if( !NT_SUCCESS( ntStatus))
214 try_return( ntStatus);
217 ntStatus = AFSQueryPositionInfo( Irp,
219 &pAllInfo->PositionInformation,
222 if( !NT_SUCCESS( ntStatus))
225 try_return( ntStatus);
228 ntStatus = AFSQueryMode( Irp,
230 &pAllInfo->ModeInformation,
233 if( !NT_SUCCESS( ntStatus))
236 try_return( ntStatus);
239 ntStatus = AFSQueryAlignment( Irp,
241 &pAllInfo->AlignmentInformation,
244 if( !NT_SUCCESS( ntStatus))
247 try_return( ntStatus);
250 ntStatus = AFSQueryNameInfo( Irp,
252 &pAllInfo->NameInformation,
255 if( !NT_SUCCESS( ntStatus))
258 try_return( ntStatus);
264 case FileBasicInformation:
267 ntStatus = AFSQueryBasicInfo( Irp,
269 (PFILE_BASIC_INFORMATION)pBuffer,
275 case FileStandardInformation:
278 ntStatus = AFSQueryStandardInfo( Irp,
280 (PFILE_STANDARD_INFORMATION)pBuffer,
286 case FileInternalInformation:
289 ntStatus = AFSQueryInternalInfo( Irp,
291 (PFILE_INTERNAL_INFORMATION)pBuffer,
297 case FileEaInformation:
300 ntStatus = AFSQueryEaInfo( Irp,
302 (PFILE_EA_INFORMATION)pBuffer,
308 case FilePositionInformation:
311 ntStatus = AFSQueryPositionInfo( Irp,
313 (PFILE_POSITION_INFORMATION)pBuffer,
319 case FileNameInformation:
322 ntStatus = AFSQueryNameInfo( Irp,
324 (PFILE_NAME_INFORMATION)pBuffer,
330 case FileAlternateNameInformation:
333 ntStatus = AFSQueryShortNameInfo( Irp,
335 (PFILE_NAME_INFORMATION)pBuffer,
341 case FileNetworkOpenInformation:
344 ntStatus = AFSQueryNetworkInfo( Irp,
346 (PFILE_NETWORK_OPEN_INFORMATION)pBuffer,
352 case FileStreamInformation:
355 ntStatus = AFSQueryStreamInfo( Irp,
357 (FILE_STREAM_INFORMATION *)pBuffer,
364 case FileAttributeTagInformation:
367 ntStatus = AFSQueryAttribTagInfo( Irp,
369 (FILE_ATTRIBUTE_TAG_INFORMATION *)pBuffer,
375 case FileRemoteProtocolInformation:
378 ntStatus = AFSQueryRemoteProtocolInfo( Irp,
380 (FILE_REMOTE_PROTOCOL_INFORMATION *)pBuffer,
386 case FileNetworkPhysicalNameInformation:
389 ntStatus = AFSQueryPhysicalNameInfo( Irp,
391 (FILE_NETWORK_PHYSICAL_NAME_INFORMATION *)pBuffer,
399 ntStatus = STATUS_INVALID_PARAMETER;
406 Irp->IoStatus.Information = pIrpSp->Parameters.QueryFile.Length - lLength;
411 AFSReleaseResource( &pFcb->NPFcb->Resource);
414 if( !NT_SUCCESS( ntStatus) &&
415 ntStatus != STATUS_INVALID_PARAMETER &&
416 ntStatus != STATUS_BUFFER_OVERFLOW)
420 pCcb->DirectoryCB != NULL)
423 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
424 AFS_TRACE_LEVEL_ERROR,
425 "AFSQueryFileInfo Failed to process request for %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
426 &pCcb->DirectoryCB->NameInformation.FileName,
427 pCcb->DirectoryCB->ObjectInformation->FileId.Cell,
428 pCcb->DirectoryCB->ObjectInformation->FileId.Volume,
429 pCcb->DirectoryCB->ObjectInformation->FileId.Vnode,
430 pCcb->DirectoryCB->ObjectInformation->FileId.Unique,
435 __except( AFSExceptionFilter( GetExceptionCode(), GetExceptionInformation()) )
440 "EXCEPTION - AFSQueryFileInfo\n");
442 ntStatus = STATUS_UNSUCCESSFUL;
447 AFSReleaseResource( &pFcb->NPFcb->Resource);
451 AFSCompleteRequest( Irp,
458 // Function: AFSSetFileInfo
462 // This function is the dispatch handler for the IRP_MJ_SET_FILE_INFORMATION request
466 // A status is returned for the function
470 AFSSetFileInfo( IN PDEVICE_OBJECT LibDeviceObject,
474 NTSTATUS ntStatus = STATUS_SUCCESS;
475 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
476 IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
479 BOOLEAN bCompleteRequest = TRUE;
480 FILE_INFORMATION_CLASS FileInformationClass;
481 BOOLEAN bCanQueueRequest = FALSE;
482 PFILE_OBJECT pFileObject = NULL;
483 BOOLEAN bReleaseMain = FALSE;
484 BOOLEAN bUpdateFileInfo = FALSE;
485 AFSFileID stParentFileId;
490 pFileObject = pIrpSp->FileObject;
492 pFcb = (AFSFcb *)pFileObject->FsContext;
493 pCcb = (AFSCcb *)pFileObject->FsContext2;
498 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
499 AFS_TRACE_LEVEL_ERROR,
500 "AFSSetFileInfo Attempted access (%08lX) when pFcb == NULL\n",
503 try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST);
506 bCanQueueRequest = !(IoIsOperationSynchronous( Irp) | (KeGetCurrentIrql() != PASSIVE_LEVEL));
507 FileInformationClass = pIrpSp->Parameters.SetFile.FileInformationClass;
513 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
514 AFS_TRACE_LEVEL_VERBOSE,
515 "AFSSetFileInfo Acquiring Fcb lock %08lX EXCL %08lX\n",
516 &pFcb->NPFcb->Resource,
517 PsGetCurrentThread());
519 AFSAcquireExcl( &pFcb->NPFcb->Resource,
525 // Don't allow requests against IOCtl nodes
528 if( pFcb->Header.NodeTypeCode == AFS_IOCTL_FCB)
531 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
532 AFS_TRACE_LEVEL_ERROR,
533 "AFSSetFileInfo Failing request against PIOCtl Fcb\n");
535 try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST);
537 else if( pFcb->Header.NodeTypeCode == AFS_SPECIAL_SHARE_FCB)
540 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
541 AFS_TRACE_LEVEL_VERBOSE,
542 "AFSSetFileInfo Processing request against SpecialShare Fcb\n");
544 ntStatus = AFSProcessShareSetInfo( Irp,
548 try_return( ntStatus);
551 if( BooleanFlagOn( pFcb->ObjectInformation->VolumeCB->VolumeInformation.Characteristics, FILE_READ_ONLY_DEVICE))
554 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
555 AFS_TRACE_LEVEL_ERROR,
556 "AFSSetFileInfo Request failed due to read only volume\n",
559 try_return( ntStatus = STATUS_ACCESS_DENIED);
563 // Ensure rename operations are synchronous
566 if( FileInformationClass == FileRenameInformation)
569 bCanQueueRequest = FALSE;
573 // Store away the parent fid
576 RtlZeroMemory( &stParentFileId,
579 if( pFcb->ObjectInformation->ParentObjectInformation != NULL)
581 stParentFileId = pFcb->ObjectInformation->ParentObjectInformation->FileId;
585 // Process the request
588 switch( FileInformationClass)
591 case FileBasicInformation:
594 bUpdateFileInfo = TRUE;
596 ntStatus = AFSSetBasicInfo( Irp,
602 case FileDispositionInformation:
605 ntStatus = AFSSetDispositionInfo( Irp,
611 case FileRenameInformation:
614 ntStatus = AFSSetRenameInfo( Irp);
619 case FilePositionInformation:
622 ntStatus = AFSSetPositionInfo( Irp,
628 case FileLinkInformation:
631 ntStatus = STATUS_INVALID_DEVICE_REQUEST;
636 case FileAllocationInformation:
639 ntStatus = AFSSetAllocationInfo( Irp,
645 case FileEndOfFileInformation:
648 ntStatus = AFSSetEndOfFileInfo( Irp,
656 ntStatus = STATUS_INVALID_PARAMETER;
666 AFSReleaseResource( &pFcb->NPFcb->Resource);
669 if( NT_SUCCESS( ntStatus) &&
673 ntStatus = AFSUpdateFileInformation( &stParentFileId,
674 pFcb->ObjectInformation,
677 if( !NT_SUCCESS( ntStatus))
680 AFSAcquireExcl( &pFcb->NPFcb->Resource,
684 // Unwind the update and fail the request
687 AFSUnwindFileInfo( pFcb,
690 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
691 AFS_TRACE_LEVEL_ERROR,
692 "AFSSetFileInfo Failed to send file info update to service request for %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
693 &pCcb->DirectoryCB->NameInformation.FileName,
694 pCcb->DirectoryCB->ObjectInformation->FileId.Cell,
695 pCcb->DirectoryCB->ObjectInformation->FileId.Volume,
696 pCcb->DirectoryCB->ObjectInformation->FileId.Vnode,
697 pCcb->DirectoryCB->ObjectInformation->FileId.Unique,
700 AFSReleaseResource( &pFcb->NPFcb->Resource);
704 if( !NT_SUCCESS( ntStatus))
708 pCcb->DirectoryCB != NULL)
711 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
712 AFS_TRACE_LEVEL_ERROR,
713 "AFSSetFileInfo Failed to process request for %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
714 &pCcb->DirectoryCB->NameInformation.FileName,
715 pCcb->DirectoryCB->ObjectInformation->FileId.Cell,
716 pCcb->DirectoryCB->ObjectInformation->FileId.Volume,
717 pCcb->DirectoryCB->ObjectInformation->FileId.Vnode,
718 pCcb->DirectoryCB->ObjectInformation->FileId.Unique,
723 __except( AFSExceptionFilter( GetExceptionCode(), GetExceptionInformation()) )
728 "EXCEPTION - AFSSetFileInfo\n");
730 ntStatus = STATUS_UNSUCCESSFUL;
733 AFSCompleteRequest( Irp,
740 // Function: AFSQueryBasicInfo
744 // This function is the handler for the query basic information request
748 // A status is returned for the function
752 AFSQueryBasicInfo( IN PIRP Irp,
753 IN AFSDirectoryCB *DirectoryCB,
754 IN OUT PFILE_BASIC_INFORMATION Buffer,
757 NTSTATUS ntStatus = STATUS_SUCCESS;
758 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
759 ULONG ulFileAttribs = 0;
762 IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
763 AFSFileInfoCB stFileInfo;
764 AFSDirectoryCB *pParentDirectoryCB = NULL;
765 UNICODE_STRING uniParentPath;
767 if( *Length >= sizeof( FILE_BASIC_INFORMATION))
770 RtlZeroMemory( Buffer,
773 ulFileAttribs = DirectoryCB->ObjectInformation->FileAttributes;
775 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
776 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
778 if( DirectoryCB->ObjectInformation->FileType == AFS_FILE_TYPE_SYMLINK)
781 pParentDirectoryCB = AFSGetParentEntry( pCcb->NameArray);
783 AFSRetrieveParentPath( &pCcb->FullFileName,
786 RtlZeroMemory( &stFileInfo,
787 sizeof( AFSFileInfoCB));
790 // Can't hold the Fcb while evaluating the path, leads to lock inversion
793 AFSReleaseResource( &pFcb->NPFcb->Resource);
795 if( NT_SUCCESS( AFSRetrieveFileAttributes( pParentDirectoryCB,
801 ulFileAttribs = stFileInfo.FileAttributes;
803 ulFileAttribs |= FILE_ATTRIBUTE_REPARSE_POINT;
806 AFSAcquireShared( &pFcb->NPFcb->Resource,
810 Buffer->CreationTime = DirectoryCB->ObjectInformation->CreationTime;
811 Buffer->LastAccessTime = DirectoryCB->ObjectInformation->LastAccessTime;
812 Buffer->LastWriteTime = DirectoryCB->ObjectInformation->LastWriteTime;
813 Buffer->ChangeTime = DirectoryCB->ObjectInformation->ChangeTime;
814 Buffer->FileAttributes = ulFileAttribs;
816 if( DirectoryCB->NameInformation.FileName.Buffer[ 0] == L'.' &&
817 BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_HIDE_DOT_NAMES))
820 if ( Buffer->FileAttributes != FILE_ATTRIBUTE_NORMAL)
822 Buffer->FileAttributes |= FILE_ATTRIBUTE_HIDDEN;
826 Buffer->FileAttributes = FILE_ATTRIBUTE_HIDDEN;
830 *Length -= sizeof( FILE_BASIC_INFORMATION);
835 ntStatus = STATUS_BUFFER_TOO_SMALL;
842 AFSQueryStandardInfo( IN PIRP Irp,
843 IN AFSDirectoryCB *DirectoryCB,
844 IN OUT PFILE_STANDARD_INFORMATION Buffer,
848 NTSTATUS ntStatus = STATUS_SUCCESS;
851 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
852 AFSFileInfoCB stFileInfo;
853 AFSDirectoryCB *pParentDirectoryCB = NULL;
854 UNICODE_STRING uniParentPath;
855 ULONG ulFileAttribs = 0;
857 if( *Length >= sizeof( FILE_STANDARD_INFORMATION))
860 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
861 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
863 RtlZeroMemory( Buffer,
866 Buffer->NumberOfLinks = 1;
867 Buffer->DeletePending = BooleanFlagOn( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
869 Buffer->AllocationSize.QuadPart = (ULONGLONG)((DirectoryCB->ObjectInformation->AllocationSize.QuadPart/PAGE_SIZE) + 1) * PAGE_SIZE;
871 Buffer->EndOfFile = DirectoryCB->ObjectInformation->EndOfFile;
873 ulFileAttribs = DirectoryCB->ObjectInformation->FileAttributes;
875 if( DirectoryCB->ObjectInformation->FileType == AFS_FILE_TYPE_SYMLINK)
878 pParentDirectoryCB = AFSGetParentEntry( pCcb->NameArray);
880 AFSRetrieveParentPath( &pCcb->FullFileName,
883 RtlZeroMemory( &stFileInfo,
884 sizeof( AFSFileInfoCB));
887 // Can't hold the Fcb while evaluating the path, leads to lock inversion
890 AFSReleaseResource( &pFcb->NPFcb->Resource);
892 if( NT_SUCCESS( AFSRetrieveFileAttributes( pParentDirectoryCB,
898 ulFileAttribs = stFileInfo.FileAttributes;
901 AFSAcquireShared( &pFcb->NPFcb->Resource,
905 Buffer->Directory = BooleanFlagOn( ulFileAttribs, FILE_ATTRIBUTE_DIRECTORY);
907 *Length -= sizeof( FILE_STANDARD_INFORMATION);
912 ntStatus = STATUS_BUFFER_TOO_SMALL;
919 AFSQueryInternalInfo( IN PIRP Irp,
921 IN OUT PFILE_INTERNAL_INFORMATION Buffer,
925 NTSTATUS ntStatus = STATUS_SUCCESS;
927 if( *Length >= sizeof( FILE_INTERNAL_INFORMATION))
930 Buffer->IndexNumber.HighPart = Fcb->ObjectInformation->FileId.Volume;
932 Buffer->IndexNumber.LowPart = Fcb->ObjectInformation->FileId.Vnode;
934 *Length -= sizeof( FILE_INTERNAL_INFORMATION);
939 ntStatus = STATUS_BUFFER_TOO_SMALL;
946 AFSQueryEaInfo( IN PIRP Irp,
947 IN AFSDirectoryCB *DirectoryCB,
948 IN OUT PFILE_EA_INFORMATION Buffer,
952 NTSTATUS ntStatus = STATUS_SUCCESS;
954 RtlZeroMemory( Buffer,
957 if( *Length >= sizeof( FILE_EA_INFORMATION))
962 *Length -= sizeof( FILE_EA_INFORMATION);
967 ntStatus = STATUS_BUFFER_TOO_SMALL;
974 AFSQueryPositionInfo( IN PIRP Irp,
976 IN OUT PFILE_POSITION_INFORMATION Buffer,
980 NTSTATUS ntStatus = STATUS_SUCCESS;
981 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
983 if( *Length >= sizeof( FILE_POSITION_INFORMATION))
986 RtlZeroMemory( Buffer,
989 Buffer->CurrentByteOffset.QuadPart = pIrpSp->FileObject->CurrentByteOffset.QuadPart;
991 *Length -= sizeof( FILE_POSITION_INFORMATION);
996 ntStatus = STATUS_BUFFER_TOO_SMALL;
1003 AFSQueryAccess( IN PIRP Irp,
1005 IN OUT PFILE_ACCESS_INFORMATION Buffer,
1006 IN OUT PLONG Length)
1009 NTSTATUS ntStatus = STATUS_SUCCESS;
1011 if( *Length >= sizeof( FILE_ACCESS_INFORMATION))
1014 RtlZeroMemory( Buffer,
1017 Buffer->AccessFlags = 0;
1019 *Length -= sizeof( FILE_ACCESS_INFORMATION);
1024 ntStatus = STATUS_BUFFER_TOO_SMALL;
1031 AFSQueryMode( IN PIRP Irp,
1033 IN OUT PFILE_MODE_INFORMATION Buffer,
1034 IN OUT PLONG Length)
1037 NTSTATUS ntStatus = STATUS_SUCCESS;
1039 if( *Length >= sizeof( FILE_MODE_INFORMATION))
1042 RtlZeroMemory( Buffer,
1047 *Length -= sizeof( FILE_MODE_INFORMATION);
1052 ntStatus = STATUS_BUFFER_TOO_SMALL;
1059 AFSQueryAlignment( IN PIRP Irp,
1061 IN OUT PFILE_ALIGNMENT_INFORMATION Buffer,
1062 IN OUT PLONG Length)
1065 NTSTATUS ntStatus = STATUS_SUCCESS;
1067 if( *Length >= sizeof( FILE_ALIGNMENT_INFORMATION))
1070 RtlZeroMemory( Buffer,
1073 Buffer->AlignmentRequirement = 1;
1075 *Length -= sizeof( FILE_ALIGNMENT_INFORMATION);
1080 ntStatus = STATUS_BUFFER_TOO_SMALL;
1087 AFSQueryNameInfo( IN PIRP Irp,
1088 IN AFSDirectoryCB *DirectoryCB,
1089 IN OUT PFILE_NAME_INFORMATION Buffer,
1090 IN OUT PLONG Length)
1093 NTSTATUS ntStatus = STATUS_SUCCESS;
1094 ULONG ulCopyLength = 0;
1095 ULONG cchCopied = 0;
1096 AFSFcb *pFcb = NULL;
1097 AFSCcb *pCcb = NULL;
1098 IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1099 BOOLEAN bAddLeadingSlash = FALSE;
1100 BOOLEAN bAddTrailingSlash = FALSE;
1101 USHORT usFullNameLength = 0;
1103 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
1105 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
1107 if( *Length >= FIELD_OFFSET( FILE_NAME_INFORMATION, FileName))
1110 RtlZeroMemory( Buffer,
1113 if( pCcb->FullFileName.Length == 0 ||
1114 pCcb->FullFileName.Buffer[ 0] != L'\\')
1116 bAddLeadingSlash = TRUE;
1119 if( pFcb->ObjectInformation->FileType == AFS_FILE_TYPE_DIRECTORY &&
1120 pCcb->FullFileName.Length > 0 &&
1121 pCcb->FullFileName.Buffer[ (pCcb->FullFileName.Length/sizeof( WCHAR)) - 1] != L'\\')
1123 bAddTrailingSlash = TRUE;
1126 usFullNameLength = sizeof( WCHAR) +
1127 AFSServerName.Length +
1128 pCcb->FullFileName.Length;
1130 if( bAddLeadingSlash)
1132 usFullNameLength += sizeof( WCHAR);
1135 if( bAddTrailingSlash)
1137 usFullNameLength += sizeof( WCHAR);
1140 if( *Length >= (LONG)(FIELD_OFFSET( FILE_NAME_INFORMATION, FileName) + (LONG)usFullNameLength))
1143 ulCopyLength = (LONG)usFullNameLength;
1148 ulCopyLength = *Length - FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
1150 ntStatus = STATUS_BUFFER_OVERFLOW;
1153 Buffer->FileNameLength = (ULONG)usFullNameLength;
1155 *Length -= FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
1157 if( ulCopyLength > 0)
1160 Buffer->FileName[ 0] = L'\\';
1161 ulCopyLength -= sizeof( WCHAR);
1163 *Length -= sizeof( WCHAR);
1166 if( ulCopyLength >= AFSServerName.Length)
1169 RtlCopyMemory( &Buffer->FileName[ 1],
1170 AFSServerName.Buffer,
1171 AFSServerName.Length);
1173 ulCopyLength -= AFSServerName.Length;
1174 *Length -= AFSServerName.Length;
1175 cchCopied += AFSServerName.Length/sizeof( WCHAR);
1177 if ( ulCopyLength > 0 &&
1181 Buffer->FileName[ cchCopied] = L'\\';
1183 ulCopyLength -= sizeof( WCHAR);
1184 *Length -= sizeof( WCHAR);
1188 if( ulCopyLength >= pCcb->FullFileName.Length)
1191 RtlCopyMemory( &Buffer->FileName[ cchCopied],
1192 pCcb->FullFileName.Buffer,
1193 pCcb->FullFileName.Length);
1195 ulCopyLength -= pCcb->FullFileName.Length;
1196 *Length -= pCcb->FullFileName.Length;
1197 cchCopied += pCcb->FullFileName.Length/sizeof( WCHAR);
1199 if( ulCopyLength > 0 &&
1202 Buffer->FileName[ cchCopied] = L'\\';
1204 *Length -= sizeof( WCHAR);
1210 RtlCopyMemory( &Buffer->FileName[ cchCopied],
1211 pCcb->FullFileName.Buffer,
1214 *Length -= ulCopyLength;
1222 ntStatus = STATUS_BUFFER_TOO_SMALL;
1229 AFSQueryShortNameInfo( IN PIRP Irp,
1230 IN AFSDirectoryCB *DirectoryCB,
1231 IN OUT PFILE_NAME_INFORMATION Buffer,
1232 IN OUT PLONG Length)
1235 NTSTATUS ntStatus = STATUS_BUFFER_TOO_SMALL;
1236 ULONG ulCopyLength = 0;
1238 RtlZeroMemory( Buffer,
1241 if( DirectoryCB->NameInformation.ShortNameLength == 0)
1245 // The short name IS the long name
1248 if( *Length >= (LONG)FIELD_OFFSET( FILE_NAME_INFORMATION, FileName))
1251 if( *Length >= (LONG)(FIELD_OFFSET( FILE_NAME_INFORMATION, FileName) + (LONG)DirectoryCB->NameInformation.FileName.Length))
1254 ulCopyLength = (LONG)DirectoryCB->NameInformation.FileName.Length;
1256 ntStatus = STATUS_SUCCESS;
1261 ulCopyLength = *Length - FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
1263 ntStatus = STATUS_BUFFER_OVERFLOW;
1266 Buffer->FileNameLength = DirectoryCB->NameInformation.FileName.Length;
1268 *Length -= FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
1270 if( ulCopyLength > 0)
1273 RtlCopyMemory( Buffer->FileName,
1274 DirectoryCB->NameInformation.FileName.Buffer,
1277 *Length -= ulCopyLength;
1284 if( *Length >= (LONG)FIELD_OFFSET( FILE_NAME_INFORMATION, FileName))
1287 if( *Length >= (LONG)(FIELD_OFFSET( FILE_NAME_INFORMATION, FileName) + (LONG)DirectoryCB->NameInformation.FileName.Length))
1290 ulCopyLength = (LONG)DirectoryCB->NameInformation.ShortNameLength;
1292 ntStatus = STATUS_SUCCESS;
1297 ulCopyLength = *Length - FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
1299 ntStatus = STATUS_BUFFER_OVERFLOW;
1302 Buffer->FileNameLength = DirectoryCB->NameInformation.ShortNameLength;
1304 *Length -= FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
1306 if( ulCopyLength > 0)
1309 RtlCopyMemory( Buffer->FileName,
1310 DirectoryCB->NameInformation.ShortName,
1311 Buffer->FileNameLength);
1313 *Length -= ulCopyLength;
1322 AFSQueryNetworkInfo( IN PIRP Irp,
1323 IN AFSDirectoryCB *DirectoryCB,
1324 IN OUT PFILE_NETWORK_OPEN_INFORMATION Buffer,
1325 IN OUT PLONG Length)
1328 NTSTATUS ntStatus = STATUS_SUCCESS;
1329 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1330 AFSFcb *pFcb = NULL;
1331 AFSCcb *pCcb = NULL;
1332 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1333 AFSFileInfoCB stFileInfo;
1334 AFSDirectoryCB *pParentDirectoryCB = NULL;
1335 UNICODE_STRING uniParentPath;
1336 ULONG ulFileAttribs = 0;
1338 RtlZeroMemory( Buffer,
1341 if( *Length >= sizeof( FILE_NETWORK_OPEN_INFORMATION))
1344 ulFileAttribs = DirectoryCB->ObjectInformation->FileAttributes;
1346 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
1347 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
1349 if( DirectoryCB->ObjectInformation->FileType == AFS_FILE_TYPE_SYMLINK)
1352 pParentDirectoryCB = AFSGetParentEntry( pCcb->NameArray);
1354 AFSRetrieveParentPath( &pCcb->FullFileName,
1357 RtlZeroMemory( &stFileInfo,
1358 sizeof( AFSFileInfoCB));
1361 // Can't hold the Fcb while evaluating the path, leads to lock inversion
1364 AFSReleaseResource( &pFcb->NPFcb->Resource);
1366 if( NT_SUCCESS( AFSRetrieveFileAttributes( pParentDirectoryCB,
1372 ulFileAttribs = stFileInfo.FileAttributes;
1374 ulFileAttribs |= FILE_ATTRIBUTE_REPARSE_POINT;
1377 AFSAcquireShared( &pFcb->NPFcb->Resource,
1381 Buffer->CreationTime.QuadPart = DirectoryCB->ObjectInformation->CreationTime.QuadPart;
1382 Buffer->LastAccessTime.QuadPart = DirectoryCB->ObjectInformation->LastAccessTime.QuadPart;
1383 Buffer->LastWriteTime.QuadPart = DirectoryCB->ObjectInformation->LastWriteTime.QuadPart;
1384 Buffer->ChangeTime.QuadPart = DirectoryCB->ObjectInformation->ChangeTime.QuadPart;
1386 Buffer->AllocationSize.QuadPart = DirectoryCB->ObjectInformation->AllocationSize.QuadPart;
1387 Buffer->EndOfFile.QuadPart = DirectoryCB->ObjectInformation->EndOfFile.QuadPart;
1389 Buffer->FileAttributes = ulFileAttribs;
1391 if( DirectoryCB->NameInformation.FileName.Buffer[ 0] == L'.' &&
1392 BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_HIDE_DOT_NAMES))
1395 if ( Buffer->FileAttributes != FILE_ATTRIBUTE_NORMAL)
1398 Buffer->FileAttributes |= FILE_ATTRIBUTE_HIDDEN;
1403 Buffer->FileAttributes = FILE_ATTRIBUTE_HIDDEN;
1407 *Length -= sizeof( FILE_NETWORK_OPEN_INFORMATION);
1412 ntStatus = STATUS_BUFFER_TOO_SMALL;
1419 AFSQueryStreamInfo( IN PIRP Irp,
1420 IN AFSDirectoryCB *DirectoryCB,
1421 IN OUT FILE_STREAM_INFORMATION *Buffer,
1422 IN OUT PLONG Length)
1425 NTSTATUS ntStatus = STATUS_BUFFER_TOO_SMALL;
1426 ULONG ulCopyLength = 0;
1427 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1429 if( *Length >= FIELD_OFFSET( FILE_STREAM_INFORMATION, StreamName))
1432 RtlZeroMemory( Buffer,
1435 Buffer->NextEntryOffset = 0;
1438 if( !BooleanFlagOn( DirectoryCB->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_DIRECTORY))
1441 if( *Length >= (LONG)(FIELD_OFFSET( FILE_STREAM_INFORMATION, StreamName) + 14)) // ::$DATA
1446 ntStatus = STATUS_SUCCESS;
1451 ulCopyLength = *Length - FIELD_OFFSET( FILE_STREAM_INFORMATION, StreamName);
1453 ntStatus = STATUS_BUFFER_OVERFLOW;
1456 Buffer->StreamNameLength = 14; // ::$DATA
1458 Buffer->StreamSize.QuadPart = DirectoryCB->ObjectInformation->EndOfFile.QuadPart;
1460 Buffer->StreamAllocationSize.QuadPart = DirectoryCB->ObjectInformation->AllocationSize.QuadPart;
1462 *Length -= FIELD_OFFSET( FILE_STREAM_INFORMATION, StreamName);
1464 if( ulCopyLength > 0)
1467 RtlCopyMemory( Buffer->StreamName,
1471 *Length -= ulCopyLength;
1477 Buffer->StreamNameLength = 0; // No stream for a directory
1479 // The response size is zero
1481 ntStatus = STATUS_SUCCESS;
1489 AFSQueryAttribTagInfo( IN PIRP Irp,
1490 IN AFSDirectoryCB *DirectoryCB,
1491 IN OUT FILE_ATTRIBUTE_TAG_INFORMATION *Buffer,
1492 IN OUT PLONG Length)
1495 NTSTATUS ntStatus = STATUS_BUFFER_TOO_SMALL;
1496 ULONG ulCopyLength = 0;
1497 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1498 AFSFcb *pFcb = NULL;
1499 AFSCcb *pCcb = NULL;
1500 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1501 AFSFileInfoCB stFileInfo;
1502 AFSDirectoryCB *pParentDirectoryCB = NULL;
1503 UNICODE_STRING uniParentPath;
1504 ULONG ulFileAttribs = 0;
1506 if( *Length >= sizeof( FILE_ATTRIBUTE_TAG_INFORMATION))
1509 RtlZeroMemory( Buffer,
1512 ulFileAttribs = DirectoryCB->ObjectInformation->FileAttributes;
1514 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
1515 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
1517 if( DirectoryCB->ObjectInformation->FileType == AFS_FILE_TYPE_SYMLINK)
1520 pParentDirectoryCB = AFSGetParentEntry( pCcb->NameArray);
1522 AFSRetrieveParentPath( &pCcb->FullFileName,
1525 RtlZeroMemory( &stFileInfo,
1526 sizeof( AFSFileInfoCB));
1529 // Can't hold the Fcb while evaluating the path, leads to lock inversion
1532 AFSReleaseResource( &pFcb->NPFcb->Resource);
1534 if( NT_SUCCESS( AFSRetrieveFileAttributes( pParentDirectoryCB,
1540 ulFileAttribs = stFileInfo.FileAttributes;
1542 ulFileAttribs |= FILE_ATTRIBUTE_REPARSE_POINT;
1545 AFSAcquireShared( &pFcb->NPFcb->Resource,
1549 Buffer->FileAttributes = ulFileAttribs;
1551 if( DirectoryCB->NameInformation.FileName.Buffer[ 0] == L'.' &&
1552 BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_HIDE_DOT_NAMES))
1555 if ( Buffer->FileAttributes != FILE_ATTRIBUTE_NORMAL)
1558 Buffer->FileAttributes |= FILE_ATTRIBUTE_HIDDEN;
1563 Buffer->FileAttributes = FILE_ATTRIBUTE_HIDDEN;
1567 if( BooleanFlagOn( DirectoryCB->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_REPARSE_POINT))
1569 Buffer->ReparseTag = IO_REPARSE_TAG_OPENAFS_DFS;
1572 *Length -= sizeof( FILE_ATTRIBUTE_TAG_INFORMATION);
1574 ntStatus = STATUS_SUCCESS;
1581 AFSQueryRemoteProtocolInfo( IN PIRP Irp,
1582 IN AFSDirectoryCB *DirectoryCB,
1583 IN OUT FILE_REMOTE_PROTOCOL_INFORMATION *Buffer,
1584 IN OUT PLONG Length)
1587 NTSTATUS ntStatus = STATUS_BUFFER_TOO_SMALL;
1588 ULONG ulCopyLength = 0;
1589 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1591 if( *Length >= sizeof( FILE_REMOTE_PROTOCOL_INFORMATION))
1594 RtlZeroMemory( Buffer,
1597 Buffer->StructureVersion = 1;
1599 Buffer->StructureSize = sizeof(FILE_REMOTE_PROTOCOL_INFORMATION);
1601 Buffer->Protocol = WNNC_NET_OPENAFS;
1603 Buffer->ProtocolMajorVersion = 3;
1605 Buffer->ProtocolMinorVersion = 0;
1607 Buffer->ProtocolRevision = 0;
1609 *Length -= sizeof( FILE_REMOTE_PROTOCOL_INFORMATION);
1611 ntStatus = STATUS_SUCCESS;
1618 AFSQueryPhysicalNameInfo( IN PIRP Irp,
1619 IN AFSDirectoryCB *DirectoryCB,
1620 IN OUT PFILE_NETWORK_PHYSICAL_NAME_INFORMATION Buffer,
1621 IN OUT PLONG Length)
1624 NTSTATUS ntStatus = STATUS_SUCCESS;
1625 ULONG ulCopyLength = 0;
1626 ULONG cchCopied = 0;
1627 AFSFcb *pFcb = NULL;
1628 AFSCcb *pCcb = NULL;
1629 IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1630 BOOLEAN bAddLeadingSlash = FALSE;
1631 USHORT usFullNameLength = 0;
1633 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
1635 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
1637 if( *Length >= FIELD_OFFSET( FILE_NETWORK_PHYSICAL_NAME_INFORMATION, FileName))
1640 RtlZeroMemory( Buffer,
1643 if( pCcb->FullFileName.Length == 0 ||
1644 pCcb->FullFileName.Buffer[ 0] != L'\\')
1646 bAddLeadingSlash = TRUE;
1649 usFullNameLength = pCcb->FullFileName.Length;
1651 if( bAddLeadingSlash)
1653 usFullNameLength += sizeof( WCHAR);
1656 if( *Length >= (LONG)(FIELD_OFFSET( FILE_NETWORK_PHYSICAL_NAME_INFORMATION, FileName) + (LONG)usFullNameLength))
1658 ulCopyLength = (LONG)usFullNameLength;
1663 ulCopyLength = *Length - FIELD_OFFSET( FILE_NETWORK_PHYSICAL_NAME_INFORMATION, FileName);
1665 ntStatus = STATUS_BUFFER_OVERFLOW;
1668 Buffer->FileNameLength = (ULONG)usFullNameLength;
1670 *Length -= FIELD_OFFSET( FILE_NETWORK_PHYSICAL_NAME_INFORMATION, FileName);
1672 if( ulCopyLength > 0)
1675 if( bAddLeadingSlash)
1678 Buffer->FileName[ cchCopied] = L'\\';
1680 ulCopyLength -= sizeof( WCHAR);
1681 *Length -= sizeof( WCHAR);
1685 if( ulCopyLength >= pCcb->FullFileName.Length)
1688 RtlCopyMemory( &Buffer->FileName[ cchCopied],
1689 pCcb->FullFileName.Buffer,
1690 pCcb->FullFileName.Length);
1692 ulCopyLength -= pCcb->FullFileName.Length;
1693 *Length -= pCcb->FullFileName.Length;
1694 cchCopied += pCcb->FullFileName.Length/sizeof( WCHAR);
1699 RtlCopyMemory( &Buffer->FileName[ cchCopied],
1700 pCcb->FullFileName.Buffer,
1703 *Length -= ulCopyLength;
1710 ntStatus = STATUS_BUFFER_TOO_SMALL;
1717 AFSSetBasicInfo( IN PIRP Irp,
1718 IN AFSDirectoryCB *DirectoryCB)
1720 NTSTATUS ntStatus = STATUS_SUCCESS;
1721 PFILE_BASIC_INFORMATION pBuffer;
1722 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1723 ULONG ulNotifyFilter = 0;
1724 AFSCcb *pCcb = NULL;
1729 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
1731 pBuffer = (PFILE_BASIC_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
1733 pCcb->FileUnwindInfo.FileAttributes = (ULONG)-1;
1735 if( pBuffer->FileAttributes != (ULONGLONG)0)
1738 if( DirectoryCB->ObjectInformation->Fcb->Header.NodeTypeCode == AFS_FILE_FCB &&
1739 BooleanFlagOn( pBuffer->FileAttributes, FILE_ATTRIBUTE_DIRECTORY))
1742 try_return( ntStatus = STATUS_INVALID_PARAMETER);
1745 if( DirectoryCB->ObjectInformation->Fcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB)
1748 pBuffer->FileAttributes |= FILE_ATTRIBUTE_DIRECTORY;
1751 pCcb->FileUnwindInfo.FileAttributes = DirectoryCB->ObjectInformation->FileAttributes;
1753 DirectoryCB->ObjectInformation->FileAttributes = pBuffer->FileAttributes;
1755 ulNotifyFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
1757 SetFlag( DirectoryCB->ObjectInformation->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED);
1760 pCcb->FileUnwindInfo.CreationTime.QuadPart = (ULONGLONG)-1;
1762 if( pBuffer->CreationTime.QuadPart != (ULONGLONG)-1 &&
1763 pBuffer->CreationTime.QuadPart != (ULONGLONG)0)
1766 pCcb->FileUnwindInfo.CreationTime.QuadPart = DirectoryCB->ObjectInformation->CreationTime.QuadPart;
1768 DirectoryCB->ObjectInformation->CreationTime.QuadPart = pBuffer->CreationTime.QuadPart;
1770 ulNotifyFilter |= FILE_NOTIFY_CHANGE_CREATION;
1772 SetFlag( DirectoryCB->ObjectInformation->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_CREATE_TIME);
1775 pCcb->FileUnwindInfo.LastAccessTime.QuadPart = (ULONGLONG)-1;
1777 if( pBuffer->LastAccessTime.QuadPart != (ULONGLONG)-1 &&
1778 pBuffer->LastAccessTime.QuadPart != (ULONGLONG)0)
1781 pCcb->FileUnwindInfo.LastAccessTime.QuadPart = DirectoryCB->ObjectInformation->LastAccessTime.QuadPart;
1783 DirectoryCB->ObjectInformation->LastAccessTime.QuadPart = pBuffer->LastAccessTime.QuadPart;
1785 ulNotifyFilter |= FILE_NOTIFY_CHANGE_LAST_ACCESS;
1787 SetFlag( DirectoryCB->ObjectInformation->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_ACCESS_TIME);
1790 pCcb->FileUnwindInfo.LastWriteTime.QuadPart = (ULONGLONG)-1;
1792 if( pBuffer->LastWriteTime.QuadPart != (ULONGLONG)-1 &&
1793 pBuffer->LastWriteTime.QuadPart != (ULONGLONG)0)
1796 pCcb->FileUnwindInfo.LastWriteTime.QuadPart = DirectoryCB->ObjectInformation->LastWriteTime.QuadPart;
1798 DirectoryCB->ObjectInformation->LastWriteTime.QuadPart = pBuffer->LastWriteTime.QuadPart;
1800 ulNotifyFilter |= FILE_NOTIFY_CHANGE_LAST_WRITE;
1802 SetFlag( DirectoryCB->ObjectInformation->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_LAST_WRITE_TIME);
1805 pCcb->FileUnwindInfo.ChangeTime.QuadPart = (ULONGLONG)-1;
1807 if( pBuffer->ChangeTime.QuadPart != (ULONGLONG)-1 &&
1808 pBuffer->ChangeTime.QuadPart != (ULONGLONG)0)
1811 pCcb->FileUnwindInfo.ChangeTime.QuadPart = DirectoryCB->ObjectInformation->ChangeTime.QuadPart;
1813 DirectoryCB->ObjectInformation->ChangeTime.QuadPart = pBuffer->ChangeTime.QuadPart;
1815 ulNotifyFilter |= FILE_NOTIFY_CHANGE_LAST_ACCESS;
1817 SetFlag( DirectoryCB->ObjectInformation->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_CHANGE_TIME);
1820 if( ulNotifyFilter > 0)
1823 if( DirectoryCB->ObjectInformation->ParentObjectInformation != NULL)
1826 AFSFsRtlNotifyFullReportChange( DirectoryCB->ObjectInformation->ParentObjectInformation,
1828 (ULONG)ulNotifyFilter,
1829 (ULONG)FILE_ACTION_MODIFIED);
1842 AFSSetDispositionInfo( IN PIRP Irp,
1843 IN AFSDirectoryCB *DirectoryCB)
1845 NTSTATUS ntStatus = STATUS_SUCCESS;
1846 PFILE_DISPOSITION_INFORMATION pBuffer;
1847 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1848 AFSFcb *pFcb = NULL;
1849 AFSCcb *pCcb = NULL;
1854 pBuffer = (PFILE_DISPOSITION_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
1856 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
1858 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
1861 // Can't delete the root
1864 if( pFcb->Header.NodeTypeCode == AFS_ROOT_FCB)
1867 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1868 AFS_TRACE_LEVEL_ERROR,
1869 "AFSSetDispositionInfo Attempt to delete root entry\n");
1871 try_return( ntStatus = STATUS_CANNOT_DELETE);
1875 // If the file is read only then do not allow the delete
1878 if( BooleanFlagOn( DirectoryCB->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_READONLY))
1881 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1882 AFS_TRACE_LEVEL_ERROR,
1883 "AFSSetDispositionInfo Attempt to delete read only entry %wZ\n",
1884 &DirectoryCB->NameInformation.FileName);
1886 try_return( ntStatus = STATUS_CANNOT_DELETE);
1889 if( pBuffer->DeleteFile)
1893 // Check if the caller can delete the file
1896 ntStatus = AFSNotifyDelete( DirectoryCB,
1899 if( !NT_SUCCESS( ntStatus))
1902 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1903 AFS_TRACE_LEVEL_ERROR,
1904 "AFSSetDispositionInfo Cannot delete entry %wZ Status %08lX\n",
1905 &DirectoryCB->NameInformation.FileName,
1908 try_return( ntStatus);
1911 if( pFcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB)
1915 // Check if this is a directory that there are not currently other opens
1918 if( pFcb->ObjectInformation->Specific.Directory.ChildOpenHandleCount > 0)
1921 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1922 AFS_TRACE_LEVEL_ERROR,
1923 "AFSSetDispositionInfo Attempt to delete directory %wZ with open %u handles\n",
1924 &DirectoryCB->NameInformation.FileName,
1925 pFcb->ObjectInformation->Specific.Directory.ChildOpenHandleCount);
1927 try_return( ntStatus = STATUS_DIRECTORY_NOT_EMPTY);
1930 if( !AFSIsDirectoryEmptyForDelete( pFcb))
1933 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1934 AFS_TRACE_LEVEL_ERROR,
1935 "AFSSetDispositionInfo Attempt to delete non-empty directory %wZ\n",
1936 &DirectoryCB->NameInformation.FileName);
1938 try_return( ntStatus = STATUS_DIRECTORY_NOT_EMPTY);
1945 // Attempt to flush any outstanding data
1948 if( !MmFlushImageSection( &pFcb->NPFcb->SectionObjectPointers,
1952 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1953 AFS_TRACE_LEVEL_ERROR,
1954 "AFSSetDispositionInfo Failed to flush image section for delete Entry %wZ\n",
1955 &DirectoryCB->NameInformation.FileName);
1957 try_return( ntStatus = STATUS_CANNOT_DELETE);
1961 // Purge the cache as well
1964 if( pFcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
1967 CcPurgeCacheSection( &pFcb->NPFcb->SectionObjectPointers,
1974 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1975 AFS_TRACE_LEVEL_VERBOSE,
1976 "AFSSetDispositionInfo Setting PENDING_DELETE on DirEntry %p Name %wZ\n",
1978 &DirectoryCB->NameInformation.FileName);
1980 SetFlag( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
1985 ClearFlag( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
1989 // OK, should be good to go, set the flag in the file object
1992 pIrpSp->FileObject->DeletePending = pBuffer->DeleteFile;
2003 AFSSetRenameInfo( IN PIRP Irp)
2006 NTSTATUS ntStatus = STATUS_SUCCESS;
2007 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2008 IO_STATUS_BLOCK stIoSb = {0,0};
2009 AFSFcb *pSrcFcb = NULL, *pTargetDcb = NULL, *pTargetFcb = NULL;
2010 AFSCcb *pSrcCcb = NULL, *pTargetDirCcb = NULL;
2011 PFILE_OBJECT pSrcFileObj = pIrpSp->FileObject;
2012 PFILE_OBJECT pTargetFileObj = pIrpSp->Parameters.SetFile.FileObject;
2013 PFILE_RENAME_INFORMATION pRenameInfo = NULL;
2014 UNICODE_STRING uniTargetName, uniSourceName;
2015 BOOLEAN bReplaceIfExists = FALSE;
2016 UNICODE_STRING uniShortName;
2017 AFSDirectoryCB *pTargetDirEntry = NULL;
2018 ULONG ulTargetCRC = 0;
2019 BOOLEAN bTargetEntryExists = FALSE;
2020 AFSObjectInfoCB *pSrcObject = NULL, *pTargetObject = NULL;
2021 AFSObjectInfoCB *pSrcParentObject = NULL, *pTargetParentObject = NULL;
2022 AFSFileID stNewFid, stTmpTargetFid;
2023 ULONG ulNotificationAction = 0, ulNotifyFilter = 0;
2024 UNICODE_STRING uniFullTargetPath;
2025 BOOLEAN bCommonParent = FALSE;
2027 BOOLEAN bReleaseVolumeLock = FALSE;
2028 BOOLEAN bReleaseTargetDirLock = FALSE;
2029 BOOLEAN bReleaseSourceDirLock = FALSE;
2030 PERESOURCE pSourceDirLock = NULL;
2035 bReplaceIfExists = pIrpSp->Parameters.SetFile.ReplaceIfExists;
2037 pSrcFcb = (AFSFcb *)pSrcFileObj->FsContext;
2038 pSrcCcb = (AFSCcb *)pSrcFileObj->FsContext2;
2040 pSrcObject = pSrcFcb->ObjectInformation;
2043 // Perform some basic checks to ensure FS integrity
2046 if( pSrcFcb->Header.NodeTypeCode == AFS_ROOT_FCB)
2050 // Can't rename the root directory
2053 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2054 AFS_TRACE_LEVEL_ERROR,
2055 "AFSSetRenameInfo Attempt to rename root entry\n");
2057 try_return( ntStatus = STATUS_INVALID_PARAMETER);
2060 if( pSrcFcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB)
2064 // If there are any open children then fail the rename
2067 if( pSrcFcb->ObjectInformation->Specific.Directory.ChildOpenHandleCount > 0)
2070 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2071 AFS_TRACE_LEVEL_ERROR,
2072 "AFSSetRenameInfo Attempt to rename directory with open children %wZ\n",
2073 &pSrcCcb->DirectoryCB->NameInformation.FileName);
2075 try_return( ntStatus = STATUS_ACCESS_DENIED);
2081 if( pSrcFcb->OpenHandleCount > 1)
2084 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2085 AFS_TRACE_LEVEL_ERROR,
2086 "AFSSetRenameInfo Attempt to rename directory with open references %wZ\n",
2087 &pSrcCcb->DirectoryCB->NameInformation.FileName);
2089 try_return( ntStatus = STATUS_ACCESS_DENIED);
2094 // Resolve the target fileobject
2097 if( pTargetFileObj == NULL)
2101 // This is a simple rename. Here the target directory is the same as the source parent directory
2102 // and the name is retrieved from the system buffer information
2105 pRenameInfo = (PFILE_RENAME_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
2107 pTargetParentObject = pSrcFcb->ObjectInformation->ParentObjectInformation;
2109 pTargetDcb = pTargetParentObject->Fcb;
2111 uniTargetName.Length = (USHORT)pRenameInfo->FileNameLength;
2112 uniTargetName.Buffer = (PWSTR)&pRenameInfo->FileName;
2118 // So here we have the target directory taken from the targetfile object
2121 pTargetDcb = (AFSFcb *)pTargetFileObj->FsContext;
2123 pTargetDirCcb = (AFSCcb *)pTargetFileObj->FsContext2;
2125 pTargetParentObject = (AFSObjectInfoCB *)pTargetDcb->ObjectInformation;
2128 // Grab the target name which we setup in the IRP_MJ_CREATE handler. By how we set this up
2129 // it is only the target component of the rename operation
2132 uniTargetName = *((PUNICODE_STRING)&pTargetFileObj->FileName);
2136 // We do not allow cross-volume renames to occur
2139 if( pTargetParentObject->VolumeCB != pSrcObject->VolumeCB)
2142 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2143 AFS_TRACE_LEVEL_ERROR,
2144 "AFSSetRenameInfo Attempt to rename directory to different volume %wZ\n",
2145 &pSrcCcb->DirectoryCB->NameInformation.FileName);
2147 try_return( ntStatus = STATUS_NOT_SAME_DEVICE);
2150 AFSAcquireExcl( pTargetParentObject->VolumeCB->VolumeLock,
2153 bReleaseVolumeLock = TRUE;
2155 ulTargetCRC = AFSGenerateCRC( &uniTargetName,
2158 AFSAcquireExcl( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock,
2161 bReleaseTargetDirLock = TRUE;
2163 if( pTargetParentObject != pSrcFcb->ObjectInformation->ParentObjectInformation)
2165 AFSAcquireExcl( pSrcFcb->ObjectInformation->ParentObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
2168 bReleaseSourceDirLock = TRUE;
2170 pSourceDirLock = pSrcFcb->ObjectInformation->ParentObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock;
2173 AFSLocateCaseSensitiveDirEntry( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
2177 if( pTargetDirEntry == NULL)
2181 // Missed so perform a case insensitive lookup
2184 ulTargetCRC = AFSGenerateCRC( &uniTargetName,
2187 AFSLocateCaseInsensitiveDirEntry( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
2192 if( pTargetDirEntry == NULL && RtlIsNameLegalDOS8Dot3( &uniTargetName,
2197 // Try the short name
2199 AFSLocateShortNameDirEntry( pTargetParentObject->Specific.Directory.ShortNameTree,
2205 // Increment our ref count on the dir entry
2208 if( pTargetDirEntry != NULL)
2211 ASSERT( pTargetParentObject == pTargetDirEntry->ObjectInformation->ParentObjectInformation);
2213 InterlockedIncrement( &pTargetDirEntry->OpenReferenceCount);
2215 if( !bReplaceIfExists)
2218 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2219 AFS_TRACE_LEVEL_ERROR,
2220 "AFSSetRenameInfo Attempt to rename directory with target collision %wZ Target %wZ\n",
2221 &pSrcCcb->DirectoryCB->NameInformation.FileName,
2222 &pTargetDirEntry->NameInformation.FileName);
2224 try_return( ntStatus = STATUS_OBJECT_NAME_COLLISION);
2227 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2228 AFS_TRACE_LEVEL_ERROR,
2229 "AFSSetRenameInfo Target %wZ exists DE %p Count %08lX, performing delete of target\n",
2230 &pTargetDirEntry->NameInformation.FileName,
2232 pTargetDirEntry->OpenReferenceCount);
2235 // Pull the directory entry from the parent
2238 AFSRemoveDirNodeFromParent( pTargetParentObject,
2242 bTargetEntryExists = TRUE;
2246 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2247 AFS_TRACE_LEVEL_ERROR,
2248 "AFSSetRenameInfo Target Target does NOT exist, normal rename\n");
2252 // Extract off the final component name from the Fcb
2255 uniSourceName.Length = (USHORT)pSrcCcb->DirectoryCB->NameInformation.FileName.Length;
2256 uniSourceName.MaximumLength = uniSourceName.Length;
2258 uniSourceName.Buffer = pSrcCcb->DirectoryCB->NameInformation.FileName.Buffer;
2261 // The quick check to see if they are not really performing a rename
2262 // Do the names match? Only do this where the parent directories are
2266 if( pTargetParentObject == pSrcFcb->ObjectInformation->ParentObjectInformation)
2269 bCommonParent = TRUE;
2271 if( FsRtlAreNamesEqual( &uniTargetName,
2276 try_return( ntStatus = STATUS_SUCCESS);
2282 bCommonParent = FALSE;
2286 // We need to remove the DirEntry from the parent node, update the index
2287 // and reinsert it into the parent tree. Note that for entries with the
2288 // same parent we do not pull the node from the enumeration list
2291 AFSRemoveDirNodeFromParent( pSrcFcb->ObjectInformation->ParentObjectInformation,
2292 pSrcCcb->DirectoryCB,
2295 oldFileIndex = pSrcCcb->DirectoryCB->FileIndex;
2301 // We always need to update the FileIndex since this entry will be put at the 'end'
2302 // of the enumeraiton list. If we don't it will cause recursion ... We do this
2303 // here to cover any failures which might occur below
2306 pSrcCcb->DirectoryCB->FileIndex =
2307 (ULONG)InterlockedIncrement( &pTargetDcb->ObjectInformation->ParentObjectInformation->Specific.Directory.DirectoryNodeHdr.ContentIndex);
2311 // OK, this is a simple rename. Issue the rename
2312 // request to the service.
2315 ntStatus = AFSNotifyRename( pSrcFcb->ObjectInformation,
2316 pSrcFcb->ObjectInformation->ParentObjectInformation,
2317 pTargetDcb->ObjectInformation,
2318 pSrcCcb->DirectoryCB,
2322 if( !NT_SUCCESS( ntStatus))
2326 // Attempt to re-insert the directory entry
2329 pSrcCcb->DirectoryCB->FileIndex = oldFileIndex;
2330 AFSInsertDirectoryNode( pSrcFcb->ObjectInformation->ParentObjectInformation,
2331 pSrcCcb->DirectoryCB,
2334 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2335 AFS_TRACE_LEVEL_ERROR,
2336 "AFSSetRenameInfo Failed rename of %wZ to target %wZ Status %08lX\n",
2337 &pSrcCcb->DirectoryCB->NameInformation.FileName,
2341 try_return( ntStatus);
2345 // Set the notification up for the source file
2348 if( pSrcCcb->DirectoryCB->ObjectInformation->ParentObjectInformation == pTargetParentObject &&
2349 !bTargetEntryExists)
2352 ulNotificationAction = FILE_ACTION_RENAMED_OLD_NAME;
2357 ulNotificationAction = FILE_ACTION_REMOVED;
2360 if( pSrcCcb->DirectoryCB->ObjectInformation->FileType == AFS_FILE_TYPE_DIRECTORY)
2363 ulNotifyFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
2368 ulNotifyFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
2371 AFSFsRtlNotifyFullReportChange( pSrcCcb->DirectoryCB->ObjectInformation->ParentObjectInformation,
2373 (ULONG)ulNotifyFilter,
2374 (ULONG)ulNotificationAction);
2377 // Update the name in the dir entry.
2380 ntStatus = AFSUpdateDirEntryName( pSrcCcb->DirectoryCB,
2383 if( !NT_SUCCESS( ntStatus))
2387 // Attempt to re-insert the directory entry
2390 pSrcCcb->DirectoryCB->FileIndex = oldFileIndex;
2391 AFSInsertDirectoryNode( pSrcFcb->ObjectInformation->ParentObjectInformation,
2392 pSrcCcb->DirectoryCB,
2395 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2396 AFS_TRACE_LEVEL_ERROR,
2397 "AFSSetRenameInfo Failed update of dir entry %wZ to target %wZ Status %08lX\n",
2398 &pSrcCcb->DirectoryCB->NameInformation.FileName,
2402 try_return( ntStatus);
2406 // Update the object information block, if needed
2409 if( !AFSIsEqualFID( &pSrcObject->FileId,
2414 // Remove the old information entry
2417 AFSRemoveHashEntry( &pSrcObject->VolumeCB->ObjectInfoTree.TreeHead,
2418 &pSrcObject->TreeEntry);
2420 RtlCopyMemory( &pSrcObject->FileId,
2422 sizeof( AFSFileID));
2425 // Insert the entry into the new object table.
2428 pSrcObject->TreeEntry.HashIndex = AFSCreateLowIndex( &pSrcObject->FileId);
2430 if( pSrcObject->VolumeCB->ObjectInfoTree.TreeHead == NULL)
2433 pSrcObject->VolumeCB->ObjectInfoTree.TreeHead = &pSrcObject->TreeEntry;
2438 AFSInsertHashEntry( pSrcObject->VolumeCB->ObjectInfoTree.TreeHead,
2439 &pSrcObject->TreeEntry);
2444 // Update the hash values for the name trees.
2447 pSrcCcb->DirectoryCB->CaseSensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pSrcCcb->DirectoryCB->NameInformation.FileName,
2450 pSrcCcb->DirectoryCB->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pSrcCcb->DirectoryCB->NameInformation.FileName,
2453 if( pSrcCcb->DirectoryCB->NameInformation.ShortNameLength > 0 &&
2454 !RtlIsNameLegalDOS8Dot3( &pSrcCcb->DirectoryCB->NameInformation.FileName,
2459 uniShortName.Length = pSrcCcb->DirectoryCB->NameInformation.ShortNameLength;
2460 uniShortName.MaximumLength = uniShortName.Length;
2461 uniShortName.Buffer = pSrcCcb->DirectoryCB->NameInformation.ShortName;
2463 pSrcCcb->DirectoryCB->Type.Data.ShortNameTreeEntry.HashIndex = AFSGenerateCRC( &uniShortName,
2466 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2467 AFS_TRACE_LEVEL_VERBOSE,
2468 "AFSSetRenameInfo Initialized short name hash for %wZ longname %wZ\n",
2470 &pSrcCcb->DirectoryCB->NameInformation.FileName);
2475 pSrcCcb->DirectoryCB->Type.Data.ShortNameTreeEntry.HashIndex = 0;
2482 // Update the file index for the object in the new parent
2485 pSrcCcb->DirectoryCB->FileIndex = (ULONG)InterlockedIncrement( &pTargetParentObject->Specific.Directory.DirectoryNodeHdr.ContentIndex);
2489 // Re-insert the directory entry
2492 AFSInsertDirectoryNode( pTargetParentObject,
2493 pSrcCcb->DirectoryCB,
2497 // Update the parent pointer in the source object if they are different
2500 if( pSrcCcb->DirectoryCB->ObjectInformation->ParentObjectInformation != pTargetParentObject)
2503 InterlockedDecrement( &pSrcCcb->DirectoryCB->ObjectInformation->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);
2505 InterlockedDecrement( &pSrcCcb->DirectoryCB->ObjectInformation->ParentObjectInformation->Specific.Directory.ChildOpenReferenceCount);
2507 InterlockedIncrement( &pTargetParentObject->Specific.Directory.ChildOpenHandleCount);
2509 InterlockedIncrement( &pTargetParentObject->Specific.Directory.ChildOpenReferenceCount);
2511 pSrcCcb->DirectoryCB->ObjectInformation->ParentObjectInformation = pTargetParentObject;
2513 ulNotificationAction = FILE_ACTION_ADDED;
2518 ulNotificationAction = FILE_ACTION_RENAMED_NEW_NAME;
2522 // Now update the notification for the target file
2525 AFSFsRtlNotifyFullReportChange( pTargetParentObject->ParentObjectInformation,
2527 (ULONG)ulNotifyFilter,
2528 (ULONG)ulNotificationAction);
2531 // If we performed the rename of the target because it existed, we now need to
2532 // delete the tmp target we created above
2535 if( bTargetEntryExists)
2538 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2539 AFS_TRACE_LEVEL_VERBOSE,
2540 "AFSSetRenameInfo Setting DELETE flag in dir entry %p name %wZ\n",
2542 &pTargetDirEntry->NameInformation.FileName);
2544 SetFlag( pTargetDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
2547 // Try and purge the cache map if this is a file
2550 if( pTargetDirEntry->ObjectInformation->FileType == AFS_FILE_TYPE_FILE &&
2551 pTargetDirEntry->ObjectInformation->Fcb != NULL &&
2552 pTargetDirEntry->OpenReferenceCount > 1)
2555 pTargetFcb = pTargetDirEntry->ObjectInformation->Fcb;
2557 AFSAcquireExcl( &pTargetFcb->NPFcb->Resource,
2561 // Close the section in the event it was mapped
2564 if( !MmForceSectionClosed( &pTargetFcb->NPFcb->SectionObjectPointers,
2568 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2569 AFS_TRACE_LEVEL_ERROR,
2570 "AFSSetRenameInfo Failed to delete section for target file %wZ\n",
2571 &pTargetDirEntry->NameInformation.FileName);
2574 AFSReleaseResource( &pTargetFcb->NPFcb->Resource);
2577 ASSERT( pTargetDirEntry->OpenReferenceCount > 0);
2579 InterlockedDecrement( &pTargetDirEntry->OpenReferenceCount); // The count we added above
2581 if( pTargetDirEntry->OpenReferenceCount == 0)
2584 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2585 AFS_TRACE_LEVEL_VERBOSE,
2586 "AFSSetRenameInfo Deleting dir entry %p name %wZ\n",
2588 &pTargetDirEntry->NameInformation.FileName);
2590 AFSDeleteDirEntry( pTargetParentObject,
2594 pTargetDirEntry = NULL;
2600 if( !NT_SUCCESS( ntStatus))
2603 if( bTargetEntryExists)
2605 AFSInsertDirectoryNode( pTargetDirEntry->ObjectInformation->ParentObjectInformation,
2611 if( pTargetDirEntry != NULL)
2614 InterlockedDecrement( &pTargetDirEntry->OpenReferenceCount);
2617 if( bReleaseVolumeLock)
2619 AFSReleaseResource( pTargetParentObject->VolumeCB->VolumeLock);
2622 if( bReleaseTargetDirLock)
2624 AFSReleaseResource( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
2627 if( bReleaseSourceDirLock)
2629 AFSReleaseResource( pSourceDirLock);
2637 AFSSetPositionInfo( IN PIRP Irp,
2638 IN AFSDirectoryCB *DirectoryCB)
2640 NTSTATUS ntStatus = STATUS_SUCCESS;
2641 PFILE_POSITION_INFORMATION pBuffer;
2642 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2644 pBuffer = (PFILE_POSITION_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
2646 pIrpSp->FileObject->CurrentByteOffset.QuadPart = pBuffer->CurrentByteOffset.QuadPart;
2652 AFSSetAllocationInfo( IN PIRP Irp,
2653 IN AFSDirectoryCB *DirectoryCB)
2655 NTSTATUS ntStatus = STATUS_SUCCESS;
2656 PFILE_ALLOCATION_INFORMATION pBuffer;
2657 BOOLEAN bReleasePaging = FALSE;
2658 BOOLEAN bTellCc = FALSE;
2659 BOOLEAN bTellService = FALSE;
2660 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2661 PFILE_OBJECT pFileObject = pIrpSp->FileObject;
2662 AFSFcb *pFcb = NULL;
2663 AFSCcb *pCcb = NULL;
2664 LARGE_INTEGER liSaveAlloc;
2665 LARGE_INTEGER liSaveFileSize;
2666 LARGE_INTEGER liSaveVDL;
2668 pBuffer = (PFILE_ALLOCATION_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
2670 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
2672 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
2675 // save values to put back
2677 liSaveAlloc = pFcb->Header.AllocationSize;
2678 liSaveFileSize = pFcb->Header.FileSize;
2679 liSaveVDL = pFcb->Header.ValidDataLength;
2681 if( pFcb->Header.AllocationSize.QuadPart == pBuffer->AllocationSize.QuadPart ||
2682 pIrpSp->Parameters.SetFile.AdvanceOnly)
2684 return STATUS_SUCCESS ;
2687 if( pFcb->Header.AllocationSize.QuadPart > pBuffer->AllocationSize.QuadPart)
2690 // Truncating the file
2692 if( !MmCanFileBeTruncated( pFileObject->SectionObjectPointer,
2693 &pBuffer->AllocationSize))
2696 ntStatus = STATUS_USER_MAPPED_FILE ;
2701 // If this is a truncation we need to grab the paging IO resource.
2703 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2704 AFS_TRACE_LEVEL_VERBOSE,
2705 "AFSSetAllocationInfo Acquiring Fcb PagingIo lock %08lX EXCL %08lX\n",
2706 &pFcb->NPFcb->PagingResource,
2707 PsGetCurrentThread());
2709 AFSAcquireExcl( &pFcb->NPFcb->PagingResource,
2712 bReleasePaging = TRUE;
2715 pFcb->Header.AllocationSize = pBuffer->AllocationSize;
2717 pFcb->ObjectInformation->AllocationSize = pBuffer->AllocationSize;
2720 // Tell Cc that Allocation is moved.
2724 if( pFcb->Header.FileSize.QuadPart > pBuffer->AllocationSize.QuadPart)
2727 // We are pulling the EOF back as well so we need to tell
2730 bTellService = TRUE;
2732 pFcb->Header.FileSize = pBuffer->AllocationSize;
2734 pFcb->ObjectInformation->EndOfFile = pBuffer->AllocationSize;
2742 // Tell Cc if allocation is increased.
2744 bTellCc = pBuffer->AllocationSize.QuadPart > pFcb->Header.AllocationSize.QuadPart;
2746 pFcb->Header.AllocationSize = pBuffer->AllocationSize;
2748 pFcb->ObjectInformation->AllocationSize = pBuffer->AllocationSize;
2752 // Now Tell the server if we have to
2756 ntStatus = AFSUpdateFileInformation( &pFcb->ObjectInformation->ParentObjectInformation->FileId,
2757 pFcb->ObjectInformation,
2761 if (NT_SUCCESS(ntStatus))
2764 // Trim extents if we told the service - the update has done an implicit
2765 // trim at the service.
2769 AFSTrimExtents( pFcb,
2770 &pFcb->Header.FileSize);
2773 KeQuerySystemTime( &pFcb->ObjectInformation->ChangeTime);
2775 SetFlag( pFcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_CHANGE_TIME);
2778 CcIsFileCached( pFileObject))
2780 CcSetFileSizes( pFileObject,
2781 (PCC_FILE_SIZES)&pFcb->Header.AllocationSize);
2787 // Put the saved values back
2789 pFcb->Header.ValidDataLength = liSaveVDL;
2790 pFcb->Header.FileSize = liSaveFileSize;
2791 pFcb->Header.AllocationSize = liSaveAlloc;
2792 pFcb->ObjectInformation->EndOfFile = liSaveFileSize;
2793 pFcb->ObjectInformation->AllocationSize = liSaveAlloc;
2799 AFSReleaseResource( &pFcb->NPFcb->PagingResource);
2806 AFSSetEndOfFileInfo( IN PIRP Irp,
2807 IN AFSDirectoryCB *DirectoryCB)
2809 NTSTATUS ntStatus = STATUS_SUCCESS;
2810 PFILE_END_OF_FILE_INFORMATION pBuffer;
2811 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2812 PFILE_OBJECT pFileObject = pIrpSp->FileObject;
2813 LARGE_INTEGER liSaveSize;
2814 LARGE_INTEGER liSaveVDL;
2815 LARGE_INTEGER liSaveAlloc;
2816 BOOLEAN bModified = FALSE;
2817 BOOLEAN bReleasePaging = FALSE;
2818 BOOLEAN bTruncated = FALSE;
2819 AFSFcb *pFcb = NULL;
2820 AFSCcb *pCcb = NULL;
2822 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
2824 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
2826 pBuffer = (PFILE_END_OF_FILE_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
2828 liSaveSize = pFcb->Header.FileSize;
2829 liSaveAlloc = pFcb->Header.AllocationSize;
2830 liSaveVDL = pFcb->Header.ValidDataLength;
2832 if( pFcb->Header.FileSize.QuadPart != pBuffer->EndOfFile.QuadPart &&
2833 !pIrpSp->Parameters.SetFile.AdvanceOnly)
2836 if( pBuffer->EndOfFile.QuadPart < pFcb->Header.FileSize.QuadPart)
2839 // Truncating the file
2840 if( !MmCanFileBeTruncated( pFileObject->SectionObjectPointer,
2841 &pBuffer->EndOfFile))
2844 ntStatus = STATUS_USER_MAPPED_FILE;
2849 // If this is a truncation we need to grab the paging
2852 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2853 AFS_TRACE_LEVEL_VERBOSE,
2854 "AFSSetAllocationInfo Acquiring Fcb PagingIo lock %08lX EXCL %08lX\n",
2855 &pFcb->NPFcb->PagingResource,
2856 PsGetCurrentThread());
2858 AFSAcquireExcl( &pFcb->NPFcb->PagingResource,
2861 bReleasePaging = TRUE;
2863 pFcb->Header.AllocationSize = pBuffer->EndOfFile;
2865 pFcb->Header.FileSize = pBuffer->EndOfFile;
2867 pFcb->ObjectInformation->EndOfFile = pBuffer->EndOfFile;
2869 pFcb->ObjectInformation->AllocationSize = pBuffer->EndOfFile;
2871 if( pFcb->Header.ValidDataLength.QuadPart > pFcb->Header.FileSize.QuadPart)
2874 pFcb->Header.ValidDataLength = pFcb->Header.FileSize;
2885 // extending the file, move EOF
2888 pFcb->Header.FileSize = pBuffer->EndOfFile;
2890 pFcb->ObjectInformation->EndOfFile = pBuffer->EndOfFile;
2892 if (pFcb->Header.FileSize.QuadPart > pFcb->Header.AllocationSize.QuadPart)
2895 // And Allocation as needed.
2897 pFcb->Header.AllocationSize = pBuffer->EndOfFile;
2899 pFcb->ObjectInformation->AllocationSize = pBuffer->EndOfFile;
2909 KeQuerySystemTime( &pFcb->ObjectInformation->ChangeTime);
2911 SetFlag( pFcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_CHANGE_TIME);
2917 ntStatus = AFSUpdateFileInformation( &pFcb->ObjectInformation->ParentObjectInformation->FileId,
2918 pFcb->ObjectInformation,
2921 if( NT_SUCCESS(ntStatus))
2924 // We are now good to go so tell CC.
2926 CcSetFileSizes( pFileObject,
2927 (PCC_FILE_SIZES)&pFcb->Header.AllocationSize);
2930 // And give up those extents
2935 AFSTrimExtents( pFcb,
2936 &pFcb->Header.FileSize);
2941 pFcb->Header.ValidDataLength = liSaveVDL;
2942 pFcb->Header.FileSize = liSaveSize;
2943 pFcb->Header.AllocationSize = liSaveAlloc;
2944 pFcb->ObjectInformation->EndOfFile = liSaveSize;
2945 pFcb->ObjectInformation->AllocationSize = liSaveAlloc;
2952 AFSReleaseResource( &pFcb->NPFcb->PagingResource);
2959 AFSProcessShareSetInfo( IN IRP *Irp,
2964 NTSTATUS ntStatus = STATUS_SUCCESS;
2965 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2966 ULONG ulOutputBufferLen = 0, ulInputBufferLen;
2967 FILE_INFORMATION_CLASS ulFileInformationClass;
2968 void *pPipeInfo = NULL;
2972 ulFileInformationClass = pIrpSp->Parameters.SetFile.FileInformationClass;
2974 AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
2975 AFS_TRACE_LEVEL_VERBOSE,
2976 "AFSProcessShareSetInfo On pipe %wZ Class %08lX\n",
2977 &Ccb->DirectoryCB->NameInformation.FileName,
2978 ulFileInformationClass);
2980 pPipeInfo = AFSLockSystemBuffer( Irp,
2981 pIrpSp->Parameters.SetFile.Length);
2983 if( pPipeInfo == NULL)
2986 AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
2987 AFS_TRACE_LEVEL_ERROR,
2988 "AFSProcessShareSetInfo Failed to lock buffer on pipe %wZ\n",
2989 &Ccb->DirectoryCB->NameInformation.FileName);
2991 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2995 // Send the request to the service
2998 ntStatus = AFSNotifySetPipeInfo( Ccb,
2999 (ULONG)ulFileInformationClass,
3000 pIrpSp->Parameters.SetFile.Length,
3003 if( !NT_SUCCESS( ntStatus))
3006 AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
3007 AFS_TRACE_LEVEL_ERROR,
3008 "AFSProcessShareSetInfo Failed to send request to service on pipe %wZ Status %08lX\n",
3009 &Ccb->DirectoryCB->NameInformation.FileName,
3012 try_return( ntStatus);
3015 AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
3016 AFS_TRACE_LEVEL_VERBOSE,
3017 "AFSProcessShareSetInfo Completed request on pipe %wZ Class %08lX\n",
3018 &Ccb->DirectoryCB->NameInformation.FileName,
3019 ulFileInformationClass);
3030 AFSProcessShareQueryInfo( IN IRP *Irp,
3035 NTSTATUS ntStatus = STATUS_SUCCESS;
3036 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
3037 ULONG ulOutputBufferLen = 0, ulInputBufferLen;
3038 FILE_INFORMATION_CLASS ulFileInformationClass;
3039 void *pPipeInfo = NULL;
3044 ulFileInformationClass = pIrpSp->Parameters.QueryFile.FileInformationClass;
3046 AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
3047 AFS_TRACE_LEVEL_VERBOSE,
3048 "AFSProcessShareQueryInfo On pipe %wZ Class %08lX\n",
3049 &Ccb->DirectoryCB->NameInformation.FileName,
3050 ulFileInformationClass);
3052 pPipeInfo = AFSLockSystemBuffer( Irp,
3053 pIrpSp->Parameters.QueryFile.Length);
3055 if( pPipeInfo == NULL)
3058 AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
3059 AFS_TRACE_LEVEL_ERROR,
3060 "AFSProcessShareQueryInfo Failed to lock buffer on pipe %wZ\n",
3061 &Ccb->DirectoryCB->NameInformation.FileName);
3063 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
3067 // Send the request to the service
3070 ntStatus = AFSNotifyQueryPipeInfo( Ccb,
3071 (ULONG)ulFileInformationClass,
3072 pIrpSp->Parameters.QueryFile.Length,
3074 (ULONG *)&Irp->IoStatus.Information);
3076 if( !NT_SUCCESS( ntStatus))
3079 AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
3080 AFS_TRACE_LEVEL_ERROR,
3081 "AFSProcessShareQueryInfo Failed to send request to service on pipe %wZ Status %08lX\n",
3082 &Ccb->DirectoryCB->NameInformation.FileName,
3085 try_return( ntStatus);
3088 AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
3089 AFS_TRACE_LEVEL_VERBOSE,
3090 "AFSProcessShareQueryInfo Completed request on pipe %wZ Class %08lX\n",
3091 &Ccb->DirectoryCB->NameInformation.FileName,
3092 ulFileInformationClass);
3103 AFSProcessPIOCtlQueryInfo( IN IRP *Irp,
3106 IN OUT LONG *Length)
3109 NTSTATUS ntStatus = STATUS_SUCCESS;
3110 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
3111 FILE_INFORMATION_CLASS ulFileInformationClass;
3116 ulFileInformationClass = pIrpSp->Parameters.QueryFile.FileInformationClass;
3118 switch( ulFileInformationClass)
3121 case FileBasicInformation:
3124 if ( *Length >= sizeof( FILE_BASIC_INFORMATION))
3126 PFILE_BASIC_INFORMATION pBasic = (PFILE_BASIC_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
3128 pBasic->CreationTime.QuadPart = 0;
3129 pBasic->LastAccessTime.QuadPart = 0;
3130 pBasic->ChangeTime.QuadPart = 0;
3131 pBasic->LastWriteTime.QuadPart = 0;
3132 pBasic->FileAttributes = FILE_ATTRIBUTE_SYSTEM;
3134 *Length -= sizeof( FILE_BASIC_INFORMATION);
3138 ntStatus = STATUS_BUFFER_OVERFLOW;
3144 case FileStandardInformation:
3147 if ( *Length >= sizeof( FILE_STANDARD_INFORMATION))
3149 PFILE_STANDARD_INFORMATION pStandard = (PFILE_STANDARD_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
3151 pStandard->NumberOfLinks = 1;
3152 pStandard->DeletePending = 0;
3153 pStandard->AllocationSize.QuadPart = 4096;
3154 pStandard->EndOfFile.QuadPart = 4096;
3155 pStandard->Directory = 0;
3157 *Length -= sizeof( FILE_STANDARD_INFORMATION);
3161 ntStatus = STATUS_BUFFER_OVERFLOW;
3167 case FileNameInformation:
3170 ULONG ulCopyLength = 0;
3171 AFSFcb *pFcb = NULL;
3172 AFSCcb *pCcb = NULL;
3173 USHORT usFullNameLength = 0;
3174 PFILE_NAME_INFORMATION pNameInfo = (PFILE_NAME_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
3175 UNICODE_STRING uniName;
3177 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
3178 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
3180 if( *Length < FIELD_OFFSET( FILE_NAME_INFORMATION, FileName))
3182 ntStatus = STATUS_BUFFER_TOO_SMALL;
3186 RtlZeroMemory( pNameInfo,
3189 usFullNameLength = sizeof( WCHAR) +
3190 AFSServerName.Length +
3191 pCcb->FullFileName.Length;
3193 if( *Length >= (LONG)(FIELD_OFFSET( FILE_NAME_INFORMATION, FileName) + (LONG)usFullNameLength))
3195 ulCopyLength = (LONG)usFullNameLength;
3199 ulCopyLength = *Length - FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
3200 ntStatus = STATUS_BUFFER_OVERFLOW;
3203 pNameInfo->FileNameLength = (ULONG)usFullNameLength;
3205 *Length -= FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
3207 if( ulCopyLength > 0)
3210 pNameInfo->FileName[ 0] = L'\\';
3211 ulCopyLength -= sizeof( WCHAR);
3213 *Length -= sizeof( WCHAR);
3215 if( ulCopyLength >= AFSServerName.Length)
3218 RtlCopyMemory( &pNameInfo->FileName[ 1],
3219 AFSServerName.Buffer,
3220 AFSServerName.Length);
3222 ulCopyLength -= AFSServerName.Length;
3223 *Length -= AFSServerName.Length;
3225 if( ulCopyLength >= pCcb->FullFileName.Length)
3228 RtlCopyMemory( &pNameInfo->FileName[ 1 + (AFSServerName.Length/sizeof( WCHAR))],
3229 pCcb->FullFileName.Buffer,
3230 pCcb->FullFileName.Length);
3232 ulCopyLength -= pCcb->FullFileName.Length;
3233 *Length -= pCcb->FullFileName.Length;
3235 uniName.Length = (USHORT)pNameInfo->FileNameLength;
3236 uniName.MaximumLength = uniName.Length;
3237 uniName.Buffer = pNameInfo->FileName;
3242 RtlCopyMemory( &pNameInfo->FileName[ 1 + (AFSServerName.Length/sizeof( WCHAR))],
3243 pCcb->FullFileName.Buffer,
3246 *Length -= ulCopyLength;
3248 uniName.Length = (USHORT)(sizeof( WCHAR) + AFSServerName.Length + ulCopyLength);
3249 uniName.MaximumLength = uniName.Length;
3250 uniName.Buffer = pNameInfo->FileName;
3253 AFSDbgLogMsg( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
3254 AFS_TRACE_LEVEL_VERBOSE,
3255 "AFSProcessPIOCtlQueryInfo (FileNameInformation) Returning %wZ\n",
3263 case FileInternalInformation:
3266 PFILE_INTERNAL_INFORMATION pInternalInfo = (PFILE_INTERNAL_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
3268 if( *Length >= sizeof( FILE_INTERNAL_INFORMATION))
3271 pInternalInfo->IndexNumber.HighPart = 0;
3273 pInternalInfo->IndexNumber.LowPart = 0;
3275 *Length -= sizeof( FILE_INTERNAL_INFORMATION);
3280 ntStatus = STATUS_BUFFER_TOO_SMALL;
3288 ntStatus = STATUS_INVALID_PARAMETER;
3290 AFSDbgLogMsg( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
3291 AFS_TRACE_LEVEL_WARNING,
3292 "AFSProcessPIOCtlQueryInfo Not handling request %08lX\n",
3293 ulFileInformationClass);