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,
388 ntStatus = STATUS_INVALID_PARAMETER;
395 Irp->IoStatus.Information = pIrpSp->Parameters.QueryFile.Length - lLength;
400 AFSReleaseResource( &pFcb->NPFcb->Resource);
403 if( !NT_SUCCESS( ntStatus) &&
404 ntStatus != STATUS_INVALID_PARAMETER &&
405 ntStatus != STATUS_BUFFER_OVERFLOW)
409 pCcb->DirectoryCB != NULL)
412 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
413 AFS_TRACE_LEVEL_ERROR,
414 "AFSQueryFileInfo Failed to process request for %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
415 &pCcb->DirectoryCB->NameInformation.FileName,
416 pCcb->DirectoryCB->ObjectInformation->FileId.Cell,
417 pCcb->DirectoryCB->ObjectInformation->FileId.Volume,
418 pCcb->DirectoryCB->ObjectInformation->FileId.Vnode,
419 pCcb->DirectoryCB->ObjectInformation->FileId.Unique,
424 __except( AFSExceptionFilter( GetExceptionCode(), GetExceptionInformation()) )
429 "EXCEPTION - AFSQueryFileInfo\n");
431 ntStatus = STATUS_UNSUCCESSFUL;
436 AFSReleaseResource( &pFcb->NPFcb->Resource);
440 AFSCompleteRequest( Irp,
447 // Function: AFSSetFileInfo
451 // This function is the dispatch handler for the IRP_MJ_SET_FILE_INFORMATION request
455 // A status is returned for the function
459 AFSSetFileInfo( IN PDEVICE_OBJECT LibDeviceObject,
463 NTSTATUS ntStatus = STATUS_SUCCESS;
464 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
465 IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
468 BOOLEAN bCompleteRequest = TRUE;
469 FILE_INFORMATION_CLASS FileInformationClass;
470 BOOLEAN bCanQueueRequest = FALSE;
471 PFILE_OBJECT pFileObject = NULL;
472 BOOLEAN bReleaseMain = FALSE;
473 BOOLEAN bUpdateFileInfo = FALSE;
474 AFSFileID stParentFileId;
479 pFileObject = pIrpSp->FileObject;
481 pFcb = (AFSFcb *)pFileObject->FsContext;
482 pCcb = (AFSCcb *)pFileObject->FsContext2;
487 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
488 AFS_TRACE_LEVEL_ERROR,
489 "AFSSetFileInfo Attempted access (%08lX) when pFcb == NULL\n",
492 try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST);
495 bCanQueueRequest = !(IoIsOperationSynchronous( Irp) | (KeGetCurrentIrql() != PASSIVE_LEVEL));
496 FileInformationClass = pIrpSp->Parameters.SetFile.FileInformationClass;
502 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
503 AFS_TRACE_LEVEL_VERBOSE,
504 "AFSSetFileInfo Acquiring Fcb lock %08lX EXCL %08lX\n",
505 &pFcb->NPFcb->Resource,
506 PsGetCurrentThread());
508 AFSAcquireExcl( &pFcb->NPFcb->Resource,
514 // Don't allow requests against IOCtl nodes
517 if( pFcb->Header.NodeTypeCode == AFS_IOCTL_FCB)
520 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
521 AFS_TRACE_LEVEL_ERROR,
522 "AFSSetFileInfo Failing request against PIOCtl Fcb\n");
524 try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST);
526 else if( pFcb->Header.NodeTypeCode == AFS_SPECIAL_SHARE_FCB)
529 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
530 AFS_TRACE_LEVEL_VERBOSE,
531 "AFSSetFileInfo Processing request against SpecialShare Fcb\n");
533 ntStatus = AFSProcessShareSetInfo( Irp,
537 try_return( ntStatus);
540 if( BooleanFlagOn( pFcb->ObjectInformation->VolumeCB->VolumeInformation.Characteristics, FILE_READ_ONLY_DEVICE))
543 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
544 AFS_TRACE_LEVEL_ERROR,
545 "AFSSetFileInfo Request failed due to read only volume\n",
548 try_return( ntStatus = STATUS_ACCESS_DENIED);
552 // Ensure rename operations are synchronous
555 if( FileInformationClass == FileRenameInformation)
558 bCanQueueRequest = FALSE;
562 // Store away the parent fid
565 RtlZeroMemory( &stParentFileId,
568 if( pFcb->ObjectInformation->ParentObjectInformation != NULL)
570 stParentFileId = pFcb->ObjectInformation->ParentObjectInformation->FileId;
574 // Process the request
577 switch( FileInformationClass)
580 case FileBasicInformation:
583 bUpdateFileInfo = TRUE;
585 ntStatus = AFSSetBasicInfo( Irp,
591 case FileDispositionInformation:
594 ntStatus = AFSSetDispositionInfo( Irp,
600 case FileRenameInformation:
603 ntStatus = AFSSetRenameInfo( Irp);
608 case FilePositionInformation:
611 ntStatus = AFSSetPositionInfo( Irp,
617 case FileLinkInformation:
620 ntStatus = STATUS_INVALID_DEVICE_REQUEST;
625 case FileAllocationInformation:
628 ntStatus = AFSSetAllocationInfo( Irp,
634 case FileEndOfFileInformation:
637 ntStatus = AFSSetEndOfFileInfo( Irp,
645 ntStatus = STATUS_INVALID_PARAMETER;
655 AFSReleaseResource( &pFcb->NPFcb->Resource);
658 if( NT_SUCCESS( ntStatus) &&
662 ntStatus = AFSUpdateFileInformation( &stParentFileId,
663 pFcb->ObjectInformation,
666 if( !NT_SUCCESS( ntStatus))
669 AFSAcquireExcl( &pFcb->NPFcb->Resource,
673 // Unwind the update and fail the request
676 AFSUnwindFileInfo( pFcb,
679 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
680 AFS_TRACE_LEVEL_ERROR,
681 "AFSSetFileInfo Failed to send file info update to service request for %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
682 &pCcb->DirectoryCB->NameInformation.FileName,
683 pCcb->DirectoryCB->ObjectInformation->FileId.Cell,
684 pCcb->DirectoryCB->ObjectInformation->FileId.Volume,
685 pCcb->DirectoryCB->ObjectInformation->FileId.Vnode,
686 pCcb->DirectoryCB->ObjectInformation->FileId.Unique,
689 AFSReleaseResource( &pFcb->NPFcb->Resource);
693 if( !NT_SUCCESS( ntStatus))
697 pCcb->DirectoryCB != NULL)
700 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
701 AFS_TRACE_LEVEL_ERROR,
702 "AFSSetFileInfo Failed to process request for %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
703 &pCcb->DirectoryCB->NameInformation.FileName,
704 pCcb->DirectoryCB->ObjectInformation->FileId.Cell,
705 pCcb->DirectoryCB->ObjectInformation->FileId.Volume,
706 pCcb->DirectoryCB->ObjectInformation->FileId.Vnode,
707 pCcb->DirectoryCB->ObjectInformation->FileId.Unique,
712 __except( AFSExceptionFilter( GetExceptionCode(), GetExceptionInformation()) )
717 "EXCEPTION - AFSSetFileInfo\n");
719 ntStatus = STATUS_UNSUCCESSFUL;
722 AFSCompleteRequest( Irp,
729 // Function: AFSQueryBasicInfo
733 // This function is the handler for the query basic information request
737 // A status is returned for the function
741 AFSQueryBasicInfo( IN PIRP Irp,
742 IN AFSDirectoryCB *DirectoryCB,
743 IN OUT PFILE_BASIC_INFORMATION Buffer,
746 NTSTATUS ntStatus = STATUS_SUCCESS;
747 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
749 if( *Length >= sizeof( FILE_BASIC_INFORMATION))
752 RtlZeroMemory( Buffer,
755 Buffer->CreationTime = DirectoryCB->ObjectInformation->CreationTime;
756 Buffer->LastAccessTime = DirectoryCB->ObjectInformation->LastAccessTime;
757 Buffer->LastWriteTime = DirectoryCB->ObjectInformation->LastWriteTime;
758 Buffer->ChangeTime = DirectoryCB->ObjectInformation->ChangeTime;
759 Buffer->FileAttributes = DirectoryCB->ObjectInformation->FileAttributes;
761 if( DirectoryCB->NameInformation.FileName.Buffer[ 0] == L'.' &&
762 BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_HIDE_DOT_NAMES))
765 if ( Buffer->FileAttributes != FILE_ATTRIBUTE_NORMAL)
768 Buffer->FileAttributes |= FILE_ATTRIBUTE_HIDDEN;
773 Buffer->FileAttributes = FILE_ATTRIBUTE_HIDDEN;
777 *Length -= sizeof( FILE_BASIC_INFORMATION);
782 ntStatus = STATUS_BUFFER_TOO_SMALL;
789 AFSQueryStandardInfo( IN PIRP Irp,
790 IN AFSDirectoryCB *DirectoryCB,
791 IN OUT PFILE_STANDARD_INFORMATION Buffer,
795 NTSTATUS ntStatus = STATUS_SUCCESS;
796 AFSFileInfoCB stFileInformation;
798 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
800 if( *Length >= sizeof( FILE_STANDARD_INFORMATION))
803 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
805 RtlZeroMemory( Buffer,
808 Buffer->NumberOfLinks = 1;
809 Buffer->DeletePending = BooleanFlagOn( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
811 RtlZeroMemory( &stFileInformation,
812 sizeof( AFSFileInfoCB));
814 Buffer->AllocationSize.QuadPart = (ULONGLONG)((DirectoryCB->ObjectInformation->AllocationSize.QuadPart/PAGE_SIZE) + 1) * PAGE_SIZE;
816 Buffer->EndOfFile = DirectoryCB->ObjectInformation->EndOfFile;
818 Buffer->Directory = BooleanFlagOn( DirectoryCB->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_DIRECTORY);
820 *Length -= sizeof( FILE_STANDARD_INFORMATION);
825 ntStatus = STATUS_BUFFER_TOO_SMALL;
832 AFSQueryInternalInfo( IN PIRP Irp,
834 IN OUT PFILE_INTERNAL_INFORMATION Buffer,
838 NTSTATUS ntStatus = STATUS_SUCCESS;
840 if( *Length >= sizeof( FILE_INTERNAL_INFORMATION))
843 Buffer->IndexNumber.HighPart = Fcb->ObjectInformation->FileId.Volume;
845 Buffer->IndexNumber.LowPart = Fcb->ObjectInformation->FileId.Vnode;
847 *Length -= sizeof( FILE_INTERNAL_INFORMATION);
852 ntStatus = STATUS_BUFFER_TOO_SMALL;
859 AFSQueryEaInfo( IN PIRP Irp,
860 IN AFSDirectoryCB *DirectoryCB,
861 IN OUT PFILE_EA_INFORMATION Buffer,
865 NTSTATUS ntStatus = STATUS_SUCCESS;
867 RtlZeroMemory( Buffer,
870 if( *Length >= sizeof( FILE_EA_INFORMATION))
875 *Length -= sizeof( FILE_EA_INFORMATION);
880 ntStatus = STATUS_BUFFER_TOO_SMALL;
887 AFSQueryPositionInfo( IN PIRP Irp,
889 IN OUT PFILE_POSITION_INFORMATION Buffer,
893 NTSTATUS ntStatus = STATUS_SUCCESS;
894 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
896 if( *Length >= sizeof( FILE_POSITION_INFORMATION))
899 RtlZeroMemory( Buffer,
902 Buffer->CurrentByteOffset.QuadPart = pIrpSp->FileObject->CurrentByteOffset.QuadPart;
904 *Length -= sizeof( FILE_POSITION_INFORMATION);
909 ntStatus = STATUS_BUFFER_TOO_SMALL;
916 AFSQueryAccess( IN PIRP Irp,
918 IN OUT PFILE_ACCESS_INFORMATION Buffer,
922 NTSTATUS ntStatus = STATUS_SUCCESS;
924 if( *Length >= sizeof( FILE_ACCESS_INFORMATION))
927 RtlZeroMemory( Buffer,
930 Buffer->AccessFlags = 0;
932 *Length -= sizeof( FILE_ACCESS_INFORMATION);
937 ntStatus = STATUS_BUFFER_TOO_SMALL;
944 AFSQueryMode( IN PIRP Irp,
946 IN OUT PFILE_MODE_INFORMATION Buffer,
950 NTSTATUS ntStatus = STATUS_SUCCESS;
952 if( *Length >= sizeof( FILE_MODE_INFORMATION))
955 RtlZeroMemory( Buffer,
960 *Length -= sizeof( FILE_MODE_INFORMATION);
965 ntStatus = STATUS_BUFFER_TOO_SMALL;
972 AFSQueryAlignment( IN PIRP Irp,
974 IN OUT PFILE_ALIGNMENT_INFORMATION Buffer,
978 NTSTATUS ntStatus = STATUS_SUCCESS;
980 if( *Length >= sizeof( FILE_ALIGNMENT_INFORMATION))
983 RtlZeroMemory( Buffer,
986 Buffer->AlignmentRequirement = 1;
988 *Length -= sizeof( FILE_ALIGNMENT_INFORMATION);
993 ntStatus = STATUS_BUFFER_TOO_SMALL;
1000 AFSQueryNameInfo( IN PIRP Irp,
1001 IN AFSDirectoryCB *DirectoryCB,
1002 IN OUT PFILE_NAME_INFORMATION Buffer,
1003 IN OUT PLONG Length)
1006 NTSTATUS ntStatus = STATUS_SUCCESS;
1007 ULONG ulCopyLength = 0;
1008 ULONG cchCopied = 0;
1009 AFSFcb *pFcb = NULL;
1010 AFSCcb *pCcb = NULL;
1011 IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1012 BOOLEAN bAddLeadingSlash = FALSE;
1013 BOOLEAN bAddTrailingSlash = FALSE;
1014 USHORT usFullNameLength = 0;
1016 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
1018 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
1020 if( *Length >= FIELD_OFFSET( FILE_NAME_INFORMATION, FileName))
1023 RtlZeroMemory( Buffer,
1026 if( pCcb->FullFileName.Length == 0 ||
1027 pCcb->FullFileName.Buffer[ 0] != L'\\')
1029 bAddLeadingSlash = TRUE;
1032 if( pFcb->ObjectInformation->FileType == AFS_FILE_TYPE_DIRECTORY &&
1033 pCcb->FullFileName.Length > 0 &&
1034 pCcb->FullFileName.Buffer[ (pCcb->FullFileName.Length/sizeof( WCHAR)) - 1] != L'\\')
1036 bAddTrailingSlash = TRUE;
1039 usFullNameLength = sizeof( WCHAR) +
1040 AFSServerName.Length +
1041 pCcb->FullFileName.Length;
1043 if( bAddLeadingSlash)
1045 usFullNameLength += sizeof( WCHAR);
1048 if( bAddTrailingSlash)
1050 usFullNameLength += sizeof( WCHAR);
1053 if( *Length >= (LONG)(FIELD_OFFSET( FILE_NAME_INFORMATION, FileName) + (LONG)usFullNameLength))
1056 ulCopyLength = (LONG)usFullNameLength;
1061 ulCopyLength = *Length - FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
1063 ntStatus = STATUS_BUFFER_OVERFLOW;
1066 Buffer->FileNameLength = (ULONG)usFullNameLength;
1068 *Length -= FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
1070 if( ulCopyLength > 0)
1073 Buffer->FileName[ 0] = L'\\';
1074 ulCopyLength -= sizeof( WCHAR);
1076 *Length -= sizeof( WCHAR);
1079 if( ulCopyLength >= AFSServerName.Length)
1082 RtlCopyMemory( &Buffer->FileName[ 1],
1083 AFSServerName.Buffer,
1084 AFSServerName.Length);
1086 ulCopyLength -= AFSServerName.Length;
1087 *Length -= AFSServerName.Length;
1088 cchCopied += AFSServerName.Length/sizeof( WCHAR);
1090 if ( ulCopyLength > 0 &&
1094 Buffer->FileName[ cchCopied] = L'\\';
1096 ulCopyLength -= sizeof( WCHAR);
1097 *Length -= sizeof( WCHAR);
1101 if( ulCopyLength >= pCcb->FullFileName.Length)
1104 RtlCopyMemory( &Buffer->FileName[ cchCopied],
1105 pCcb->FullFileName.Buffer,
1106 pCcb->FullFileName.Length);
1108 ulCopyLength -= pCcb->FullFileName.Length;
1109 *Length -= pCcb->FullFileName.Length;
1110 cchCopied += pCcb->FullFileName.Length/sizeof( WCHAR);
1112 if( ulCopyLength > 0 &&
1115 Buffer->FileName[ cchCopied] = L'\\';
1117 *Length -= sizeof( WCHAR);
1123 RtlCopyMemory( &Buffer->FileName[ cchCopied],
1124 pCcb->FullFileName.Buffer,
1127 *Length -= ulCopyLength;
1135 ntStatus = STATUS_BUFFER_TOO_SMALL;
1142 AFSQueryShortNameInfo( IN PIRP Irp,
1143 IN AFSDirectoryCB *DirectoryCB,
1144 IN OUT PFILE_NAME_INFORMATION Buffer,
1145 IN OUT PLONG Length)
1148 NTSTATUS ntStatus = STATUS_BUFFER_TOO_SMALL;
1149 ULONG ulCopyLength = 0;
1151 RtlZeroMemory( Buffer,
1154 if( DirectoryCB->NameInformation.ShortNameLength == 0)
1158 // The short name IS the long name
1161 if( *Length >= (LONG)FIELD_OFFSET( FILE_NAME_INFORMATION, FileName))
1164 if( *Length >= (LONG)(FIELD_OFFSET( FILE_NAME_INFORMATION, FileName) + (LONG)DirectoryCB->NameInformation.FileName.Length))
1167 ulCopyLength = (LONG)DirectoryCB->NameInformation.FileName.Length;
1169 ntStatus = STATUS_SUCCESS;
1174 ulCopyLength = *Length - FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
1176 ntStatus = STATUS_BUFFER_OVERFLOW;
1179 Buffer->FileNameLength = DirectoryCB->NameInformation.FileName.Length;
1181 *Length -= FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
1183 if( ulCopyLength > 0)
1186 RtlCopyMemory( Buffer->FileName,
1187 DirectoryCB->NameInformation.FileName.Buffer,
1190 *Length -= ulCopyLength;
1197 if( *Length >= (LONG)FIELD_OFFSET( FILE_NAME_INFORMATION, FileName))
1200 if( *Length >= (LONG)(FIELD_OFFSET( FILE_NAME_INFORMATION, FileName) + (LONG)DirectoryCB->NameInformation.FileName.Length))
1203 ulCopyLength = (LONG)DirectoryCB->NameInformation.ShortNameLength;
1205 ntStatus = STATUS_SUCCESS;
1210 ulCopyLength = *Length - FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
1212 ntStatus = STATUS_BUFFER_OVERFLOW;
1215 Buffer->FileNameLength = DirectoryCB->NameInformation.ShortNameLength;
1217 *Length -= FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
1219 if( ulCopyLength > 0)
1222 RtlCopyMemory( Buffer->FileName,
1223 DirectoryCB->NameInformation.ShortName,
1224 Buffer->FileNameLength);
1226 *Length -= ulCopyLength;
1235 AFSQueryNetworkInfo( IN PIRP Irp,
1236 IN AFSDirectoryCB *DirectoryCB,
1237 IN OUT PFILE_NETWORK_OPEN_INFORMATION Buffer,
1238 IN OUT PLONG Length)
1241 NTSTATUS ntStatus = STATUS_SUCCESS;
1242 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1244 RtlZeroMemory( Buffer,
1247 if( *Length >= sizeof( FILE_NETWORK_OPEN_INFORMATION))
1250 Buffer->CreationTime.QuadPart = DirectoryCB->ObjectInformation->CreationTime.QuadPart;
1251 Buffer->LastAccessTime.QuadPart = DirectoryCB->ObjectInformation->LastAccessTime.QuadPart;
1252 Buffer->LastWriteTime.QuadPart = DirectoryCB->ObjectInformation->LastWriteTime.QuadPart;
1253 Buffer->ChangeTime.QuadPart = DirectoryCB->ObjectInformation->ChangeTime.QuadPart;
1255 Buffer->AllocationSize.QuadPart = DirectoryCB->ObjectInformation->AllocationSize.QuadPart;
1256 Buffer->EndOfFile.QuadPart = DirectoryCB->ObjectInformation->EndOfFile.QuadPart;
1258 Buffer->FileAttributes = DirectoryCB->ObjectInformation->FileAttributes;
1260 if( DirectoryCB->NameInformation.FileName.Buffer[ 0] == L'.' &&
1261 BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_HIDE_DOT_NAMES))
1264 if ( Buffer->FileAttributes != FILE_ATTRIBUTE_NORMAL)
1267 Buffer->FileAttributes |= FILE_ATTRIBUTE_HIDDEN;
1272 Buffer->FileAttributes = FILE_ATTRIBUTE_HIDDEN;
1276 *Length -= sizeof( FILE_NETWORK_OPEN_INFORMATION);
1281 ntStatus = STATUS_BUFFER_TOO_SMALL;
1288 AFSQueryStreamInfo( IN PIRP Irp,
1289 IN AFSDirectoryCB *DirectoryCB,
1290 IN OUT FILE_STREAM_INFORMATION *Buffer,
1291 IN OUT PLONG Length)
1294 NTSTATUS ntStatus = STATUS_BUFFER_TOO_SMALL;
1295 ULONG ulCopyLength = 0;
1296 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1298 if( *Length >= FIELD_OFFSET( FILE_STREAM_INFORMATION, StreamName))
1301 RtlZeroMemory( Buffer,
1304 Buffer->NextEntryOffset = 0;
1307 if( !BooleanFlagOn( DirectoryCB->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_DIRECTORY))
1310 if( *Length >= (LONG)(FIELD_OFFSET( FILE_STREAM_INFORMATION, StreamName) + 14)) // ::$DATA
1315 ntStatus = STATUS_SUCCESS;
1320 ulCopyLength = *Length - FIELD_OFFSET( FILE_STREAM_INFORMATION, StreamName);
1322 ntStatus = STATUS_BUFFER_OVERFLOW;
1325 Buffer->StreamNameLength = 14; // ::$DATA
1327 Buffer->StreamSize.QuadPart = DirectoryCB->ObjectInformation->EndOfFile.QuadPart;
1329 Buffer->StreamAllocationSize.QuadPart = DirectoryCB->ObjectInformation->AllocationSize.QuadPart;
1331 *Length -= FIELD_OFFSET( FILE_STREAM_INFORMATION, StreamName);
1333 if( ulCopyLength > 0)
1336 RtlCopyMemory( Buffer->StreamName,
1340 *Length -= ulCopyLength;
1346 Buffer->StreamNameLength = 0; // No stream for a directory
1348 // The response size is zero
1350 ntStatus = STATUS_SUCCESS;
1358 AFSQueryAttribTagInfo( IN PIRP Irp,
1359 IN AFSDirectoryCB *DirectoryCB,
1360 IN OUT FILE_ATTRIBUTE_TAG_INFORMATION *Buffer,
1361 IN OUT PLONG Length)
1364 NTSTATUS ntStatus = STATUS_BUFFER_TOO_SMALL;
1365 ULONG ulCopyLength = 0;
1366 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1368 if( *Length >= sizeof( FILE_ATTRIBUTE_TAG_INFORMATION))
1371 RtlZeroMemory( Buffer,
1374 Buffer->FileAttributes = DirectoryCB->ObjectInformation->FileAttributes;
1376 if( DirectoryCB->NameInformation.FileName.Buffer[ 0] == L'.' &&
1377 BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_HIDE_DOT_NAMES))
1380 if ( Buffer->FileAttributes != FILE_ATTRIBUTE_NORMAL)
1383 Buffer->FileAttributes |= FILE_ATTRIBUTE_HIDDEN;
1388 Buffer->FileAttributes = FILE_ATTRIBUTE_HIDDEN;
1392 if( BooleanFlagOn( DirectoryCB->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_REPARSE_POINT))
1394 Buffer->ReparseTag = IO_REPARSE_TAG_OPENAFS_DFS;
1397 *Length -= sizeof( FILE_ATTRIBUTE_TAG_INFORMATION);
1399 ntStatus = STATUS_SUCCESS;
1406 AFSQueryRemoteProtocolInfo( IN PIRP Irp,
1407 IN AFSDirectoryCB *DirectoryCB,
1408 IN OUT FILE_REMOTE_PROTOCOL_INFORMATION *Buffer,
1409 IN OUT PLONG Length)
1412 NTSTATUS ntStatus = STATUS_BUFFER_TOO_SMALL;
1413 ULONG ulCopyLength = 0;
1414 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1416 if( *Length >= sizeof( FILE_REMOTE_PROTOCOL_INFORMATION))
1419 RtlZeroMemory( Buffer,
1422 Buffer->StructureVersion = 1;
1424 Buffer->StructureSize = sizeof(FILE_REMOTE_PROTOCOL_INFORMATION);
1426 Buffer->Protocol = WNNC_NET_OPENAFS;
1428 Buffer->ProtocolMajorVersion = 3;
1430 Buffer->ProtocolMinorVersion = 0;
1432 Buffer->ProtocolRevision = 0;
1434 *Length -= sizeof( FILE_REMOTE_PROTOCOL_INFORMATION);
1436 ntStatus = STATUS_SUCCESS;
1443 AFSSetBasicInfo( IN PIRP Irp,
1444 IN AFSDirectoryCB *DirectoryCB)
1446 NTSTATUS ntStatus = STATUS_SUCCESS;
1447 PFILE_BASIC_INFORMATION pBuffer;
1448 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1449 ULONG ulNotifyFilter = 0;
1450 AFSCcb *pCcb = NULL;
1455 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
1457 pBuffer = (PFILE_BASIC_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
1459 pCcb->FileUnwindInfo.FileAttributes = (ULONG)-1;
1461 if( pBuffer->FileAttributes != (ULONGLONG)0)
1464 if( DirectoryCB->ObjectInformation->Fcb->Header.NodeTypeCode == AFS_FILE_FCB &&
1465 BooleanFlagOn( pBuffer->FileAttributes, FILE_ATTRIBUTE_DIRECTORY))
1468 try_return( ntStatus = STATUS_INVALID_PARAMETER);
1471 if( DirectoryCB->ObjectInformation->Fcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB)
1474 pBuffer->FileAttributes |= FILE_ATTRIBUTE_DIRECTORY;
1477 pCcb->FileUnwindInfo.FileAttributes = DirectoryCB->ObjectInformation->FileAttributes;
1479 DirectoryCB->ObjectInformation->FileAttributes = pBuffer->FileAttributes;
1481 ulNotifyFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
1483 SetFlag( DirectoryCB->ObjectInformation->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED);
1486 pCcb->FileUnwindInfo.CreationTime.QuadPart = (ULONGLONG)-1;
1488 if( pBuffer->CreationTime.QuadPart != (ULONGLONG)-1 &&
1489 pBuffer->CreationTime.QuadPart != (ULONGLONG)0)
1492 pCcb->FileUnwindInfo.CreationTime.QuadPart = DirectoryCB->ObjectInformation->CreationTime.QuadPart;
1494 DirectoryCB->ObjectInformation->CreationTime.QuadPart = pBuffer->CreationTime.QuadPart;
1496 ulNotifyFilter |= FILE_NOTIFY_CHANGE_CREATION;
1498 SetFlag( DirectoryCB->ObjectInformation->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_CREATE_TIME);
1501 pCcb->FileUnwindInfo.LastAccessTime.QuadPart = (ULONGLONG)-1;
1503 if( pBuffer->LastAccessTime.QuadPart != (ULONGLONG)-1 &&
1504 pBuffer->LastAccessTime.QuadPart != (ULONGLONG)0)
1507 pCcb->FileUnwindInfo.LastAccessTime.QuadPart = DirectoryCB->ObjectInformation->LastAccessTime.QuadPart;
1509 DirectoryCB->ObjectInformation->LastAccessTime.QuadPart = pBuffer->LastAccessTime.QuadPart;
1511 ulNotifyFilter |= FILE_NOTIFY_CHANGE_LAST_ACCESS;
1513 SetFlag( DirectoryCB->ObjectInformation->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_ACCESS_TIME);
1516 pCcb->FileUnwindInfo.LastWriteTime.QuadPart = (ULONGLONG)-1;
1518 if( pBuffer->LastWriteTime.QuadPart != (ULONGLONG)-1 &&
1519 pBuffer->LastWriteTime.QuadPart != (ULONGLONG)0)
1522 pCcb->FileUnwindInfo.LastWriteTime.QuadPart = DirectoryCB->ObjectInformation->LastWriteTime.QuadPart;
1524 DirectoryCB->ObjectInformation->LastWriteTime.QuadPart = pBuffer->LastWriteTime.QuadPart;
1526 ulNotifyFilter |= FILE_NOTIFY_CHANGE_LAST_WRITE;
1528 SetFlag( DirectoryCB->ObjectInformation->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_LAST_WRITE_TIME);
1531 pCcb->FileUnwindInfo.ChangeTime.QuadPart = (ULONGLONG)-1;
1533 if( pBuffer->ChangeTime.QuadPart != (ULONGLONG)-1 &&
1534 pBuffer->ChangeTime.QuadPart != (ULONGLONG)0)
1537 pCcb->FileUnwindInfo.ChangeTime.QuadPart = DirectoryCB->ObjectInformation->ChangeTime.QuadPart;
1539 DirectoryCB->ObjectInformation->ChangeTime.QuadPart = pBuffer->ChangeTime.QuadPart;
1541 ulNotifyFilter |= FILE_NOTIFY_CHANGE_LAST_ACCESS;
1543 SetFlag( DirectoryCB->ObjectInformation->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_CHANGE_TIME);
1546 if( ulNotifyFilter > 0)
1549 if( DirectoryCB->ObjectInformation->ParentObjectInformation != NULL)
1552 AFSFsRtlNotifyFullReportChange( DirectoryCB->ObjectInformation->ParentObjectInformation,
1554 (ULONG)ulNotifyFilter,
1555 (ULONG)FILE_ACTION_MODIFIED);
1568 AFSSetDispositionInfo( IN PIRP Irp,
1569 IN AFSDirectoryCB *DirectoryCB)
1571 NTSTATUS ntStatus = STATUS_SUCCESS;
1572 PFILE_DISPOSITION_INFORMATION pBuffer;
1573 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1574 AFSFcb *pFcb = NULL;
1575 AFSCcb *pCcb = NULL;
1580 pBuffer = (PFILE_DISPOSITION_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
1582 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
1584 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
1587 // Can't delete the root
1590 if( pFcb->Header.NodeTypeCode == AFS_ROOT_FCB)
1593 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1594 AFS_TRACE_LEVEL_ERROR,
1595 "AFSSetDispositionInfo Attempt to delete root entry\n");
1597 try_return( ntStatus = STATUS_CANNOT_DELETE);
1601 // If the file is read only then do not allow the delete
1604 if( BooleanFlagOn( DirectoryCB->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_READONLY))
1607 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1608 AFS_TRACE_LEVEL_ERROR,
1609 "AFSSetDispositionInfo Attempt to delete read only entry %wZ\n",
1610 &DirectoryCB->NameInformation.FileName);
1612 try_return( ntStatus = STATUS_CANNOT_DELETE);
1615 if( pBuffer->DeleteFile)
1619 // Check if the caller can delete the file
1622 ntStatus = AFSNotifyDelete( DirectoryCB,
1625 if( !NT_SUCCESS( ntStatus))
1628 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1629 AFS_TRACE_LEVEL_ERROR,
1630 "AFSSetDispositionInfo Cannot delete entry %wZ Status %08lX\n",
1631 &DirectoryCB->NameInformation.FileName,
1634 try_return( ntStatus);
1637 if( pFcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB)
1641 // Check if this is a directory that there are not currently other opens
1644 if( pFcb->ObjectInformation->Specific.Directory.ChildOpenHandleCount > 0)
1647 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1648 AFS_TRACE_LEVEL_ERROR,
1649 "AFSSetDispositionInfo Attempt to delete directory %wZ with open %u handles\n",
1650 &DirectoryCB->NameInformation.FileName,
1651 pFcb->ObjectInformation->Specific.Directory.ChildOpenHandleCount);
1653 try_return( ntStatus = STATUS_DIRECTORY_NOT_EMPTY);
1656 if( !AFSIsDirectoryEmptyForDelete( pFcb))
1659 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1660 AFS_TRACE_LEVEL_ERROR,
1661 "AFSSetDispositionInfo Attempt to delete non-empty directory %wZ\n",
1662 &DirectoryCB->NameInformation.FileName);
1664 try_return( ntStatus = STATUS_DIRECTORY_NOT_EMPTY);
1671 // Attempt to flush any outstanding data
1674 if( !MmFlushImageSection( &pFcb->NPFcb->SectionObjectPointers,
1678 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1679 AFS_TRACE_LEVEL_ERROR,
1680 "AFSSetDispositionInfo Failed to flush image section for delete Entry %wZ\n",
1681 &DirectoryCB->NameInformation.FileName);
1683 try_return( ntStatus = STATUS_CANNOT_DELETE);
1687 // Purge the cache as well
1690 if( pFcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
1693 CcPurgeCacheSection( &pFcb->NPFcb->SectionObjectPointers,
1700 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1701 AFS_TRACE_LEVEL_VERBOSE,
1702 "AFSSetDispositionInfo Setting PENDING_DELETE on DirEntry %p Name %wZ\n",
1704 &DirectoryCB->NameInformation.FileName);
1706 SetFlag( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
1711 ClearFlag( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
1715 // OK, should be good to go, set the flag in the file object
1718 pIrpSp->FileObject->DeletePending = pBuffer->DeleteFile;
1729 AFSSetRenameInfo( IN PIRP Irp)
1732 NTSTATUS ntStatus = STATUS_SUCCESS;
1733 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1734 IO_STATUS_BLOCK stIoSb = {0,0};
1735 AFSFcb *pSrcFcb = NULL, *pTargetDcb = NULL, *pTargetFcb = NULL;
1736 AFSCcb *pSrcCcb = NULL, *pTargetDirCcb = NULL;
1737 PFILE_OBJECT pSrcFileObj = pIrpSp->FileObject;
1738 PFILE_OBJECT pTargetFileObj = pIrpSp->Parameters.SetFile.FileObject;
1739 PFILE_RENAME_INFORMATION pRenameInfo = NULL;
1740 UNICODE_STRING uniTargetName, uniSourceName;
1741 BOOLEAN bReplaceIfExists = FALSE;
1742 UNICODE_STRING uniShortName;
1743 AFSDirectoryCB *pTargetDirEntry = NULL;
1744 ULONG ulTargetCRC = 0;
1745 BOOLEAN bTargetEntryExists = FALSE;
1746 AFSObjectInfoCB *pSrcObject = NULL, *pTargetObject = NULL;
1747 AFSObjectInfoCB *pSrcParentObject = NULL, *pTargetParentObject = NULL;
1748 AFSFileID stNewFid, stTmpTargetFid;
1749 UNICODE_STRING uniTmpTargetName;
1750 BOOLEAN bReplaceTmpTargetEntry = FALSE;
1751 ULONG ulNotificationAction = 0, ulNotifyFilter = 0;
1752 UNICODE_STRING uniFullTargetPath;
1753 BOOLEAN bCommonParent = FALSE;
1759 bReplaceIfExists = pIrpSp->Parameters.SetFile.ReplaceIfExists;
1761 pSrcFcb = (AFSFcb *)pSrcFileObj->FsContext;
1762 pSrcCcb = (AFSCcb *)pSrcFileObj->FsContext2;
1764 pSrcObject = pSrcFcb->ObjectInformation;
1766 uniTmpTargetName.Length = 0;
1767 uniTmpTargetName.MaximumLength = 0;
1768 uniTmpTargetName.Buffer = NULL;
1771 // Perform some basic checks to ensure FS integrity
1774 if( pSrcFcb->Header.NodeTypeCode == AFS_ROOT_FCB)
1778 // Can't rename the root directory
1781 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1782 AFS_TRACE_LEVEL_ERROR,
1783 "AFSSetRenameInfo Attempt to rename root entry\n");
1785 try_return( ntStatus = STATUS_INVALID_PARAMETER);
1788 if( pSrcFcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB)
1792 // If there are any open children then fail the rename
1795 if( pSrcFcb->ObjectInformation->Specific.Directory.ChildOpenHandleCount > 0)
1798 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1799 AFS_TRACE_LEVEL_ERROR,
1800 "AFSSetRenameInfo Attempt to rename directory with open children %wZ\n",
1801 &pSrcCcb->DirectoryCB->NameInformation.FileName);
1803 try_return( ntStatus = STATUS_ACCESS_DENIED);
1809 if( pSrcFcb->OpenHandleCount > 1)
1812 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1813 AFS_TRACE_LEVEL_ERROR,
1814 "AFSSetRenameInfo Attempt to rename directory with open references %wZ\n",
1815 &pSrcCcb->DirectoryCB->NameInformation.FileName);
1817 try_return( ntStatus = STATUS_ACCESS_DENIED);
1822 // Resolve the target fileobject
1825 if( pTargetFileObj == NULL)
1829 // This is a simple rename. Here the target directory is the same as the source parent directory
1830 // and the name is retrieved from the system buffer information
1833 pRenameInfo = (PFILE_RENAME_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
1835 pTargetParentObject = pSrcFcb->ObjectInformation->ParentObjectInformation;
1837 pTargetDcb = pTargetParentObject->Fcb;
1839 uniTargetName.Length = (USHORT)pRenameInfo->FileNameLength;
1840 uniTargetName.Buffer = (PWSTR)&pRenameInfo->FileName;
1846 // So here we have the target directory taken from the targetfile object
1849 pTargetDcb = (AFSFcb *)pTargetFileObj->FsContext;
1851 pTargetDirCcb = (AFSCcb *)pTargetFileObj->FsContext2;
1853 pTargetParentObject = (AFSObjectInfoCB *)pTargetDcb->ObjectInformation;
1856 // Grab the target name which we setup in the IRP_MJ_CREATE handler. By how we set this up
1857 // it is only the target component of the rename operation
1860 uniTargetName = *((PUNICODE_STRING)&pTargetFileObj->FileName);
1864 // We do not allow cross-volume renames to occur
1867 if( pTargetParentObject->VolumeCB != pSrcObject->VolumeCB)
1870 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1871 AFS_TRACE_LEVEL_ERROR,
1872 "AFSSetRenameInfo Attempt to rename directory to different volume %wZ\n",
1873 &pSrcCcb->DirectoryCB->NameInformation.FileName);
1875 try_return( ntStatus = STATUS_NOT_SAME_DEVICE);
1879 // If the target exists be sure the ReplaceIfExists flag is set
1882 AFSAcquireShared( pTargetParentObject->VolumeCB->VolumeLock,
1885 ulTargetCRC = AFSGenerateCRC( &uniTargetName,
1888 AFSAcquireShared( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock,
1891 AFSLocateCaseSensitiveDirEntry( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
1895 if( pTargetDirEntry == NULL)
1899 // Missed so perform a case insensitive lookup
1902 ulTargetCRC = AFSGenerateCRC( &uniTargetName,
1905 AFSLocateCaseInsensitiveDirEntry( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
1910 if( pTargetDirEntry == NULL && RtlIsNameLegalDOS8Dot3( &uniTargetName,
1915 // Try the short name
1917 AFSLocateShortNameDirEntry( pTargetParentObject->Specific.Directory.ShortNameTree,
1922 // Increment our ref count on the dir entry
1925 if( pTargetDirEntry != NULL)
1927 InterlockedIncrement( &pTargetDirEntry->OpenReferenceCount);
1930 AFSReleaseResource( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
1932 if( pTargetDirEntry != NULL)
1935 if( !bReplaceIfExists)
1938 AFSReleaseResource( pTargetParentObject->VolumeCB->VolumeLock);
1940 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1941 AFS_TRACE_LEVEL_ERROR,
1942 "AFSSetRenameInfo Attempt to rename directory with target collision %wZ Target %wZ\n",
1943 &pSrcCcb->DirectoryCB->NameInformation.FileName,
1944 &pTargetDirEntry->NameInformation.FileName);
1946 try_return( ntStatus = STATUS_OBJECT_NAME_COLLISION);
1949 bTargetEntryExists = TRUE;
1952 AFSReleaseResource( pTargetParentObject->VolumeCB->VolumeLock);
1955 // Extract off the final component name from the Fcb
1958 uniSourceName.Length = (USHORT)pSrcCcb->DirectoryCB->NameInformation.FileName.Length;
1959 uniSourceName.MaximumLength = uniSourceName.Length;
1961 uniSourceName.Buffer = pSrcCcb->DirectoryCB->NameInformation.FileName.Buffer;
1964 // The quick check to see if they are not really performing a rename
1965 // Do the names match? Only do this where the parent directories are
1969 if( pTargetParentObject == pSrcFcb->ObjectInformation->ParentObjectInformation)
1972 bCommonParent = TRUE;
1974 if( FsRtlAreNamesEqual( &uniTargetName,
1981 // Check for case only rename
1984 if( !FsRtlAreNamesEqual( &uniTargetName,
1991 // Just move in the new case form of the name
1994 RtlCopyMemory( pSrcCcb->DirectoryCB->NameInformation.FileName.Buffer,
1995 uniTargetName.Buffer,
1996 uniTargetName.Length);
1999 try_return( ntStatus = STATUS_SUCCESS);
2005 bCommonParent = FALSE;
2009 // If the target name exists then we need to 'move' the target before
2010 // sending the rename to the service
2013 if( bReplaceIfExists &&
2014 pTargetDirEntry != NULL)
2018 // What we will do is temporarily rename the file to a tmp file
2019 // so we can back out if anything fails below
2020 // First thing is to remove the original target from the parent
2023 AFSAcquireExcl( pTargetDirEntry->ObjectInformation->ParentObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
2026 AFSRemoveDirNodeFromParent( pTargetDirEntry->ObjectInformation->ParentObjectInformation,
2030 AFSReleaseResource( pTargetDirEntry->ObjectInformation->ParentObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
2032 pTargetDirEntry->FileIndex = (ULONG)InterlockedIncrement( &pTargetDirEntry->ObjectInformation->ParentObjectInformation->Specific.Directory.DirectoryNodeHdr.ContentIndex);
2034 uniTmpTargetName.Length = 0;
2035 uniTmpTargetName.MaximumLength = uniTargetName.Length + (4 * sizeof( WCHAR));
2037 uniTmpTargetName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2038 uniTmpTargetName.MaximumLength,
2039 AFS_GENERIC_MEMORY_11_TAG);
2041 if( uniTmpTargetName.Buffer == NULL)
2045 // Re-insert the entry
2048 AFSInsertDirectoryNode( pTargetDirEntry->ObjectInformation->ParentObjectInformation,
2052 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2053 AFS_TRACE_LEVEL_ERROR,
2054 "AFSSetRenameInfo Failed tmp buffer allocation during rename of %wZ\n",
2055 &pSrcCcb->DirectoryCB->NameInformation.FileName);
2057 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2060 RtlZeroMemory( uniTmpTargetName.Buffer,
2061 uniTmpTargetName.MaximumLength);
2063 uniTmpTargetName.Length = uniTargetName.Length;
2065 RtlCopyMemory( uniTmpTargetName.Buffer,
2066 uniTargetName.Buffer,
2067 uniTmpTargetName.Length);
2069 RtlCopyMemory( &uniTmpTargetName.Buffer[ uniTmpTargetName.Length/sizeof( WCHAR)],
2071 4 * sizeof( WCHAR));
2073 uniTmpTargetName.Length += (4 * sizeof( WCHAR));
2075 ntStatus = AFSNotifyRename( pTargetDirEntry->ObjectInformation,
2076 pTargetDirEntry->ObjectInformation->ParentObjectInformation,
2077 pTargetDcb->ObjectInformation,
2082 if( !NT_SUCCESS( ntStatus))
2086 // Re-insert the entry
2089 AFSInsertDirectoryNode( pTargetDirEntry->ObjectInformation->ParentObjectInformation,
2093 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2094 AFS_TRACE_LEVEL_ERROR,
2095 "AFSSetRenameInfo Failed rename of %wZ to tmp %wZ Status %08lX\n",
2096 &pSrcCcb->DirectoryCB->NameInformation.FileName,
2100 try_return( ntStatus);
2104 // Indicate we need to replace this entry if any failure occurs below
2107 bReplaceTmpTargetEntry = TRUE;
2111 // We need to remove the DirEntry from the parent node, update the index
2112 // and reinsert it into the parent tree. Note that for entries with the
2113 // same parent we do not pull the node from the enumeration list
2116 AFSAcquireExcl( pSrcFcb->ObjectInformation->ParentObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
2119 AFSRemoveDirNodeFromParent( pSrcFcb->ObjectInformation->ParentObjectInformation,
2120 pSrcCcb->DirectoryCB,
2123 AFSReleaseResource( pSrcFcb->ObjectInformation->ParentObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
2125 oldFileIndex = pSrcCcb->DirectoryCB->FileIndex;
2130 // We always need to update the FileIndex since this entry will be put at the 'end'
2131 // of the enumeraiton list. If we don't it will cause recursion ... We do this
2132 // here to cover any failures which might occur below
2135 pSrcCcb->DirectoryCB->FileIndex =
2136 (ULONG)InterlockedIncrement( &pTargetDcb->ObjectInformation->ParentObjectInformation->Specific.Directory.DirectoryNodeHdr.ContentIndex);
2140 // OK, this is a simple rename. Issue the rename
2141 // request to the service.
2144 ntStatus = AFSNotifyRename( pSrcFcb->ObjectInformation,
2145 pSrcFcb->ObjectInformation->ParentObjectInformation,
2146 pTargetDcb->ObjectInformation,
2147 pSrcCcb->DirectoryCB,
2151 if( !NT_SUCCESS( ntStatus))
2155 // Attempt to re-insert the directory entry
2158 pSrcCcb->DirectoryCB->FileIndex = oldFileIndex;
2159 AFSInsertDirectoryNode( pSrcFcb->ObjectInformation->ParentObjectInformation,
2160 pSrcCcb->DirectoryCB,
2163 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2164 AFS_TRACE_LEVEL_ERROR,
2165 "AFSSetRenameInfo Failed rename of %wZ to target %wZ Status %08lX\n",
2166 &pSrcCcb->DirectoryCB->NameInformation.FileName,
2170 try_return( ntStatus);
2174 // Set the notification up for the source file
2177 if( pSrcCcb->DirectoryCB->ObjectInformation->ParentObjectInformation == pTargetParentObject &&
2178 !bReplaceTmpTargetEntry)
2181 ulNotificationAction = FILE_ACTION_RENAMED_OLD_NAME;
2186 ulNotificationAction = FILE_ACTION_REMOVED;
2189 if( pSrcCcb->DirectoryCB->ObjectInformation->FileType == AFS_FILE_TYPE_DIRECTORY)
2192 ulNotifyFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
2197 ulNotifyFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
2200 AFSFsRtlNotifyFullReportChange( pSrcCcb->DirectoryCB->ObjectInformation->ParentObjectInformation,
2202 (ULONG)ulNotifyFilter,
2203 (ULONG)ulNotificationAction);
2206 // Update the name in the dir entry.
2209 ntStatus = AFSUpdateDirEntryName( pSrcCcb->DirectoryCB,
2212 if( !NT_SUCCESS( ntStatus))
2216 // Attempt to re-insert the directory entry
2219 pSrcCcb->DirectoryCB->FileIndex = oldFileIndex;
2220 AFSInsertDirectoryNode( pSrcFcb->ObjectInformation->ParentObjectInformation,
2221 pSrcCcb->DirectoryCB,
2224 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2225 AFS_TRACE_LEVEL_ERROR,
2226 "AFSSetRenameInfo Failed update of dir entry %wZ to target %wZ Status %08lX\n",
2227 &pSrcCcb->DirectoryCB->NameInformation.FileName,
2231 try_return( ntStatus);
2235 // Update the object information block, if needed
2238 if( !AFSIsEqualFID( &pSrcObject->FileId,
2243 // Remove the old information entry
2246 AFSAcquireExcl( pSrcObject->VolumeCB->ObjectInfoTree.TreeLock,
2249 AFSRemoveHashEntry( &pSrcObject->VolumeCB->ObjectInfoTree.TreeHead,
2250 &pSrcObject->TreeEntry);
2252 RtlCopyMemory( &pSrcObject->FileId,
2254 sizeof( AFSFileID));
2257 // Insert the entry into the new object table.
2260 pSrcObject->TreeEntry.HashIndex = AFSCreateLowIndex( &pSrcObject->FileId);
2262 if( pSrcObject->VolumeCB->ObjectInfoTree.TreeHead == NULL)
2265 pSrcObject->VolumeCB->ObjectInfoTree.TreeHead = &pSrcObject->TreeEntry;
2270 AFSInsertHashEntry( pSrcObject->VolumeCB->ObjectInfoTree.TreeHead,
2271 &pSrcObject->TreeEntry);
2274 AFSReleaseResource( pSrcObject->VolumeCB->ObjectInfoTree.TreeLock);
2278 // Update the hash values for the name trees.
2281 pSrcCcb->DirectoryCB->CaseSensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pSrcCcb->DirectoryCB->NameInformation.FileName,
2284 pSrcCcb->DirectoryCB->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pSrcCcb->DirectoryCB->NameInformation.FileName,
2287 if( pSrcCcb->DirectoryCB->NameInformation.ShortNameLength > 0)
2290 uniShortName.Length = pSrcCcb->DirectoryCB->NameInformation.ShortNameLength;
2291 uniShortName.Buffer = pSrcCcb->DirectoryCB->NameInformation.ShortName;
2293 pSrcCcb->DirectoryCB->Type.Data.ShortNameTreeEntry.HashIndex = AFSGenerateCRC( &uniShortName,
2299 pSrcCcb->DirectoryCB->Type.Data.ShortNameTreeEntry.HashIndex = 0;
2306 // Update the file index for the object in the new parent
2309 pSrcCcb->DirectoryCB->FileIndex = (ULONG)InterlockedIncrement( &pTargetParentObject->Specific.Directory.DirectoryNodeHdr.ContentIndex);
2313 // Re-insert the directory entry
2316 AFSInsertDirectoryNode( pTargetParentObject,
2317 pSrcCcb->DirectoryCB,
2321 // Update the parent pointer in the source object if they are different
2324 if( pSrcCcb->DirectoryCB->ObjectInformation->ParentObjectInformation != pTargetParentObject)
2327 InterlockedDecrement( &pSrcCcb->DirectoryCB->ObjectInformation->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);
2329 InterlockedDecrement( &pSrcCcb->DirectoryCB->ObjectInformation->ParentObjectInformation->Specific.Directory.ChildOpenReferenceCount);
2331 InterlockedIncrement( &pTargetParentObject->Specific.Directory.ChildOpenHandleCount);
2333 InterlockedIncrement( &pTargetParentObject->Specific.Directory.ChildOpenReferenceCount);
2335 pSrcCcb->DirectoryCB->ObjectInformation->ParentObjectInformation = pTargetParentObject;
2337 ulNotificationAction = FILE_ACTION_ADDED;
2342 ulNotificationAction = FILE_ACTION_RENAMED_NEW_NAME;
2346 // Now update the notification for the target file
2349 AFSFsRtlNotifyFullReportChange( pTargetParentObject->ParentObjectInformation,
2351 (ULONG)ulNotifyFilter,
2352 (ULONG)ulNotificationAction);
2355 // If we performed the rename of the target because it existed, we now need to
2356 // delete the tmp target we created above
2359 if( bReplaceTmpTargetEntry)
2362 RtlCopyMemory( &pTargetDirEntry->ObjectInformation->FileId,
2364 sizeof( AFSFileID));
2367 // Update the name in the dir entry
2370 ntStatus = AFSUpdateDirEntryName( pTargetDirEntry,
2373 if( !NT_SUCCESS( ntStatus))
2376 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2377 AFS_TRACE_LEVEL_ERROR,
2378 "AFSSetRenameInfo Failed update of target dir entry %wZ to tmp %wZ Status %08lX\n",
2379 &pTargetDirEntry->NameInformation.FileName,
2383 try_return( ntStatus);
2386 ntStatus = AFSNotifyDelete( pTargetDirEntry,
2389 if( !NT_SUCCESS( ntStatus))
2392 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2393 AFS_TRACE_LEVEL_VERBOSE,
2394 "AFSSetRenameInfo object deletion failure dir entry %p name %wZ to tmp %wZ\n",
2396 &pTargetDirEntry->NameInformation.FileName,
2399 try_return( ntStatus);
2402 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2403 AFS_TRACE_LEVEL_VERBOSE,
2404 "AFSSetRenameInfo Setting DELETE flag in dir entry %p name %wZ to tmp %wZ\n",
2406 &pTargetDirEntry->NameInformation.FileName,
2409 SetFlag( pTargetDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
2412 // Try and purge the cache map if this is a file
2415 if( pTargetDirEntry->ObjectInformation->FileType == AFS_FILE_TYPE_FILE &&
2416 pTargetDirEntry->ObjectInformation->Fcb != NULL &&
2417 pTargetDirEntry->OpenReferenceCount > 1)
2420 pTargetFcb = pTargetDirEntry->ObjectInformation->Fcb;
2422 AFSAcquireExcl( &pTargetFcb->NPFcb->Resource,
2426 // Try and flush the cache map
2429 if( !MmFlushImageSection( &pTargetFcb->NPFcb->SectionObjectPointers,
2433 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2434 AFS_TRACE_LEVEL_ERROR,
2435 "AFSSetRenameInfo Failed to flush section for deleted temp file %wZ\n",
2436 &pTargetDirEntry->NameInformation.FileName);
2439 AFSReleaseResource( &pTargetFcb->NPFcb->Resource);
2442 ASSERT( pTargetDirEntry->OpenReferenceCount > 0);
2444 InterlockedDecrement( &pTargetDirEntry->OpenReferenceCount);
2446 if( pTargetDirEntry->OpenReferenceCount == 0)
2449 SetFlag( pTargetDirEntry->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED);
2451 ASSERT( BooleanFlagOn( pTargetDirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE));
2454 // Free up the name buffer if it was reallocated
2457 if( BooleanFlagOn( pTargetDirEntry->Flags, AFS_DIR_RELEASE_NAME_BUFFER))
2460 AFSExFreePool( pTargetDirEntry->NameInformation.FileName.Buffer);
2463 if( BooleanFlagOn( pTargetDirEntry->Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER))
2466 AFSExFreePool( pTargetDirEntry->NameInformation.TargetName.Buffer);
2470 // Dereference the object for this dir entry
2473 ASSERT( pTargetDirEntry->ObjectInformation->ObjectReferenceCount > 0);
2475 InterlockedDecrement( &pTargetDirEntry->ObjectInformation->ObjectReferenceCount);
2477 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2478 AFS_TRACE_LEVEL_VERBOSE,
2479 "AFSSetRenameInfo Decrement3 count on object %08lX Cnt %d\n",
2480 pTargetDirEntry->ObjectInformation,
2481 pTargetDirEntry->ObjectInformation->ObjectReferenceCount);
2484 // Free up the dir entry
2487 ExDeleteResourceLite( &pTargetDirEntry->NonPaged->Lock);
2489 AFSExFreePool( pTargetDirEntry->NonPaged);
2491 AFSExFreePool( pTargetDirEntry);
2494 pTargetDirEntry = NULL;
2500 if( !NT_SUCCESS( ntStatus))
2503 if( bReplaceTmpTargetEntry)
2506 AFSNotifyRename( pTargetDirEntry->ObjectInformation,
2507 pTargetDirEntry->ObjectInformation->ParentObjectInformation,
2508 pTargetDcb->ObjectInformation,
2514 // Replace the target entry
2517 AFSAcquireExcl( pTargetDirEntry->ObjectInformation->VolumeCB->ObjectInfoTree.TreeLock,
2520 if( pTargetDirEntry->ObjectInformation->VolumeCB->ObjectInfoTree.TreeHead == NULL)
2523 pTargetDirEntry->ObjectInformation->VolumeCB->ObjectInfoTree.TreeHead = &pTargetDirEntry->ObjectInformation->TreeEntry;
2527 AFSInsertHashEntry( pTargetDirEntry->ObjectInformation->VolumeCB->ObjectInfoTree.TreeHead,
2528 &pTargetDirEntry->ObjectInformation->TreeEntry);
2531 AFSReleaseResource( pTargetDirEntry->ObjectInformation->VolumeCB->ObjectInfoTree.TreeLock);
2534 // We always need to update the FileIndex since this entry will be put at the 'end'
2535 // of the enumeraiton list. If we don't it will cause recursion ...
2538 pTargetDirEntry->FileIndex = (ULONG)InterlockedIncrement( &pTargetDirEntry->ObjectInformation->ParentObjectInformation->Specific.Directory.DirectoryNodeHdr.ContentIndex);
2540 AFSInsertDirectoryNode( pTargetDirEntry->ObjectInformation->ParentObjectInformation,
2546 if( pTargetDirEntry != NULL)
2549 InterlockedDecrement( &pTargetDirEntry->OpenReferenceCount);
2552 if( uniTmpTargetName.Buffer != NULL)
2555 AFSExFreePool( uniTmpTargetName.Buffer);
2563 AFSSetPositionInfo( IN PIRP Irp,
2564 IN AFSDirectoryCB *DirectoryCB)
2566 NTSTATUS ntStatus = STATUS_SUCCESS;
2567 PFILE_POSITION_INFORMATION pBuffer;
2568 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2570 pBuffer = (PFILE_POSITION_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
2572 pIrpSp->FileObject->CurrentByteOffset.QuadPart = pBuffer->CurrentByteOffset.QuadPart;
2578 AFSSetAllocationInfo( IN PIRP Irp,
2579 IN AFSDirectoryCB *DirectoryCB)
2581 NTSTATUS ntStatus = STATUS_SUCCESS;
2582 PFILE_ALLOCATION_INFORMATION pBuffer;
2583 BOOLEAN bReleasePaging = FALSE;
2584 BOOLEAN bTellCc = FALSE;
2585 BOOLEAN bTellService = FALSE;
2586 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2587 PFILE_OBJECT pFileObject = pIrpSp->FileObject;
2588 AFSFcb *pFcb = NULL;
2589 AFSCcb *pCcb = NULL;
2590 LARGE_INTEGER liSaveAlloc;
2591 LARGE_INTEGER liSaveFileSize;
2592 LARGE_INTEGER liSaveVDL;
2594 pBuffer = (PFILE_ALLOCATION_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
2596 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
2598 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
2601 // save values to put back
2603 liSaveAlloc = pFcb->Header.AllocationSize;
2604 liSaveFileSize = pFcb->Header.FileSize;
2605 liSaveVDL = pFcb->Header.ValidDataLength;
2607 if( pFcb->Header.AllocationSize.QuadPart == pBuffer->AllocationSize.QuadPart ||
2608 pIrpSp->Parameters.SetFile.AdvanceOnly)
2610 return STATUS_SUCCESS ;
2613 if( pFcb->Header.AllocationSize.QuadPart > pBuffer->AllocationSize.QuadPart)
2616 // Truncating the file
2618 if( !MmCanFileBeTruncated( pFileObject->SectionObjectPointer,
2619 &pBuffer->AllocationSize))
2622 ntStatus = STATUS_USER_MAPPED_FILE ;
2627 // If this is a truncation we need to grab the paging IO resource.
2629 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2630 AFS_TRACE_LEVEL_VERBOSE,
2631 "AFSSetAllocationInfo Acquiring Fcb PagingIo lock %08lX EXCL %08lX\n",
2632 &pFcb->NPFcb->PagingResource,
2633 PsGetCurrentThread());
2635 AFSAcquireExcl( &pFcb->NPFcb->PagingResource,
2638 bReleasePaging = TRUE;
2641 pFcb->Header.AllocationSize = pBuffer->AllocationSize;
2643 pFcb->ObjectInformation->AllocationSize = pBuffer->AllocationSize;
2646 // Tell Cc that Allocation is moved.
2650 if( pFcb->Header.FileSize.QuadPart > pBuffer->AllocationSize.QuadPart)
2653 // We are pulling the EOF back as well so we need to tell
2656 bTellService = TRUE;
2658 pFcb->Header.FileSize = pBuffer->AllocationSize;
2660 pFcb->ObjectInformation->EndOfFile = pBuffer->AllocationSize;
2668 // Tell Cc if allocation is increased.
2670 bTellCc = pBuffer->AllocationSize.QuadPart > pFcb->Header.AllocationSize.QuadPart;
2672 pFcb->Header.AllocationSize = pBuffer->AllocationSize;
2674 pFcb->ObjectInformation->AllocationSize = pBuffer->AllocationSize;
2678 // Now Tell the server if we have to
2682 ntStatus = AFSUpdateFileInformation( &pFcb->ObjectInformation->ParentObjectInformation->FileId,
2683 pFcb->ObjectInformation,
2687 if (NT_SUCCESS(ntStatus))
2690 // Trim extents if we told the service - the update has done an implicit
2691 // trim at the service.
2695 AFSTrimExtents( pFcb,
2696 &pFcb->Header.FileSize);
2699 KeQuerySystemTime( &pFcb->ObjectInformation->ChangeTime);
2701 SetFlag( pFcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_CHANGE_TIME);
2704 CcIsFileCached( pFileObject))
2706 CcSetFileSizes( pFileObject,
2707 (PCC_FILE_SIZES)&pFcb->Header.AllocationSize);
2713 // Put the saved values back
2715 pFcb->Header.ValidDataLength = liSaveVDL;
2716 pFcb->Header.FileSize = liSaveFileSize;
2717 pFcb->Header.AllocationSize = liSaveAlloc;
2718 pFcb->ObjectInformation->EndOfFile = liSaveFileSize;
2719 pFcb->ObjectInformation->AllocationSize = liSaveAlloc;
2725 AFSReleaseResource( &pFcb->NPFcb->PagingResource);
2732 AFSSetEndOfFileInfo( IN PIRP Irp,
2733 IN AFSDirectoryCB *DirectoryCB)
2735 NTSTATUS ntStatus = STATUS_SUCCESS;
2736 PFILE_END_OF_FILE_INFORMATION pBuffer;
2737 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2738 PFILE_OBJECT pFileObject = pIrpSp->FileObject;
2739 LARGE_INTEGER liSaveSize;
2740 LARGE_INTEGER liSaveVDL;
2741 LARGE_INTEGER liSaveAlloc;
2742 BOOLEAN bModified = FALSE;
2743 BOOLEAN bReleasePaging = FALSE;
2744 BOOLEAN bTruncated = FALSE;
2745 AFSFcb *pFcb = NULL;
2746 AFSCcb *pCcb = NULL;
2748 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
2750 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
2752 pBuffer = (PFILE_END_OF_FILE_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
2754 liSaveSize = pFcb->Header.FileSize;
2755 liSaveAlloc = pFcb->Header.AllocationSize;
2756 liSaveVDL = pFcb->Header.ValidDataLength;
2758 if( pFcb->Header.FileSize.QuadPart != pBuffer->EndOfFile.QuadPart &&
2759 !pIrpSp->Parameters.SetFile.AdvanceOnly)
2762 if( pBuffer->EndOfFile.QuadPart < pFcb->Header.FileSize.QuadPart)
2765 // Truncating the file
2766 if( !MmCanFileBeTruncated( pFileObject->SectionObjectPointer,
2767 &pBuffer->EndOfFile))
2770 ntStatus = STATUS_USER_MAPPED_FILE;
2775 // If this is a truncation we need to grab the paging
2778 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2779 AFS_TRACE_LEVEL_VERBOSE,
2780 "AFSSetAllocationInfo Acquiring Fcb PagingIo lock %08lX EXCL %08lX\n",
2781 &pFcb->NPFcb->PagingResource,
2782 PsGetCurrentThread());
2784 AFSAcquireExcl( &pFcb->NPFcb->PagingResource,
2787 bReleasePaging = TRUE;
2789 pFcb->Header.AllocationSize = pBuffer->EndOfFile;
2791 pFcb->Header.FileSize = pBuffer->EndOfFile;
2793 pFcb->ObjectInformation->EndOfFile = pBuffer->EndOfFile;
2795 pFcb->ObjectInformation->AllocationSize = pBuffer->EndOfFile;
2797 if( pFcb->Header.ValidDataLength.QuadPart > pFcb->Header.FileSize.QuadPart)
2800 pFcb->Header.ValidDataLength = pFcb->Header.FileSize;
2811 // extending the file, move EOF
2814 pFcb->Header.FileSize = pBuffer->EndOfFile;
2816 pFcb->ObjectInformation->EndOfFile = pBuffer->EndOfFile;
2818 if (pFcb->Header.FileSize.QuadPart > pFcb->Header.AllocationSize.QuadPart)
2821 // And Allocation as needed.
2823 pFcb->Header.AllocationSize = pBuffer->EndOfFile;
2825 pFcb->ObjectInformation->AllocationSize = pBuffer->EndOfFile;
2835 KeQuerySystemTime( &pFcb->ObjectInformation->ChangeTime);
2837 SetFlag( pFcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_CHANGE_TIME);
2843 ntStatus = AFSUpdateFileInformation( &pFcb->ObjectInformation->ParentObjectInformation->FileId,
2844 pFcb->ObjectInformation,
2847 if( NT_SUCCESS(ntStatus))
2850 // We are now good to go so tell CC.
2852 CcSetFileSizes( pFileObject,
2853 (PCC_FILE_SIZES)&pFcb->Header.AllocationSize);
2856 // And give up those extents
2861 AFSTrimExtents( pFcb,
2862 &pFcb->Header.FileSize);
2867 pFcb->Header.ValidDataLength = liSaveVDL;
2868 pFcb->Header.FileSize = liSaveSize;
2869 pFcb->Header.AllocationSize = liSaveAlloc;
2870 pFcb->ObjectInformation->EndOfFile = liSaveSize;
2871 pFcb->ObjectInformation->AllocationSize = liSaveAlloc;
2878 AFSReleaseResource( &pFcb->NPFcb->PagingResource);
2885 AFSProcessShareSetInfo( IN IRP *Irp,
2890 NTSTATUS ntStatus = STATUS_SUCCESS;
2891 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2892 ULONG ulOutputBufferLen = 0, ulInputBufferLen;
2893 FILE_INFORMATION_CLASS ulFileInformationClass;
2894 void *pPipeInfo = NULL;
2898 ulFileInformationClass = pIrpSp->Parameters.SetFile.FileInformationClass;
2900 AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
2901 AFS_TRACE_LEVEL_VERBOSE,
2902 "AFSProcessShareSetInfo On pipe %wZ Class %08lX\n",
2903 &Ccb->DirectoryCB->NameInformation.FileName,
2904 ulFileInformationClass);
2906 pPipeInfo = AFSLockSystemBuffer( Irp,
2907 pIrpSp->Parameters.SetFile.Length);
2909 if( pPipeInfo == NULL)
2912 AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
2913 AFS_TRACE_LEVEL_ERROR,
2914 "AFSProcessShareSetInfo Failed to lock buffer on pipe %wZ\n",
2915 &Ccb->DirectoryCB->NameInformation.FileName);
2917 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2921 // Send the request to the service
2924 ntStatus = AFSNotifySetPipeInfo( Ccb,
2925 (ULONG)ulFileInformationClass,
2926 pIrpSp->Parameters.SetFile.Length,
2929 if( !NT_SUCCESS( ntStatus))
2932 AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
2933 AFS_TRACE_LEVEL_ERROR,
2934 "AFSProcessShareSetInfo Failed to send request to service on pipe %wZ Status %08lX\n",
2935 &Ccb->DirectoryCB->NameInformation.FileName,
2938 try_return( ntStatus);
2941 AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
2942 AFS_TRACE_LEVEL_VERBOSE,
2943 "AFSProcessShareSetInfo Completed request on pipe %wZ Class %08lX\n",
2944 &Ccb->DirectoryCB->NameInformation.FileName,
2945 ulFileInformationClass);
2956 AFSProcessShareQueryInfo( IN IRP *Irp,
2961 NTSTATUS ntStatus = STATUS_SUCCESS;
2962 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2963 ULONG ulOutputBufferLen = 0, ulInputBufferLen;
2964 FILE_INFORMATION_CLASS ulFileInformationClass;
2965 void *pPipeInfo = NULL;
2970 ulFileInformationClass = pIrpSp->Parameters.QueryFile.FileInformationClass;
2972 AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
2973 AFS_TRACE_LEVEL_VERBOSE,
2974 "AFSProcessShareQueryInfo On pipe %wZ Class %08lX\n",
2975 &Ccb->DirectoryCB->NameInformation.FileName,
2976 ulFileInformationClass);
2978 pPipeInfo = AFSLockSystemBuffer( Irp,
2979 pIrpSp->Parameters.QueryFile.Length);
2981 if( pPipeInfo == NULL)
2984 AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
2985 AFS_TRACE_LEVEL_ERROR,
2986 "AFSProcessShareQueryInfo Failed to lock buffer on pipe %wZ\n",
2987 &Ccb->DirectoryCB->NameInformation.FileName);
2989 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2993 // Send the request to the service
2996 ntStatus = AFSNotifyQueryPipeInfo( Ccb,
2997 (ULONG)ulFileInformationClass,
2998 pIrpSp->Parameters.QueryFile.Length,
3000 (ULONG *)&Irp->IoStatus.Information);
3002 if( !NT_SUCCESS( ntStatus))
3005 AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
3006 AFS_TRACE_LEVEL_ERROR,
3007 "AFSProcessShareQueryInfo Failed to send request to service on pipe %wZ Status %08lX\n",
3008 &Ccb->DirectoryCB->NameInformation.FileName,
3011 try_return( ntStatus);
3014 AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
3015 AFS_TRACE_LEVEL_VERBOSE,
3016 "AFSProcessShareQueryInfo Completed request on pipe %wZ Class %08lX\n",
3017 &Ccb->DirectoryCB->NameInformation.FileName,
3018 ulFileInformationClass);
3029 AFSProcessPIOCtlQueryInfo( IN IRP *Irp,
3032 IN OUT LONG *Length)
3035 NTSTATUS ntStatus = STATUS_SUCCESS;
3036 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
3037 FILE_INFORMATION_CLASS ulFileInformationClass;
3042 ulFileInformationClass = pIrpSp->Parameters.QueryFile.FileInformationClass;
3044 switch( ulFileInformationClass)
3047 case FileBasicInformation:
3050 if ( *Length >= sizeof( FILE_BASIC_INFORMATION))
3052 PFILE_BASIC_INFORMATION pBasic = (PFILE_BASIC_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
3054 pBasic->CreationTime.QuadPart = 0;
3055 pBasic->LastAccessTime.QuadPart = 0;
3056 pBasic->ChangeTime.QuadPart = 0;
3057 pBasic->LastWriteTime.QuadPart = 0;
3058 pBasic->FileAttributes = FILE_ATTRIBUTE_SYSTEM;
3060 *Length -= sizeof( FILE_BASIC_INFORMATION);
3064 ntStatus = STATUS_BUFFER_OVERFLOW;
3070 case FileStandardInformation:
3073 if ( *Length >= sizeof( FILE_STANDARD_INFORMATION))
3075 PFILE_STANDARD_INFORMATION pStandard = (PFILE_STANDARD_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
3077 pStandard->NumberOfLinks = 1;
3078 pStandard->DeletePending = 0;
3079 pStandard->AllocationSize.QuadPart = 4096;
3080 pStandard->EndOfFile.QuadPart = 4096;
3081 pStandard->Directory = 0;
3083 *Length -= sizeof( FILE_STANDARD_INFORMATION);
3087 ntStatus = STATUS_BUFFER_OVERFLOW;
3093 case FileNameInformation:
3096 ULONG ulCopyLength = 0;
3097 AFSFcb *pFcb = NULL;
3098 AFSCcb *pCcb = NULL;
3099 USHORT usFullNameLength = 0;
3100 PFILE_NAME_INFORMATION pNameInfo = (PFILE_NAME_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
3101 UNICODE_STRING uniName;
3103 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
3104 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
3106 if( *Length < FIELD_OFFSET( FILE_NAME_INFORMATION, FileName))
3108 ntStatus = STATUS_BUFFER_TOO_SMALL;
3112 RtlZeroMemory( pNameInfo,
3115 usFullNameLength = sizeof( WCHAR) +
3116 AFSServerName.Length +
3117 pCcb->FullFileName.Length;
3119 if( *Length >= (LONG)(FIELD_OFFSET( FILE_NAME_INFORMATION, FileName) + (LONG)usFullNameLength))
3121 ulCopyLength = (LONG)usFullNameLength;
3125 ulCopyLength = *Length - FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
3126 ntStatus = STATUS_BUFFER_OVERFLOW;
3129 pNameInfo->FileNameLength = (ULONG)usFullNameLength;
3131 *Length -= FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
3133 if( ulCopyLength > 0)
3136 pNameInfo->FileName[ 0] = L'\\';
3137 ulCopyLength -= sizeof( WCHAR);
3139 *Length -= sizeof( WCHAR);
3141 if( ulCopyLength >= AFSServerName.Length)
3144 RtlCopyMemory( &pNameInfo->FileName[ 1],
3145 AFSServerName.Buffer,
3146 AFSServerName.Length);
3148 ulCopyLength -= AFSServerName.Length;
3149 *Length -= AFSServerName.Length;
3151 if( ulCopyLength >= pCcb->FullFileName.Length)
3154 RtlCopyMemory( &pNameInfo->FileName[ 1 + (AFSServerName.Length/sizeof( WCHAR))],
3155 pCcb->FullFileName.Buffer,
3156 pCcb->FullFileName.Length);
3158 ulCopyLength -= pCcb->FullFileName.Length;
3159 *Length -= pCcb->FullFileName.Length;
3161 uniName.Length = (USHORT)pNameInfo->FileNameLength;
3162 uniName.MaximumLength = uniName.Length;
3163 uniName.Buffer = pNameInfo->FileName;
3168 RtlCopyMemory( &pNameInfo->FileName[ 1 + (AFSServerName.Length/sizeof( WCHAR))],
3169 pCcb->FullFileName.Buffer,
3172 *Length -= ulCopyLength;
3174 uniName.Length = (USHORT)(sizeof( WCHAR) + AFSServerName.Length + ulCopyLength);
3175 uniName.MaximumLength = uniName.Length;
3176 uniName.Buffer = pNameInfo->FileName;
3179 AFSDbgLogMsg( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
3180 AFS_TRACE_LEVEL_VERBOSE,
3181 "AFSProcessPIOCtlQueryInfo (FileNameInformation) Returning %wZ\n",
3189 case FileInternalInformation:
3192 PFILE_INTERNAL_INFORMATION pInternalInfo = (PFILE_INTERNAL_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
3194 if( *Length >= sizeof( FILE_INTERNAL_INFORMATION))
3197 pInternalInfo->IndexNumber.HighPart = 0;
3199 pInternalInfo->IndexNumber.LowPart = 0;
3201 *Length -= sizeof( FILE_INTERNAL_INFORMATION);
3206 ntStatus = STATUS_BUFFER_TOO_SMALL;
3214 ntStatus = STATUS_INVALID_PARAMETER;
3216 AFSDbgLogMsg( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
3217 AFS_TRACE_LEVEL_WARNING,
3218 "AFSProcessPIOCtlQueryInfo Not handling request %08lX\n",
3219 ulFileInformationClass);