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);
142 else if( pFcb->Header.NodeTypeCode == AFS_INVALID_FCB)
144 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
145 AFS_TRACE_LEVEL_VERBOSE,
146 "AFSQueryFileInfo request against Invalid Fcb\n");
148 try_return( ntStatus = STATUS_ACCESS_DENIED);
152 // Process the request
155 switch( stFileInformationClass)
158 case FileAllInformation:
161 PFILE_ALL_INFORMATION pAllInfo;
164 // For the all information class we'll typecast a local
165 // pointer to the output buffer and then call the
166 // individual routines to fill in the buffer.
169 pAllInfo = (PFILE_ALL_INFORMATION)pBuffer;
171 ntStatus = AFSQueryBasicInfo( Irp,
173 &pAllInfo->BasicInformation,
176 if( !NT_SUCCESS( ntStatus))
179 try_return( ntStatus);
182 ntStatus = AFSQueryStandardInfo( Irp,
184 &pAllInfo->StandardInformation,
187 if( !NT_SUCCESS( ntStatus))
190 try_return( ntStatus);
193 ntStatus = AFSQueryInternalInfo( Irp,
195 &pAllInfo->InternalInformation,
198 if( !NT_SUCCESS( ntStatus))
201 try_return( ntStatus);
204 ntStatus = AFSQueryEaInfo( Irp,
206 &pAllInfo->EaInformation,
209 if( !NT_SUCCESS( ntStatus))
212 try_return( ntStatus);
215 ntStatus = AFSQueryAccess( Irp,
217 &pAllInfo->AccessInformation,
220 if( !NT_SUCCESS( ntStatus))
223 try_return( ntStatus);
226 ntStatus = AFSQueryPositionInfo( Irp,
228 &pAllInfo->PositionInformation,
231 if( !NT_SUCCESS( ntStatus))
234 try_return( ntStatus);
237 ntStatus = AFSQueryMode( Irp,
239 &pAllInfo->ModeInformation,
242 if( !NT_SUCCESS( ntStatus))
245 try_return( ntStatus);
248 ntStatus = AFSQueryAlignment( Irp,
250 &pAllInfo->AlignmentInformation,
253 if( !NT_SUCCESS( ntStatus))
256 try_return( ntStatus);
259 ntStatus = AFSQueryNameInfo( Irp,
261 &pAllInfo->NameInformation,
264 if( !NT_SUCCESS( ntStatus))
267 try_return( ntStatus);
273 case FileBasicInformation:
276 ntStatus = AFSQueryBasicInfo( Irp,
278 (PFILE_BASIC_INFORMATION)pBuffer,
284 case FileStandardInformation:
287 ntStatus = AFSQueryStandardInfo( Irp,
289 (PFILE_STANDARD_INFORMATION)pBuffer,
295 case FileInternalInformation:
298 ntStatus = AFSQueryInternalInfo( Irp,
300 (PFILE_INTERNAL_INFORMATION)pBuffer,
306 case FileEaInformation:
309 ntStatus = AFSQueryEaInfo( Irp,
311 (PFILE_EA_INFORMATION)pBuffer,
317 case FilePositionInformation:
320 ntStatus = AFSQueryPositionInfo( Irp,
322 (PFILE_POSITION_INFORMATION)pBuffer,
328 case FileNameInformation:
331 ntStatus = AFSQueryNameInfo( Irp,
333 (PFILE_NAME_INFORMATION)pBuffer,
339 case FileAlternateNameInformation:
342 ntStatus = AFSQueryShortNameInfo( Irp,
344 (PFILE_NAME_INFORMATION)pBuffer,
350 case FileNetworkOpenInformation:
353 ntStatus = AFSQueryNetworkInfo( Irp,
355 (PFILE_NETWORK_OPEN_INFORMATION)pBuffer,
361 case FileStreamInformation:
364 ntStatus = AFSQueryStreamInfo( Irp,
366 (FILE_STREAM_INFORMATION *)pBuffer,
373 case FileAttributeTagInformation:
376 ntStatus = AFSQueryAttribTagInfo( Irp,
378 (FILE_ATTRIBUTE_TAG_INFORMATION *)pBuffer,
384 case FileRemoteProtocolInformation:
387 ntStatus = AFSQueryRemoteProtocolInfo( Irp,
389 (FILE_REMOTE_PROTOCOL_INFORMATION *)pBuffer,
395 case FileNetworkPhysicalNameInformation:
398 ntStatus = AFSQueryPhysicalNameInfo( Irp,
400 (FILE_NETWORK_PHYSICAL_NAME_INFORMATION *)pBuffer,
408 ntStatus = STATUS_INVALID_PARAMETER;
415 Irp->IoStatus.Information = pIrpSp->Parameters.QueryFile.Length - lLength;
420 AFSReleaseResource( &pFcb->NPFcb->Resource);
423 if( !NT_SUCCESS( ntStatus) &&
424 ntStatus != STATUS_INVALID_PARAMETER &&
425 ntStatus != STATUS_BUFFER_OVERFLOW)
429 pCcb->DirectoryCB != NULL)
432 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
433 AFS_TRACE_LEVEL_ERROR,
434 "AFSQueryFileInfo Failed to process request for %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
435 &pCcb->DirectoryCB->NameInformation.FileName,
436 pCcb->DirectoryCB->ObjectInformation->FileId.Cell,
437 pCcb->DirectoryCB->ObjectInformation->FileId.Volume,
438 pCcb->DirectoryCB->ObjectInformation->FileId.Vnode,
439 pCcb->DirectoryCB->ObjectInformation->FileId.Unique,
444 __except( AFSExceptionFilter( GetExceptionCode(), GetExceptionInformation()) )
449 "EXCEPTION - AFSQueryFileInfo\n");
451 ntStatus = STATUS_UNSUCCESSFUL;
456 AFSReleaseResource( &pFcb->NPFcb->Resource);
460 AFSCompleteRequest( Irp,
467 // Function: AFSSetFileInfo
471 // This function is the dispatch handler for the IRP_MJ_SET_FILE_INFORMATION request
475 // A status is returned for the function
479 AFSSetFileInfo( IN PDEVICE_OBJECT LibDeviceObject,
483 NTSTATUS ntStatus = STATUS_SUCCESS;
484 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
485 IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
488 BOOLEAN bCompleteRequest = TRUE;
489 FILE_INFORMATION_CLASS FileInformationClass;
490 BOOLEAN bCanQueueRequest = FALSE;
491 PFILE_OBJECT pFileObject = NULL;
492 BOOLEAN bReleaseMain = FALSE;
493 BOOLEAN bUpdateFileInfo = FALSE;
494 AFSFileID stParentFileId;
499 pFileObject = pIrpSp->FileObject;
501 pFcb = (AFSFcb *)pFileObject->FsContext;
502 pCcb = (AFSCcb *)pFileObject->FsContext2;
507 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
508 AFS_TRACE_LEVEL_ERROR,
509 "AFSSetFileInfo Attempted access (%08lX) when pFcb == NULL\n",
512 try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST);
515 bCanQueueRequest = !(IoIsOperationSynchronous( Irp) | (KeGetCurrentIrql() != PASSIVE_LEVEL));
516 FileInformationClass = pIrpSp->Parameters.SetFile.FileInformationClass;
522 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
523 AFS_TRACE_LEVEL_VERBOSE,
524 "AFSSetFileInfo Acquiring Fcb lock %08lX EXCL %08lX\n",
525 &pFcb->NPFcb->Resource,
526 PsGetCurrentThread());
528 AFSAcquireExcl( &pFcb->NPFcb->Resource,
534 // Don't allow requests against IOCtl nodes
537 if( pFcb->Header.NodeTypeCode == AFS_IOCTL_FCB)
540 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
541 AFS_TRACE_LEVEL_ERROR,
542 "AFSSetFileInfo Failing request against PIOCtl Fcb\n");
544 try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST);
546 else if( pFcb->Header.NodeTypeCode == AFS_SPECIAL_SHARE_FCB)
549 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
550 AFS_TRACE_LEVEL_VERBOSE,
551 "AFSSetFileInfo Processing request against SpecialShare Fcb\n");
553 ntStatus = AFSProcessShareSetInfo( Irp,
557 try_return( ntStatus);
560 if( BooleanFlagOn( pFcb->ObjectInformation->VolumeCB->VolumeInformation.Characteristics, FILE_READ_ONLY_DEVICE))
563 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
564 AFS_TRACE_LEVEL_ERROR,
565 "AFSSetFileInfo Request failed due to read only volume\n",
568 try_return( ntStatus = STATUS_MEDIA_WRITE_PROTECTED);
571 if( pFcb->Header.NodeTypeCode == AFS_INVALID_FCB &&
572 FileInformationClass != FileDispositionInformation)
574 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
575 AFS_TRACE_LEVEL_VERBOSE,
576 "AFSSetFileInfo request against Invalid Fcb\n");
578 try_return( ntStatus = STATUS_ACCESS_DENIED);
582 // Ensure rename operations are synchronous
585 if( FileInformationClass == FileRenameInformation)
588 bCanQueueRequest = FALSE;
592 // Store away the parent fid
595 RtlZeroMemory( &stParentFileId,
598 if( pFcb->ObjectInformation->ParentObjectInformation != NULL)
600 stParentFileId = pFcb->ObjectInformation->ParentObjectInformation->FileId;
604 // Process the request
607 switch( FileInformationClass)
610 case FileBasicInformation:
613 bUpdateFileInfo = TRUE;
615 ntStatus = AFSSetBasicInfo( Irp,
621 case FileDispositionInformation:
624 ntStatus = AFSSetDispositionInfo( Irp,
630 case FileRenameInformation:
633 ntStatus = AFSSetRenameInfo( Irp);
638 case FilePositionInformation:
641 ntStatus = AFSSetPositionInfo( Irp,
647 case FileLinkInformation:
650 ntStatus = STATUS_INVALID_DEVICE_REQUEST;
655 case FileAllocationInformation:
658 ntStatus = AFSSetAllocationInfo( Irp,
664 case FileEndOfFileInformation:
667 ntStatus = AFSSetEndOfFileInfo( Irp,
675 ntStatus = STATUS_INVALID_PARAMETER;
685 AFSReleaseResource( &pFcb->NPFcb->Resource);
688 if( NT_SUCCESS( ntStatus) &&
692 ntStatus = AFSUpdateFileInformation( &stParentFileId,
693 pFcb->ObjectInformation,
696 if( !NT_SUCCESS( ntStatus))
699 AFSAcquireExcl( &pFcb->NPFcb->Resource,
703 // Unwind the update and fail the request
706 AFSUnwindFileInfo( pFcb,
709 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
710 AFS_TRACE_LEVEL_ERROR,
711 "AFSSetFileInfo Failed to send file info update to service request for %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
712 &pCcb->DirectoryCB->NameInformation.FileName,
713 pCcb->DirectoryCB->ObjectInformation->FileId.Cell,
714 pCcb->DirectoryCB->ObjectInformation->FileId.Volume,
715 pCcb->DirectoryCB->ObjectInformation->FileId.Vnode,
716 pCcb->DirectoryCB->ObjectInformation->FileId.Unique,
719 AFSReleaseResource( &pFcb->NPFcb->Resource);
723 if( !NT_SUCCESS( ntStatus))
727 pCcb->DirectoryCB != NULL)
730 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
731 AFS_TRACE_LEVEL_ERROR,
732 "AFSSetFileInfo Failed to process request for %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
733 &pCcb->DirectoryCB->NameInformation.FileName,
734 pCcb->DirectoryCB->ObjectInformation->FileId.Cell,
735 pCcb->DirectoryCB->ObjectInformation->FileId.Volume,
736 pCcb->DirectoryCB->ObjectInformation->FileId.Vnode,
737 pCcb->DirectoryCB->ObjectInformation->FileId.Unique,
742 __except( AFSExceptionFilter( GetExceptionCode(), GetExceptionInformation()) )
747 "EXCEPTION - AFSSetFileInfo\n");
749 ntStatus = STATUS_UNSUCCESSFUL;
752 AFSCompleteRequest( Irp,
759 // Function: AFSQueryBasicInfo
763 // This function is the handler for the query basic information request
767 // A status is returned for the function
771 AFSQueryBasicInfo( IN PIRP Irp,
772 IN AFSDirectoryCB *DirectoryCB,
773 IN OUT PFILE_BASIC_INFORMATION Buffer,
776 NTSTATUS ntStatus = STATUS_SUCCESS;
777 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
778 ULONG ulFileAttribs = 0;
781 IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
782 AFSFileInfoCB stFileInfo;
783 AFSDirectoryCB *pParentDirectoryCB = NULL;
784 UNICODE_STRING uniParentPath;
786 if( *Length >= sizeof( FILE_BASIC_INFORMATION))
789 RtlZeroMemory( Buffer,
792 ulFileAttribs = DirectoryCB->ObjectInformation->FileAttributes;
794 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
795 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
797 if( DirectoryCB->ObjectInformation->FileType == AFS_FILE_TYPE_SYMLINK)
800 pParentDirectoryCB = AFSGetParentEntry( pCcb->NameArray);
802 AFSRetrieveParentPath( &pCcb->FullFileName,
805 RtlZeroMemory( &stFileInfo,
806 sizeof( AFSFileInfoCB));
809 // Can't hold the Fcb while evaluating the path, leads to lock inversion
812 AFSReleaseResource( &pFcb->NPFcb->Resource);
814 if( NT_SUCCESS( AFSRetrieveFileAttributes( pParentDirectoryCB,
821 ulFileAttribs = stFileInfo.FileAttributes;
823 ulFileAttribs |= FILE_ATTRIBUTE_REPARSE_POINT;
826 AFSAcquireShared( &pFcb->NPFcb->Resource,
831 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
832 AFS_TRACE_LEVEL_VERBOSE_2,
833 "AFSQueryBasicInfo %wZ Type 0x%x Attrib 0x%x -> 0x%x\n",
834 &pCcb->DirectoryCB->NameInformation.FileName,
835 pCcb->DirectoryCB->ObjectInformation->FileType,
836 pCcb->DirectoryCB->ObjectInformation->FileAttributes,
839 Buffer->CreationTime = DirectoryCB->ObjectInformation->CreationTime;
840 Buffer->LastAccessTime = DirectoryCB->ObjectInformation->LastAccessTime;
841 Buffer->LastWriteTime = DirectoryCB->ObjectInformation->LastWriteTime;
842 Buffer->ChangeTime = DirectoryCB->ObjectInformation->ChangeTime;
843 Buffer->FileAttributes = ulFileAttribs;
845 if( DirectoryCB->NameInformation.FileName.Buffer[ 0] == L'.' &&
846 BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_HIDE_DOT_NAMES))
849 if ( Buffer->FileAttributes != FILE_ATTRIBUTE_NORMAL)
851 Buffer->FileAttributes |= FILE_ATTRIBUTE_HIDDEN;
855 Buffer->FileAttributes = FILE_ATTRIBUTE_HIDDEN;
859 *Length -= sizeof( FILE_BASIC_INFORMATION);
864 ntStatus = STATUS_BUFFER_TOO_SMALL;
871 AFSQueryStandardInfo( IN PIRP Irp,
872 IN AFSDirectoryCB *DirectoryCB,
873 IN OUT PFILE_STANDARD_INFORMATION Buffer,
877 NTSTATUS ntStatus = STATUS_SUCCESS;
880 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
881 AFSFileInfoCB stFileInfo;
882 AFSDirectoryCB *pParentDirectoryCB = NULL;
883 UNICODE_STRING uniParentPath;
884 ULONG ulFileAttribs = 0;
886 if( *Length >= sizeof( FILE_STANDARD_INFORMATION))
889 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
890 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
892 RtlZeroMemory( Buffer,
895 Buffer->NumberOfLinks = 1;
896 Buffer->DeletePending = BooleanFlagOn( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
898 Buffer->AllocationSize.QuadPart = (ULONGLONG)((DirectoryCB->ObjectInformation->AllocationSize.QuadPart/PAGE_SIZE) + 1) * PAGE_SIZE;
900 Buffer->EndOfFile = DirectoryCB->ObjectInformation->EndOfFile;
902 ulFileAttribs = DirectoryCB->ObjectInformation->FileAttributes;
904 if( DirectoryCB->ObjectInformation->FileType == AFS_FILE_TYPE_SYMLINK)
907 pParentDirectoryCB = AFSGetParentEntry( pCcb->NameArray);
909 AFSRetrieveParentPath( &pCcb->FullFileName,
912 RtlZeroMemory( &stFileInfo,
913 sizeof( AFSFileInfoCB));
916 // Can't hold the Fcb while evaluating the path, leads to lock inversion
919 AFSReleaseResource( &pFcb->NPFcb->Resource);
921 if( NT_SUCCESS( AFSRetrieveFileAttributes( pParentDirectoryCB,
928 ulFileAttribs = stFileInfo.FileAttributes;
931 AFSAcquireShared( &pFcb->NPFcb->Resource,
935 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
936 AFS_TRACE_LEVEL_VERBOSE_2,
937 "AFSQueryStandardInfo %wZ Type 0x%x Attrib 0x%x -> 0x%x\n",
938 &pCcb->DirectoryCB->NameInformation.FileName,
939 pCcb->DirectoryCB->ObjectInformation->FileType,
940 pCcb->DirectoryCB->ObjectInformation->FileAttributes,
943 Buffer->Directory = BooleanFlagOn( ulFileAttribs, FILE_ATTRIBUTE_DIRECTORY);
945 *Length -= sizeof( FILE_STANDARD_INFORMATION);
950 ntStatus = STATUS_BUFFER_TOO_SMALL;
957 AFSQueryInternalInfo( IN PIRP Irp,
959 IN OUT PFILE_INTERNAL_INFORMATION Buffer,
963 NTSTATUS ntStatus = STATUS_SUCCESS;
965 if( *Length >= sizeof( FILE_INTERNAL_INFORMATION))
968 Buffer->IndexNumber.HighPart = Fcb->ObjectInformation->FileId.Volume;
970 Buffer->IndexNumber.LowPart = Fcb->ObjectInformation->FileId.Vnode;
972 *Length -= sizeof( FILE_INTERNAL_INFORMATION);
977 ntStatus = STATUS_BUFFER_TOO_SMALL;
984 AFSQueryEaInfo( IN PIRP Irp,
985 IN AFSDirectoryCB *DirectoryCB,
986 IN OUT PFILE_EA_INFORMATION Buffer,
990 NTSTATUS ntStatus = STATUS_SUCCESS;
992 RtlZeroMemory( Buffer,
995 if( *Length >= sizeof( FILE_EA_INFORMATION))
1000 *Length -= sizeof( FILE_EA_INFORMATION);
1005 ntStatus = STATUS_BUFFER_TOO_SMALL;
1012 AFSQueryPositionInfo( IN PIRP Irp,
1014 IN OUT PFILE_POSITION_INFORMATION Buffer,
1015 IN OUT PLONG Length)
1018 NTSTATUS ntStatus = STATUS_SUCCESS;
1019 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1021 if( *Length >= sizeof( FILE_POSITION_INFORMATION))
1024 RtlZeroMemory( Buffer,
1027 Buffer->CurrentByteOffset.QuadPart = pIrpSp->FileObject->CurrentByteOffset.QuadPart;
1029 *Length -= sizeof( FILE_POSITION_INFORMATION);
1034 ntStatus = STATUS_BUFFER_TOO_SMALL;
1041 AFSQueryAccess( IN PIRP Irp,
1043 IN OUT PFILE_ACCESS_INFORMATION Buffer,
1044 IN OUT PLONG Length)
1047 NTSTATUS ntStatus = STATUS_SUCCESS;
1049 if( *Length >= sizeof( FILE_ACCESS_INFORMATION))
1052 RtlZeroMemory( Buffer,
1055 Buffer->AccessFlags = 0;
1057 *Length -= sizeof( FILE_ACCESS_INFORMATION);
1062 ntStatus = STATUS_BUFFER_TOO_SMALL;
1069 AFSQueryMode( IN PIRP Irp,
1071 IN OUT PFILE_MODE_INFORMATION Buffer,
1072 IN OUT PLONG Length)
1075 NTSTATUS ntStatus = STATUS_SUCCESS;
1077 if( *Length >= sizeof( FILE_MODE_INFORMATION))
1080 RtlZeroMemory( Buffer,
1085 *Length -= sizeof( FILE_MODE_INFORMATION);
1090 ntStatus = STATUS_BUFFER_TOO_SMALL;
1097 AFSQueryAlignment( IN PIRP Irp,
1099 IN OUT PFILE_ALIGNMENT_INFORMATION Buffer,
1100 IN OUT PLONG Length)
1103 NTSTATUS ntStatus = STATUS_SUCCESS;
1105 if( *Length >= sizeof( FILE_ALIGNMENT_INFORMATION))
1108 RtlZeroMemory( Buffer,
1111 Buffer->AlignmentRequirement = 1;
1113 *Length -= sizeof( FILE_ALIGNMENT_INFORMATION);
1118 ntStatus = STATUS_BUFFER_TOO_SMALL;
1125 AFSQueryNameInfo( IN PIRP Irp,
1126 IN AFSDirectoryCB *DirectoryCB,
1127 IN OUT PFILE_NAME_INFORMATION Buffer,
1128 IN OUT PLONG Length)
1131 NTSTATUS ntStatus = STATUS_SUCCESS;
1132 ULONG ulCopyLength = 0;
1133 ULONG cchCopied = 0;
1134 AFSFcb *pFcb = NULL;
1135 AFSCcb *pCcb = NULL;
1136 IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1137 BOOLEAN bAddLeadingSlash = FALSE;
1138 BOOLEAN bAddTrailingSlash = FALSE;
1139 USHORT usFullNameLength = 0;
1141 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
1143 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
1145 if( *Length >= FIELD_OFFSET( FILE_NAME_INFORMATION, FileName))
1148 RtlZeroMemory( Buffer,
1151 if( pCcb->FullFileName.Length == 0 ||
1152 pCcb->FullFileName.Buffer[ 0] != L'\\')
1154 bAddLeadingSlash = TRUE;
1157 if( pFcb->ObjectInformation->FileType == AFS_FILE_TYPE_DIRECTORY &&
1158 pCcb->FullFileName.Length > 0 &&
1159 pCcb->FullFileName.Buffer[ (pCcb->FullFileName.Length/sizeof( WCHAR)) - 1] != L'\\')
1161 bAddTrailingSlash = TRUE;
1164 usFullNameLength = sizeof( WCHAR) +
1165 AFSServerName.Length +
1166 pCcb->FullFileName.Length;
1168 if( bAddLeadingSlash)
1170 usFullNameLength += sizeof( WCHAR);
1173 if( bAddTrailingSlash)
1175 usFullNameLength += sizeof( WCHAR);
1178 if( *Length >= (LONG)(FIELD_OFFSET( FILE_NAME_INFORMATION, FileName) + (LONG)usFullNameLength))
1181 ulCopyLength = (LONG)usFullNameLength;
1186 ulCopyLength = *Length - FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
1188 ntStatus = STATUS_BUFFER_OVERFLOW;
1191 Buffer->FileNameLength = (ULONG)usFullNameLength;
1193 *Length -= FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
1195 if( ulCopyLength > 0)
1198 Buffer->FileName[ 0] = L'\\';
1199 ulCopyLength -= sizeof( WCHAR);
1201 *Length -= sizeof( WCHAR);
1204 if( ulCopyLength >= AFSServerName.Length)
1207 RtlCopyMemory( &Buffer->FileName[ 1],
1208 AFSServerName.Buffer,
1209 AFSServerName.Length);
1211 ulCopyLength -= AFSServerName.Length;
1212 *Length -= AFSServerName.Length;
1213 cchCopied += AFSServerName.Length/sizeof( WCHAR);
1215 if ( ulCopyLength > 0 &&
1219 Buffer->FileName[ cchCopied] = L'\\';
1221 ulCopyLength -= sizeof( WCHAR);
1222 *Length -= sizeof( WCHAR);
1226 if( ulCopyLength >= pCcb->FullFileName.Length)
1229 RtlCopyMemory( &Buffer->FileName[ cchCopied],
1230 pCcb->FullFileName.Buffer,
1231 pCcb->FullFileName.Length);
1233 ulCopyLength -= pCcb->FullFileName.Length;
1234 *Length -= pCcb->FullFileName.Length;
1235 cchCopied += pCcb->FullFileName.Length/sizeof( WCHAR);
1237 if( ulCopyLength > 0 &&
1240 Buffer->FileName[ cchCopied] = L'\\';
1242 *Length -= sizeof( WCHAR);
1248 RtlCopyMemory( &Buffer->FileName[ cchCopied],
1249 pCcb->FullFileName.Buffer,
1252 *Length -= ulCopyLength;
1260 ntStatus = STATUS_BUFFER_TOO_SMALL;
1267 AFSQueryShortNameInfo( IN PIRP Irp,
1268 IN AFSDirectoryCB *DirectoryCB,
1269 IN OUT PFILE_NAME_INFORMATION Buffer,
1270 IN OUT PLONG Length)
1273 NTSTATUS ntStatus = STATUS_BUFFER_TOO_SMALL;
1274 ULONG ulCopyLength = 0;
1276 RtlZeroMemory( Buffer,
1279 if( DirectoryCB->NameInformation.ShortNameLength == 0)
1283 // The short name IS the long name
1286 if( *Length >= (LONG)FIELD_OFFSET( FILE_NAME_INFORMATION, FileName))
1289 if( *Length >= (LONG)(FIELD_OFFSET( FILE_NAME_INFORMATION, FileName) + (LONG)DirectoryCB->NameInformation.FileName.Length))
1292 ulCopyLength = (LONG)DirectoryCB->NameInformation.FileName.Length;
1294 ntStatus = STATUS_SUCCESS;
1299 ulCopyLength = *Length - FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
1301 ntStatus = STATUS_BUFFER_OVERFLOW;
1304 Buffer->FileNameLength = DirectoryCB->NameInformation.FileName.Length;
1306 *Length -= FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
1308 if( ulCopyLength > 0)
1311 RtlCopyMemory( Buffer->FileName,
1312 DirectoryCB->NameInformation.FileName.Buffer,
1315 *Length -= ulCopyLength;
1322 if( *Length >= (LONG)FIELD_OFFSET( FILE_NAME_INFORMATION, FileName))
1325 if( *Length >= (LONG)(FIELD_OFFSET( FILE_NAME_INFORMATION, FileName) + (LONG)DirectoryCB->NameInformation.FileName.Length))
1328 ulCopyLength = (LONG)DirectoryCB->NameInformation.ShortNameLength;
1330 ntStatus = STATUS_SUCCESS;
1335 ulCopyLength = *Length - FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
1337 ntStatus = STATUS_BUFFER_OVERFLOW;
1340 Buffer->FileNameLength = DirectoryCB->NameInformation.ShortNameLength;
1342 *Length -= FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
1344 if( ulCopyLength > 0)
1347 RtlCopyMemory( Buffer->FileName,
1348 DirectoryCB->NameInformation.ShortName,
1349 Buffer->FileNameLength);
1351 *Length -= ulCopyLength;
1360 AFSQueryNetworkInfo( IN PIRP Irp,
1361 IN AFSDirectoryCB *DirectoryCB,
1362 IN OUT PFILE_NETWORK_OPEN_INFORMATION Buffer,
1363 IN OUT PLONG Length)
1366 NTSTATUS ntStatus = STATUS_SUCCESS;
1367 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1368 AFSFcb *pFcb = NULL;
1369 AFSCcb *pCcb = NULL;
1370 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1371 AFSFileInfoCB stFileInfo;
1372 AFSDirectoryCB *pParentDirectoryCB = NULL;
1373 UNICODE_STRING uniParentPath;
1374 ULONG ulFileAttribs = 0;
1376 RtlZeroMemory( Buffer,
1379 if( *Length >= sizeof( FILE_NETWORK_OPEN_INFORMATION))
1382 ulFileAttribs = DirectoryCB->ObjectInformation->FileAttributes;
1384 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
1385 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
1387 if( DirectoryCB->ObjectInformation->FileType == AFS_FILE_TYPE_SYMLINK)
1390 pParentDirectoryCB = AFSGetParentEntry( pCcb->NameArray);
1392 AFSRetrieveParentPath( &pCcb->FullFileName,
1395 RtlZeroMemory( &stFileInfo,
1396 sizeof( AFSFileInfoCB));
1399 // Can't hold the Fcb while evaluating the path, leads to lock inversion
1402 AFSReleaseResource( &pFcb->NPFcb->Resource);
1404 if( NT_SUCCESS( AFSRetrieveFileAttributes( pParentDirectoryCB,
1411 ulFileAttribs = stFileInfo.FileAttributes;
1413 ulFileAttribs |= FILE_ATTRIBUTE_REPARSE_POINT;
1416 AFSAcquireShared( &pFcb->NPFcb->Resource,
1420 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1421 AFS_TRACE_LEVEL_VERBOSE_2,
1422 "AFSQueryNetworkInfo %wZ Type 0x%x Attrib 0x%x -> 0x%x\n",
1423 &pCcb->DirectoryCB->NameInformation.FileName,
1424 pCcb->DirectoryCB->ObjectInformation->FileType,
1425 pCcb->DirectoryCB->ObjectInformation->FileAttributes,
1428 Buffer->CreationTime.QuadPart = DirectoryCB->ObjectInformation->CreationTime.QuadPart;
1429 Buffer->LastAccessTime.QuadPart = DirectoryCB->ObjectInformation->LastAccessTime.QuadPart;
1430 Buffer->LastWriteTime.QuadPart = DirectoryCB->ObjectInformation->LastWriteTime.QuadPart;
1431 Buffer->ChangeTime.QuadPart = DirectoryCB->ObjectInformation->ChangeTime.QuadPart;
1433 Buffer->AllocationSize.QuadPart = DirectoryCB->ObjectInformation->AllocationSize.QuadPart;
1434 Buffer->EndOfFile.QuadPart = DirectoryCB->ObjectInformation->EndOfFile.QuadPart;
1436 Buffer->FileAttributes = ulFileAttribs;
1438 if( DirectoryCB->NameInformation.FileName.Buffer[ 0] == L'.' &&
1439 BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_HIDE_DOT_NAMES))
1442 if ( Buffer->FileAttributes != FILE_ATTRIBUTE_NORMAL)
1445 Buffer->FileAttributes |= FILE_ATTRIBUTE_HIDDEN;
1450 Buffer->FileAttributes = FILE_ATTRIBUTE_HIDDEN;
1454 *Length -= sizeof( FILE_NETWORK_OPEN_INFORMATION);
1459 ntStatus = STATUS_BUFFER_TOO_SMALL;
1466 AFSQueryStreamInfo( IN PIRP Irp,
1467 IN AFSDirectoryCB *DirectoryCB,
1468 IN OUT FILE_STREAM_INFORMATION *Buffer,
1469 IN OUT PLONG Length)
1472 NTSTATUS ntStatus = STATUS_BUFFER_TOO_SMALL;
1473 ULONG ulCopyLength = 0;
1474 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1476 if( *Length >= FIELD_OFFSET( FILE_STREAM_INFORMATION, StreamName))
1479 RtlZeroMemory( Buffer,
1482 Buffer->NextEntryOffset = 0;
1485 if( !BooleanFlagOn( DirectoryCB->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_DIRECTORY))
1488 if( *Length >= (LONG)(FIELD_OFFSET( FILE_STREAM_INFORMATION, StreamName) + 14)) // ::$DATA
1493 ntStatus = STATUS_SUCCESS;
1498 ulCopyLength = *Length - FIELD_OFFSET( FILE_STREAM_INFORMATION, StreamName);
1500 ntStatus = STATUS_BUFFER_OVERFLOW;
1503 Buffer->StreamNameLength = 14; // ::$DATA
1505 Buffer->StreamSize.QuadPart = DirectoryCB->ObjectInformation->EndOfFile.QuadPart;
1507 Buffer->StreamAllocationSize.QuadPart = DirectoryCB->ObjectInformation->AllocationSize.QuadPart;
1509 *Length -= FIELD_OFFSET( FILE_STREAM_INFORMATION, StreamName);
1511 if( ulCopyLength > 0)
1514 RtlCopyMemory( Buffer->StreamName,
1518 *Length -= ulCopyLength;
1524 Buffer->StreamNameLength = 0; // No stream for a directory
1526 // The response size is zero
1528 ntStatus = STATUS_SUCCESS;
1536 AFSQueryAttribTagInfo( IN PIRP Irp,
1537 IN AFSDirectoryCB *DirectoryCB,
1538 IN OUT FILE_ATTRIBUTE_TAG_INFORMATION *Buffer,
1539 IN OUT PLONG Length)
1542 NTSTATUS ntStatus = STATUS_BUFFER_TOO_SMALL;
1543 ULONG ulCopyLength = 0;
1544 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1545 AFSFcb *pFcb = NULL;
1546 AFSCcb *pCcb = NULL;
1547 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1548 AFSFileInfoCB stFileInfo;
1549 AFSDirectoryCB *pParentDirectoryCB = NULL;
1550 UNICODE_STRING uniParentPath;
1551 ULONG ulFileAttribs = 0;
1553 if( *Length >= sizeof( FILE_ATTRIBUTE_TAG_INFORMATION))
1556 RtlZeroMemory( Buffer,
1559 ulFileAttribs = DirectoryCB->ObjectInformation->FileAttributes;
1561 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
1562 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
1564 if( DirectoryCB->ObjectInformation->FileType == AFS_FILE_TYPE_SYMLINK)
1567 pParentDirectoryCB = AFSGetParentEntry( pCcb->NameArray);
1569 AFSRetrieveParentPath( &pCcb->FullFileName,
1572 RtlZeroMemory( &stFileInfo,
1573 sizeof( AFSFileInfoCB));
1576 // Can't hold the Fcb while evaluating the path, leads to lock inversion
1579 AFSReleaseResource( &pFcb->NPFcb->Resource);
1581 if( NT_SUCCESS( AFSRetrieveFileAttributes( pParentDirectoryCB,
1588 ulFileAttribs = stFileInfo.FileAttributes;
1590 ulFileAttribs |= FILE_ATTRIBUTE_REPARSE_POINT;
1593 AFSAcquireShared( &pFcb->NPFcb->Resource,
1597 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1598 AFS_TRACE_LEVEL_VERBOSE_2,
1599 "AFSAttribTagInfo %wZ Type 0x%x Attrib 0x%x -> 0x%x\n",
1600 &pCcb->DirectoryCB->NameInformation.FileName,
1601 pCcb->DirectoryCB->ObjectInformation->FileType,
1602 pCcb->DirectoryCB->ObjectInformation->FileAttributes,
1605 Buffer->FileAttributes = ulFileAttribs;
1607 if( DirectoryCB->NameInformation.FileName.Buffer[ 0] == L'.' &&
1608 BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_HIDE_DOT_NAMES))
1611 if ( Buffer->FileAttributes != FILE_ATTRIBUTE_NORMAL)
1614 Buffer->FileAttributes |= FILE_ATTRIBUTE_HIDDEN;
1619 Buffer->FileAttributes = FILE_ATTRIBUTE_HIDDEN;
1623 if( BooleanFlagOn( DirectoryCB->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_REPARSE_POINT))
1625 Buffer->ReparseTag = IO_REPARSE_TAG_SURROGATE|IO_REPARSE_TAG_OPENAFS_DFS;
1628 *Length -= sizeof( FILE_ATTRIBUTE_TAG_INFORMATION);
1630 ntStatus = STATUS_SUCCESS;
1637 AFSQueryRemoteProtocolInfo( IN PIRP Irp,
1638 IN AFSDirectoryCB *DirectoryCB,
1639 IN OUT FILE_REMOTE_PROTOCOL_INFORMATION *Buffer,
1640 IN OUT PLONG Length)
1643 NTSTATUS ntStatus = STATUS_BUFFER_TOO_SMALL;
1644 ULONG ulCopyLength = 0;
1645 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1647 if( *Length >= sizeof( FILE_REMOTE_PROTOCOL_INFORMATION))
1650 RtlZeroMemory( Buffer,
1653 Buffer->StructureVersion = 1;
1655 Buffer->StructureSize = sizeof(FILE_REMOTE_PROTOCOL_INFORMATION);
1657 Buffer->Protocol = WNNC_NET_OPENAFS;
1659 Buffer->ProtocolMajorVersion = 3;
1661 Buffer->ProtocolMinorVersion = 0;
1663 Buffer->ProtocolRevision = 0;
1665 *Length -= sizeof( FILE_REMOTE_PROTOCOL_INFORMATION);
1667 ntStatus = STATUS_SUCCESS;
1674 AFSQueryPhysicalNameInfo( IN PIRP Irp,
1675 IN AFSDirectoryCB *DirectoryCB,
1676 IN OUT PFILE_NETWORK_PHYSICAL_NAME_INFORMATION Buffer,
1677 IN OUT PLONG Length)
1680 NTSTATUS ntStatus = STATUS_SUCCESS;
1681 ULONG ulCopyLength = 0;
1682 ULONG cchCopied = 0;
1683 AFSFcb *pFcb = NULL;
1684 AFSCcb *pCcb = NULL;
1685 IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1686 BOOLEAN bAddLeadingSlash = FALSE;
1687 USHORT usFullNameLength = 0;
1689 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
1691 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
1693 if( *Length >= FIELD_OFFSET( FILE_NETWORK_PHYSICAL_NAME_INFORMATION, FileName))
1696 RtlZeroMemory( Buffer,
1699 if( pCcb->FullFileName.Length == 0 ||
1700 pCcb->FullFileName.Buffer[ 0] != L'\\')
1702 bAddLeadingSlash = TRUE;
1705 usFullNameLength = pCcb->FullFileName.Length;
1707 if( bAddLeadingSlash)
1709 usFullNameLength += sizeof( WCHAR);
1712 if( *Length >= (LONG)(FIELD_OFFSET( FILE_NETWORK_PHYSICAL_NAME_INFORMATION, FileName) + (LONG)usFullNameLength))
1714 ulCopyLength = (LONG)usFullNameLength;
1719 ulCopyLength = *Length - FIELD_OFFSET( FILE_NETWORK_PHYSICAL_NAME_INFORMATION, FileName);
1721 ntStatus = STATUS_BUFFER_OVERFLOW;
1724 Buffer->FileNameLength = (ULONG)usFullNameLength;
1726 *Length -= FIELD_OFFSET( FILE_NETWORK_PHYSICAL_NAME_INFORMATION, FileName);
1728 if( ulCopyLength > 0)
1731 if( bAddLeadingSlash)
1734 Buffer->FileName[ cchCopied] = L'\\';
1736 ulCopyLength -= sizeof( WCHAR);
1737 *Length -= sizeof( WCHAR);
1741 if( ulCopyLength >= pCcb->FullFileName.Length)
1744 RtlCopyMemory( &Buffer->FileName[ cchCopied],
1745 pCcb->FullFileName.Buffer,
1746 pCcb->FullFileName.Length);
1748 ulCopyLength -= pCcb->FullFileName.Length;
1749 *Length -= pCcb->FullFileName.Length;
1750 cchCopied += pCcb->FullFileName.Length/sizeof( WCHAR);
1755 RtlCopyMemory( &Buffer->FileName[ cchCopied],
1756 pCcb->FullFileName.Buffer,
1759 *Length -= ulCopyLength;
1766 ntStatus = STATUS_BUFFER_TOO_SMALL;
1773 AFSSetBasicInfo( IN PIRP Irp,
1774 IN AFSDirectoryCB *DirectoryCB)
1776 NTSTATUS ntStatus = STATUS_SUCCESS;
1777 PFILE_BASIC_INFORMATION pBuffer;
1778 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1779 ULONG ulNotifyFilter = 0;
1780 AFSCcb *pCcb = NULL;
1785 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
1787 pBuffer = (PFILE_BASIC_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
1789 pCcb->FileUnwindInfo.FileAttributes = (ULONG)-1;
1791 if( pBuffer->FileAttributes != (ULONGLONG)0)
1794 if( DirectoryCB->ObjectInformation->Fcb->Header.NodeTypeCode == AFS_FILE_FCB &&
1795 BooleanFlagOn( pBuffer->FileAttributes, FILE_ATTRIBUTE_DIRECTORY))
1798 try_return( ntStatus = STATUS_INVALID_PARAMETER);
1801 if( DirectoryCB->ObjectInformation->Fcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB)
1804 pBuffer->FileAttributes |= FILE_ATTRIBUTE_DIRECTORY;
1807 pCcb->FileUnwindInfo.FileAttributes = DirectoryCB->ObjectInformation->FileAttributes;
1809 DirectoryCB->ObjectInformation->FileAttributes = pBuffer->FileAttributes;
1811 ulNotifyFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
1813 SetFlag( DirectoryCB->ObjectInformation->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED);
1816 pCcb->FileUnwindInfo.CreationTime.QuadPart = (ULONGLONG)-1;
1818 if( pBuffer->CreationTime.QuadPart != (ULONGLONG)-1 &&
1819 pBuffer->CreationTime.QuadPart != (ULONGLONG)0)
1822 pCcb->FileUnwindInfo.CreationTime.QuadPart = DirectoryCB->ObjectInformation->CreationTime.QuadPart;
1824 DirectoryCB->ObjectInformation->CreationTime.QuadPart = pBuffer->CreationTime.QuadPart;
1826 ulNotifyFilter |= FILE_NOTIFY_CHANGE_CREATION;
1828 SetFlag( DirectoryCB->ObjectInformation->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_CREATE_TIME);
1831 pCcb->FileUnwindInfo.LastAccessTime.QuadPart = (ULONGLONG)-1;
1833 if( pBuffer->LastAccessTime.QuadPart != (ULONGLONG)-1 &&
1834 pBuffer->LastAccessTime.QuadPart != (ULONGLONG)0)
1837 pCcb->FileUnwindInfo.LastAccessTime.QuadPart = DirectoryCB->ObjectInformation->LastAccessTime.QuadPart;
1839 DirectoryCB->ObjectInformation->LastAccessTime.QuadPart = pBuffer->LastAccessTime.QuadPart;
1841 ulNotifyFilter |= FILE_NOTIFY_CHANGE_LAST_ACCESS;
1843 SetFlag( DirectoryCB->ObjectInformation->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_ACCESS_TIME);
1846 pCcb->FileUnwindInfo.LastWriteTime.QuadPart = (ULONGLONG)-1;
1848 if( pBuffer->LastWriteTime.QuadPart != (ULONGLONG)-1 &&
1849 pBuffer->LastWriteTime.QuadPart != (ULONGLONG)0)
1852 pCcb->FileUnwindInfo.LastWriteTime.QuadPart = DirectoryCB->ObjectInformation->LastWriteTime.QuadPart;
1854 DirectoryCB->ObjectInformation->LastWriteTime.QuadPart = pBuffer->LastWriteTime.QuadPart;
1856 ulNotifyFilter |= FILE_NOTIFY_CHANGE_LAST_WRITE;
1858 SetFlag( DirectoryCB->ObjectInformation->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_LAST_WRITE_TIME);
1861 pCcb->FileUnwindInfo.ChangeTime.QuadPart = (ULONGLONG)-1;
1863 if( pBuffer->ChangeTime.QuadPart != (ULONGLONG)-1 &&
1864 pBuffer->ChangeTime.QuadPart != (ULONGLONG)0)
1867 pCcb->FileUnwindInfo.ChangeTime.QuadPart = DirectoryCB->ObjectInformation->ChangeTime.QuadPart;
1869 DirectoryCB->ObjectInformation->ChangeTime.QuadPart = pBuffer->ChangeTime.QuadPart;
1871 ulNotifyFilter |= FILE_NOTIFY_CHANGE_LAST_ACCESS;
1873 SetFlag( DirectoryCB->ObjectInformation->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_CHANGE_TIME);
1876 if( ulNotifyFilter > 0)
1879 if( DirectoryCB->ObjectInformation->ParentObjectInformation != NULL)
1882 AFSFsRtlNotifyFullReportChange( DirectoryCB->ObjectInformation->ParentObjectInformation,
1884 (ULONG)ulNotifyFilter,
1885 (ULONG)FILE_ACTION_MODIFIED);
1898 AFSSetDispositionInfo( IN PIRP Irp,
1899 IN AFSDirectoryCB *DirectoryCB)
1901 NTSTATUS ntStatus = STATUS_SUCCESS;
1902 PFILE_DISPOSITION_INFORMATION pBuffer;
1903 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1904 AFSFcb *pFcb = NULL;
1905 AFSCcb *pCcb = NULL;
1910 pBuffer = (PFILE_DISPOSITION_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
1912 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
1914 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
1917 // Can't delete the root
1920 if( pFcb->Header.NodeTypeCode == AFS_ROOT_FCB)
1923 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1924 AFS_TRACE_LEVEL_ERROR,
1925 "AFSSetDispositionInfo Attempt to delete root entry\n");
1927 try_return( ntStatus = STATUS_CANNOT_DELETE);
1931 // If the file is read only then do not allow the delete
1934 if( BooleanFlagOn( DirectoryCB->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_READONLY))
1937 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1938 AFS_TRACE_LEVEL_ERROR,
1939 "AFSSetDispositionInfo Attempt to delete read only entry %wZ\n",
1940 &DirectoryCB->NameInformation.FileName);
1942 try_return( ntStatus = STATUS_CANNOT_DELETE);
1945 if( pBuffer->DeleteFile)
1949 // Check if the caller can delete the file
1952 ntStatus = AFSNotifyDelete( DirectoryCB,
1956 if( !NT_SUCCESS( ntStatus))
1959 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1960 AFS_TRACE_LEVEL_ERROR,
1961 "AFSSetDispositionInfo Cannot delete entry %wZ Status %08lX\n",
1962 &DirectoryCB->NameInformation.FileName,
1965 try_return( ntStatus);
1968 if( pFcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB)
1972 // Check if this is a directory that there are not currently other opens
1975 if( pFcb->ObjectInformation->Specific.Directory.ChildOpenHandleCount > 0)
1978 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1979 AFS_TRACE_LEVEL_ERROR,
1980 "AFSSetDispositionInfo Attempt to delete directory %wZ with open %u handles\n",
1981 &DirectoryCB->NameInformation.FileName,
1982 pFcb->ObjectInformation->Specific.Directory.ChildOpenHandleCount);
1984 try_return( ntStatus = STATUS_DIRECTORY_NOT_EMPTY);
1987 if( !AFSIsDirectoryEmptyForDelete( pFcb))
1990 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1991 AFS_TRACE_LEVEL_ERROR,
1992 "AFSSetDispositionInfo Attempt to delete non-empty directory %wZ\n",
1993 &DirectoryCB->NameInformation.FileName);
1995 try_return( ntStatus = STATUS_DIRECTORY_NOT_EMPTY);
1998 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1999 AFS_TRACE_LEVEL_VERBOSE,
2000 "AFSSetDispositionInfo Setting PENDING_DELETE on DirEntry %p Name %wZ\n",
2002 &DirectoryCB->NameInformation.FileName);
2004 SetFlag( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
2006 else if( pFcb->Header.NodeTypeCode == AFS_FILE_FCB)
2010 // Attempt to flush any outstanding data
2013 if( !MmFlushImageSection( &pFcb->NPFcb->SectionObjectPointers,
2017 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2018 AFS_TRACE_LEVEL_ERROR,
2019 "AFSSetDispositionInfo Failed to flush image section for delete Entry %wZ\n",
2020 &DirectoryCB->NameInformation.FileName);
2022 try_return( ntStatus = STATUS_CANNOT_DELETE);
2026 // Set PENDING_DELETE before CcPurgeCacheSection to avoid a
2027 // deadlock with Trend Micro's Enterprise anti-virus product
2028 // which attempts to open the file which is being deleted.
2031 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2032 AFS_TRACE_LEVEL_VERBOSE,
2033 "AFSSetDispositionInfo Setting PENDING_DELETE on DirEntry %p Name %wZ\n",
2035 &DirectoryCB->NameInformation.FileName);
2037 SetFlag( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
2040 // Purge the cache as well
2043 if( pFcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
2046 CcPurgeCacheSection( &pFcb->NPFcb->SectionObjectPointers,
2056 ClearFlag( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
2060 // OK, should be good to go, set the flag in the file object
2063 pIrpSp->FileObject->DeletePending = pBuffer->DeleteFile;
2074 AFSSetRenameInfo( IN PIRP Irp)
2077 NTSTATUS ntStatus = STATUS_SUCCESS;
2078 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2079 IO_STATUS_BLOCK stIoSb = {0,0};
2080 AFSFcb *pSrcFcb = NULL, *pTargetDcb = NULL, *pTargetFcb = NULL;
2081 AFSCcb *pSrcCcb = NULL, *pTargetDirCcb = NULL;
2082 PFILE_OBJECT pSrcFileObj = pIrpSp->FileObject;
2083 PFILE_OBJECT pTargetFileObj = pIrpSp->Parameters.SetFile.FileObject;
2084 PFILE_RENAME_INFORMATION pRenameInfo = NULL;
2085 UNICODE_STRING uniTargetName, uniSourceName;
2086 BOOLEAN bReplaceIfExists = FALSE;
2087 UNICODE_STRING uniShortName;
2088 AFSDirectoryCB *pTargetDirEntry = NULL;
2089 ULONG ulTargetCRC = 0;
2090 BOOLEAN bTargetEntryExists = FALSE;
2091 AFSObjectInfoCB *pSrcObject = NULL, *pTargetObject = NULL;
2092 AFSObjectInfoCB *pSrcParentObject = NULL, *pTargetParentObject = NULL;
2093 AFSFileID stNewFid, stTmpTargetFid;
2094 ULONG ulNotificationAction = 0, ulNotifyFilter = 0;
2095 UNICODE_STRING uniFullTargetPath;
2096 BOOLEAN bCommonParent = FALSE;
2097 BOOLEAN bReleaseTargetDirLock = FALSE;
2098 BOOLEAN bReleaseSourceDirLock = FALSE;
2099 PERESOURCE pSourceDirLock = NULL;
2105 bReplaceIfExists = pIrpSp->Parameters.SetFile.ReplaceIfExists;
2107 pSrcFcb = (AFSFcb *)pSrcFileObj->FsContext;
2108 pSrcCcb = (AFSCcb *)pSrcFileObj->FsContext2;
2110 pSrcObject = pSrcFcb->ObjectInformation;
2111 pSrcParentObject = pSrcFcb->ObjectInformation->ParentObjectInformation;
2114 // Perform some basic checks to ensure FS integrity
2117 if( pSrcFcb->Header.NodeTypeCode == AFS_ROOT_FCB)
2121 // Can't rename the root directory
2124 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2125 AFS_TRACE_LEVEL_ERROR,
2126 "AFSSetRenameInfo Attempt to rename root entry\n");
2128 try_return( ntStatus = STATUS_INVALID_PARAMETER);
2131 if( pSrcFcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB)
2135 // If there are any open children then fail the rename
2138 if( pSrcFcb->ObjectInformation->Specific.Directory.ChildOpenHandleCount > 0)
2141 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2142 AFS_TRACE_LEVEL_ERROR,
2143 "AFSSetRenameInfo Attempt to rename directory with open children %wZ\n",
2144 &pSrcCcb->DirectoryCB->NameInformation.FileName);
2146 try_return( ntStatus = STATUS_ACCESS_DENIED);
2151 // Extract off the final component name from the Fcb
2154 uniSourceName.Length = (USHORT)pSrcCcb->DirectoryCB->NameInformation.FileName.Length;
2155 uniSourceName.MaximumLength = uniSourceName.Length;
2157 uniSourceName.Buffer = pSrcCcb->DirectoryCB->NameInformation.FileName.Buffer;
2160 // Resolve the target fileobject
2163 if( pTargetFileObj == NULL)
2167 // This is a simple rename. Here the target directory is the same as the source parent directory
2168 // and the name is retrieved from the system buffer information
2171 pRenameInfo = (PFILE_RENAME_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
2173 pTargetParentObject = pSrcParentObject;
2175 pTargetDcb = pTargetParentObject->Fcb;
2177 uniTargetName.Length = (USHORT)pRenameInfo->FileNameLength;
2178 uniTargetName.Buffer = (PWSTR)&pRenameInfo->FileName;
2184 // So here we have the target directory taken from the targetfile object
2187 pTargetDcb = (AFSFcb *)pTargetFileObj->FsContext;
2189 pTargetDirCcb = (AFSCcb *)pTargetFileObj->FsContext2;
2191 pTargetParentObject = (AFSObjectInfoCB *)pTargetDcb->ObjectInformation;
2194 // Grab the target name which we setup in the IRP_MJ_CREATE handler. By how we set this up
2195 // it is only the target component of the rename operation
2198 uniTargetName = *((PUNICODE_STRING)&pTargetFileObj->FileName);
2202 // The quick check to see if they are not really performing a rename
2203 // Do the names match? Only do this where the parent directories are
2207 if( pTargetParentObject == pSrcParentObject)
2210 if( FsRtlAreNamesEqual( &uniTargetName,
2215 try_return( ntStatus = STATUS_SUCCESS);
2218 bCommonParent = TRUE;
2223 bCommonParent = FALSE;
2227 // We do not allow cross-volume renames to occur
2230 if( pTargetParentObject->VolumeCB != pSrcObject->VolumeCB)
2233 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2234 AFS_TRACE_LEVEL_ERROR,
2235 "AFSSetRenameInfo Attempt to rename directory to different volume %wZ\n",
2236 &pSrcCcb->DirectoryCB->NameInformation.FileName);
2238 try_return( ntStatus = STATUS_NOT_SAME_DEVICE);
2241 ulTargetCRC = AFSGenerateCRC( &uniTargetName,
2244 AFSAcquireExcl( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock,
2247 bReleaseTargetDirLock = TRUE;
2249 if( pTargetParentObject != pSrcParentObject)
2251 AFSAcquireExcl( pSrcFcb->ObjectInformation->ParentObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
2254 bReleaseSourceDirLock = TRUE;
2256 pSourceDirLock = pSrcFcb->ObjectInformation->ParentObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock;
2259 AFSLocateCaseSensitiveDirEntry( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
2263 if( pTargetDirEntry == NULL)
2267 // Missed so perform a case insensitive lookup
2270 ulTargetCRC = AFSGenerateCRC( &uniTargetName,
2273 AFSLocateCaseInsensitiveDirEntry( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
2278 if( pTargetDirEntry == NULL && RtlIsNameLegalDOS8Dot3( &uniTargetName,
2283 // Try the short name
2285 AFSLocateShortNameDirEntry( pTargetParentObject->Specific.Directory.ShortNameTree,
2291 // Increment our ref count on the dir entry
2294 if( pTargetDirEntry != NULL)
2297 ASSERT( pTargetParentObject == pTargetDirEntry->ObjectInformation->ParentObjectInformation);
2299 lCount = InterlockedIncrement( &pTargetDirEntry->OpenReferenceCount);
2301 if( !bReplaceIfExists)
2304 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2305 AFS_TRACE_LEVEL_ERROR,
2306 "AFSSetRenameInfo Attempt to rename directory with target collision %wZ Target %wZ\n",
2307 &pSrcCcb->DirectoryCB->NameInformation.FileName,
2308 &pTargetDirEntry->NameInformation.FileName);
2310 try_return( ntStatus = STATUS_OBJECT_NAME_COLLISION);
2313 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2314 AFS_TRACE_LEVEL_ERROR,
2315 "AFSSetRenameInfo Target %wZ exists DE %p Count %08lX, performing delete of target\n",
2316 &pTargetDirEntry->NameInformation.FileName,
2318 pTargetDirEntry->OpenReferenceCount);
2321 // Pull the directory entry from the parent
2324 AFSRemoveDirNodeFromParent( pTargetParentObject,
2328 bTargetEntryExists = TRUE;
2332 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2333 AFS_TRACE_LEVEL_VERBOSE,
2334 "AFSSetRenameInfo Target does NOT exist, normal rename\n");
2338 // We need to remove the DirEntry from the parent node, update the index
2339 // and reinsert it into the parent tree. Note that for entries with the
2340 // same parent we do not pull the node from the enumeration list
2343 AFSRemoveDirNodeFromParent( pSrcFcb->ObjectInformation->ParentObjectInformation,
2344 pSrcCcb->DirectoryCB,
2348 // OK, this is a simple rename. Issue the rename
2349 // request to the service.
2352 ntStatus = AFSNotifyRename( pSrcFcb->ObjectInformation,
2353 &pSrcCcb->AuthGroup,
2354 pSrcFcb->ObjectInformation->ParentObjectInformation,
2355 pTargetDcb->ObjectInformation,
2356 pSrcCcb->DirectoryCB,
2360 if( !NT_SUCCESS( ntStatus))
2364 // Attempt to re-insert the directory entry
2367 AFSInsertDirectoryNode( pSrcFcb->ObjectInformation->ParentObjectInformation,
2368 pSrcCcb->DirectoryCB,
2371 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2372 AFS_TRACE_LEVEL_ERROR,
2373 "AFSSetRenameInfo Failed rename of %wZ to target %wZ Status %08lX\n",
2374 &pSrcCcb->DirectoryCB->NameInformation.FileName,
2378 try_return( ntStatus);
2382 // Set the notification up for the source file
2385 if( pSrcCcb->DirectoryCB->ObjectInformation->ParentObjectInformation == pTargetParentObject &&
2386 !bTargetEntryExists)
2389 ulNotificationAction = FILE_ACTION_RENAMED_OLD_NAME;
2394 ulNotificationAction = FILE_ACTION_REMOVED;
2397 if( pSrcCcb->DirectoryCB->ObjectInformation->FileType == AFS_FILE_TYPE_DIRECTORY)
2400 ulNotifyFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
2405 ulNotifyFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
2408 AFSFsRtlNotifyFullReportChange( pSrcCcb->DirectoryCB->ObjectInformation->ParentObjectInformation,
2410 (ULONG)ulNotifyFilter,
2411 (ULONG)ulNotificationAction);
2414 // Update the name in the dir entry.
2417 ntStatus = AFSUpdateDirEntryName( pSrcCcb->DirectoryCB,
2420 if( !NT_SUCCESS( ntStatus))
2424 // Attempt to re-insert the directory entry
2427 AFSInsertDirectoryNode( pSrcFcb->ObjectInformation->ParentObjectInformation,
2428 pSrcCcb->DirectoryCB,
2431 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2432 AFS_TRACE_LEVEL_ERROR,
2433 "AFSSetRenameInfo Failed update of dir entry %wZ to target %wZ Status %08lX\n",
2434 &pSrcCcb->DirectoryCB->NameInformation.FileName,
2438 try_return( ntStatus);
2442 // Update the object information block, if needed
2445 if( !AFSIsEqualFID( &pSrcObject->FileId,
2449 AFSAcquireExcl( pSrcObject->VolumeCB->ObjectInfoTree.TreeLock,
2453 // Remove the old information entry
2456 AFSRemoveHashEntry( &pSrcObject->VolumeCB->ObjectInfoTree.TreeHead,
2457 &pSrcObject->TreeEntry);
2459 RtlCopyMemory( &pSrcObject->FileId,
2461 sizeof( AFSFileID));
2464 // Insert the entry into the new object table.
2467 pSrcObject->TreeEntry.HashIndex = AFSCreateLowIndex( &pSrcObject->FileId);
2469 if( pSrcObject->VolumeCB->ObjectInfoTree.TreeHead == NULL)
2472 pSrcObject->VolumeCB->ObjectInfoTree.TreeHead = &pSrcObject->TreeEntry;
2477 if ( !NT_SUCCESS( AFSInsertHashEntry( pSrcObject->VolumeCB->ObjectInfoTree.TreeHead,
2478 &pSrcObject->TreeEntry)))
2482 // Lost a race, an ObjectInfo object already exists for this FID.
2483 // Let this copy be garbage collected.
2486 ClearFlag( pSrcObject->Flags, AFS_OBJECT_INSERTED_HASH_TREE);
2490 AFSReleaseResource( pSrcObject->VolumeCB->ObjectInfoTree.TreeLock);
2494 // Update the hash values for the name trees.
2497 pSrcCcb->DirectoryCB->CaseSensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pSrcCcb->DirectoryCB->NameInformation.FileName,
2500 pSrcCcb->DirectoryCB->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pSrcCcb->DirectoryCB->NameInformation.FileName,
2503 if( pSrcCcb->DirectoryCB->NameInformation.ShortNameLength > 0 &&
2504 !RtlIsNameLegalDOS8Dot3( &pSrcCcb->DirectoryCB->NameInformation.FileName,
2509 uniShortName.Length = pSrcCcb->DirectoryCB->NameInformation.ShortNameLength;
2510 uniShortName.MaximumLength = uniShortName.Length;
2511 uniShortName.Buffer = pSrcCcb->DirectoryCB->NameInformation.ShortName;
2513 pSrcCcb->DirectoryCB->Type.Data.ShortNameTreeEntry.HashIndex = AFSGenerateCRC( &uniShortName,
2516 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2517 AFS_TRACE_LEVEL_VERBOSE,
2518 "AFSSetRenameInfo Initialized short name hash for %wZ longname %wZ\n",
2520 &pSrcCcb->DirectoryCB->NameInformation.FileName);
2525 pSrcCcb->DirectoryCB->Type.Data.ShortNameTreeEntry.HashIndex = 0;
2532 // Update the file index for the object in the new parent
2535 pSrcCcb->DirectoryCB->FileIndex = (ULONG)InterlockedIncrement( &pTargetParentObject->Specific.Directory.DirectoryNodeHdr.ContentIndex);
2539 // Re-insert the directory entry
2542 AFSInsertDirectoryNode( pTargetParentObject,
2543 pSrcCcb->DirectoryCB,
2547 // Update the parent pointer in the source object if they are different
2550 if( pSrcCcb->DirectoryCB->ObjectInformation->ParentObjectInformation != pTargetParentObject)
2553 lCount = InterlockedDecrement( &pSrcCcb->DirectoryCB->ObjectInformation->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);
2555 lCount = InterlockedDecrement( &pSrcCcb->DirectoryCB->ObjectInformation->ParentObjectInformation->Specific.Directory.ChildOpenReferenceCount);
2557 lCount = InterlockedIncrement( &pTargetParentObject->Specific.Directory.ChildOpenHandleCount);
2559 lCount = InterlockedIncrement( &pTargetParentObject->Specific.Directory.ChildOpenReferenceCount);
2561 pSrcCcb->DirectoryCB->ObjectInformation->ParentObjectInformation = pTargetParentObject;
2563 ulNotificationAction = FILE_ACTION_ADDED;
2568 ulNotificationAction = FILE_ACTION_RENAMED_NEW_NAME;
2572 // Now update the notification for the target file
2575 AFSFsRtlNotifyFullReportChange( pTargetParentObject->ParentObjectInformation,
2577 (ULONG)ulNotifyFilter,
2578 (ULONG)ulNotificationAction);
2581 // If we performed the rename of the target because it existed, we now need to
2582 // delete the tmp target we created above
2585 if( bTargetEntryExists)
2588 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2589 AFS_TRACE_LEVEL_VERBOSE,
2590 "AFSSetRenameInfo Setting DELETE flag in dir entry %p name %wZ\n",
2592 &pTargetDirEntry->NameInformation.FileName);
2594 SetFlag( pTargetDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
2597 // Try and purge the cache map if this is a file
2600 if( pTargetDirEntry->ObjectInformation->FileType == AFS_FILE_TYPE_FILE &&
2601 pTargetDirEntry->ObjectInformation->Fcb != NULL &&
2602 pTargetDirEntry->OpenReferenceCount > 1)
2605 pTargetFcb = pTargetDirEntry->ObjectInformation->Fcb;
2607 AFSAcquireExcl( &pTargetFcb->NPFcb->Resource,
2611 // Close the section in the event it was mapped
2614 if( !MmForceSectionClosed( &pTargetFcb->NPFcb->SectionObjectPointers,
2618 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2619 AFS_TRACE_LEVEL_ERROR,
2620 "AFSSetRenameInfo Failed to delete section for target file %wZ\n",
2621 &pTargetDirEntry->NameInformation.FileName);
2624 AFSReleaseResource( &pTargetFcb->NPFcb->Resource);
2627 ASSERT( pTargetDirEntry->OpenReferenceCount > 0);
2629 lCount = InterlockedDecrement( &pTargetDirEntry->OpenReferenceCount); // The count we added above
2634 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2635 AFS_TRACE_LEVEL_VERBOSE,
2636 "AFSSetRenameInfo Deleting dir entry %p name %wZ\n",
2638 &pTargetDirEntry->NameInformation.FileName);
2640 AFSDeleteDirEntry( pTargetParentObject,
2644 pTargetDirEntry = NULL;
2650 if( !NT_SUCCESS( ntStatus))
2653 if( bTargetEntryExists)
2655 AFSInsertDirectoryNode( pTargetDirEntry->ObjectInformation->ParentObjectInformation,
2661 if( pTargetDirEntry != NULL)
2664 lCount = InterlockedDecrement( &pTargetDirEntry->OpenReferenceCount);
2667 if( bReleaseTargetDirLock)
2669 AFSReleaseResource( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.TreeLock);
2672 if( bReleaseSourceDirLock)
2674 AFSReleaseResource( pSourceDirLock);
2682 AFSSetPositionInfo( IN PIRP Irp,
2683 IN AFSDirectoryCB *DirectoryCB)
2685 NTSTATUS ntStatus = STATUS_SUCCESS;
2686 PFILE_POSITION_INFORMATION pBuffer;
2687 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2689 pBuffer = (PFILE_POSITION_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
2691 pIrpSp->FileObject->CurrentByteOffset.QuadPart = pBuffer->CurrentByteOffset.QuadPart;
2697 AFSSetAllocationInfo( IN PIRP Irp,
2698 IN AFSDirectoryCB *DirectoryCB)
2700 NTSTATUS ntStatus = STATUS_SUCCESS;
2701 PFILE_ALLOCATION_INFORMATION pBuffer;
2702 BOOLEAN bReleasePaging = FALSE;
2703 BOOLEAN bTellCc = FALSE;
2704 BOOLEAN bTellService = FALSE;
2705 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2706 PFILE_OBJECT pFileObject = pIrpSp->FileObject;
2707 AFSFcb *pFcb = NULL;
2708 AFSCcb *pCcb = NULL;
2709 LARGE_INTEGER liSaveAlloc;
2710 LARGE_INTEGER liSaveFileSize;
2711 LARGE_INTEGER liSaveVDL;
2713 pBuffer = (PFILE_ALLOCATION_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
2715 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
2717 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
2720 // save values to put back
2722 liSaveAlloc = pFcb->Header.AllocationSize;
2723 liSaveFileSize = pFcb->Header.FileSize;
2724 liSaveVDL = pFcb->Header.ValidDataLength;
2726 if( pFcb->Header.AllocationSize.QuadPart == pBuffer->AllocationSize.QuadPart ||
2727 pIrpSp->Parameters.SetFile.AdvanceOnly)
2729 return STATUS_SUCCESS ;
2732 if( pFcb->Header.AllocationSize.QuadPart > pBuffer->AllocationSize.QuadPart)
2735 // Truncating the file
2737 if( !MmCanFileBeTruncated( pFileObject->SectionObjectPointer,
2738 &pBuffer->AllocationSize))
2741 ntStatus = STATUS_USER_MAPPED_FILE ;
2746 // If this is a truncation we need to grab the paging IO resource.
2748 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2749 AFS_TRACE_LEVEL_VERBOSE,
2750 "AFSSetAllocationInfo Acquiring Fcb PagingIo lock %08lX EXCL %08lX\n",
2751 &pFcb->NPFcb->PagingResource,
2752 PsGetCurrentThread());
2754 AFSAcquireExcl( &pFcb->NPFcb->PagingResource,
2757 bReleasePaging = TRUE;
2760 pFcb->Header.AllocationSize = pBuffer->AllocationSize;
2762 pFcb->ObjectInformation->AllocationSize = pBuffer->AllocationSize;
2765 // Tell Cc that Allocation is moved.
2769 if( pFcb->Header.FileSize.QuadPart > pBuffer->AllocationSize.QuadPart)
2772 // We are pulling the EOF back as well so we need to tell
2775 bTellService = TRUE;
2777 pFcb->Header.FileSize = pBuffer->AllocationSize;
2779 pFcb->ObjectInformation->EndOfFile = pBuffer->AllocationSize;
2787 // Tell Cc if allocation is increased.
2789 bTellCc = pBuffer->AllocationSize.QuadPart > pFcb->Header.AllocationSize.QuadPart;
2791 pFcb->Header.AllocationSize = pBuffer->AllocationSize;
2793 pFcb->ObjectInformation->AllocationSize = pBuffer->AllocationSize;
2797 // Now Tell the server if we have to
2801 ntStatus = AFSUpdateFileInformation( &pFcb->ObjectInformation->ParentObjectInformation->FileId,
2802 pFcb->ObjectInformation,
2806 if (NT_SUCCESS(ntStatus))
2809 // Trim extents if we told the service - the update has done an implicit
2810 // trim at the service.
2814 AFSTrimExtents( pFcb,
2815 &pFcb->Header.FileSize);
2818 KeQuerySystemTime( &pFcb->ObjectInformation->ChangeTime);
2820 SetFlag( pFcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_CHANGE_TIME);
2823 CcIsFileCached( pFileObject))
2825 CcSetFileSizes( pFileObject,
2826 (PCC_FILE_SIZES)&pFcb->Header.AllocationSize);
2832 // Put the saved values back
2834 pFcb->Header.ValidDataLength = liSaveVDL;
2835 pFcb->Header.FileSize = liSaveFileSize;
2836 pFcb->Header.AllocationSize = liSaveAlloc;
2837 pFcb->ObjectInformation->EndOfFile = liSaveFileSize;
2838 pFcb->ObjectInformation->AllocationSize = liSaveAlloc;
2844 AFSReleaseResource( &pFcb->NPFcb->PagingResource);
2851 AFSSetEndOfFileInfo( IN PIRP Irp,
2852 IN AFSDirectoryCB *DirectoryCB)
2854 NTSTATUS ntStatus = STATUS_SUCCESS;
2855 PFILE_END_OF_FILE_INFORMATION pBuffer;
2856 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2857 PFILE_OBJECT pFileObject = pIrpSp->FileObject;
2858 LARGE_INTEGER liSaveSize;
2859 LARGE_INTEGER liSaveVDL;
2860 LARGE_INTEGER liSaveAlloc;
2861 BOOLEAN bModified = FALSE;
2862 BOOLEAN bReleasePaging = FALSE;
2863 BOOLEAN bTruncated = FALSE;
2864 AFSFcb *pFcb = NULL;
2865 AFSCcb *pCcb = NULL;
2867 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
2869 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
2871 pBuffer = (PFILE_END_OF_FILE_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
2873 liSaveSize = pFcb->Header.FileSize;
2874 liSaveAlloc = pFcb->Header.AllocationSize;
2875 liSaveVDL = pFcb->Header.ValidDataLength;
2877 if( pFcb->Header.FileSize.QuadPart != pBuffer->EndOfFile.QuadPart &&
2878 !pIrpSp->Parameters.SetFile.AdvanceOnly)
2881 if( pBuffer->EndOfFile.QuadPart < pFcb->Header.FileSize.QuadPart)
2884 // Truncating the file
2885 if( !MmCanFileBeTruncated( pFileObject->SectionObjectPointer,
2886 &pBuffer->EndOfFile))
2889 ntStatus = STATUS_USER_MAPPED_FILE;
2894 // If this is a truncation we need to grab the paging
2897 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2898 AFS_TRACE_LEVEL_VERBOSE,
2899 "AFSSetAllocationInfo Acquiring Fcb PagingIo lock %08lX EXCL %08lX\n",
2900 &pFcb->NPFcb->PagingResource,
2901 PsGetCurrentThread());
2903 AFSAcquireExcl( &pFcb->NPFcb->PagingResource,
2906 bReleasePaging = TRUE;
2908 pFcb->Header.AllocationSize = pBuffer->EndOfFile;
2910 pFcb->Header.FileSize = pBuffer->EndOfFile;
2912 pFcb->ObjectInformation->EndOfFile = pBuffer->EndOfFile;
2914 pFcb->ObjectInformation->AllocationSize = pBuffer->EndOfFile;
2916 if( pFcb->Header.ValidDataLength.QuadPart > pFcb->Header.FileSize.QuadPart)
2919 pFcb->Header.ValidDataLength = pFcb->Header.FileSize;
2930 // extending the file, move EOF
2933 pFcb->Header.FileSize = pBuffer->EndOfFile;
2935 pFcb->ObjectInformation->EndOfFile = pBuffer->EndOfFile;
2937 if (pFcb->Header.FileSize.QuadPart > pFcb->Header.AllocationSize.QuadPart)
2940 // And Allocation as needed.
2942 pFcb->Header.AllocationSize = pBuffer->EndOfFile;
2944 pFcb->ObjectInformation->AllocationSize = pBuffer->EndOfFile;
2954 KeQuerySystemTime( &pFcb->ObjectInformation->ChangeTime);
2956 SetFlag( pFcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED | AFS_FCB_FLAG_UPDATE_CHANGE_TIME);
2962 ntStatus = AFSUpdateFileInformation( &pFcb->ObjectInformation->ParentObjectInformation->FileId,
2963 pFcb->ObjectInformation,
2966 if( NT_SUCCESS(ntStatus))
2969 // We are now good to go so tell CC.
2971 CcSetFileSizes( pFileObject,
2972 (PCC_FILE_SIZES)&pFcb->Header.AllocationSize);
2975 // And give up those extents
2980 AFSTrimExtents( pFcb,
2981 &pFcb->Header.FileSize);
2986 pFcb->Header.ValidDataLength = liSaveVDL;
2987 pFcb->Header.FileSize = liSaveSize;
2988 pFcb->Header.AllocationSize = liSaveAlloc;
2989 pFcb->ObjectInformation->EndOfFile = liSaveSize;
2990 pFcb->ObjectInformation->AllocationSize = liSaveAlloc;
2997 AFSReleaseResource( &pFcb->NPFcb->PagingResource);
3004 AFSProcessShareSetInfo( IN IRP *Irp,
3009 NTSTATUS ntStatus = STATUS_SUCCESS;
3010 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
3011 ULONG ulOutputBufferLen = 0, ulInputBufferLen;
3012 FILE_INFORMATION_CLASS ulFileInformationClass;
3013 void *pPipeInfo = NULL;
3017 ulFileInformationClass = pIrpSp->Parameters.SetFile.FileInformationClass;
3019 AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
3020 AFS_TRACE_LEVEL_VERBOSE,
3021 "AFSProcessShareSetInfo On pipe %wZ Class %08lX\n",
3022 &Ccb->DirectoryCB->NameInformation.FileName,
3023 ulFileInformationClass);
3025 pPipeInfo = AFSLockSystemBuffer( Irp,
3026 pIrpSp->Parameters.SetFile.Length);
3028 if( pPipeInfo == NULL)
3031 AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
3032 AFS_TRACE_LEVEL_ERROR,
3033 "AFSProcessShareSetInfo Failed to lock buffer on pipe %wZ\n",
3034 &Ccb->DirectoryCB->NameInformation.FileName);
3036 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
3040 // Send the request to the service
3043 ntStatus = AFSNotifySetPipeInfo( Ccb,
3044 (ULONG)ulFileInformationClass,
3045 pIrpSp->Parameters.SetFile.Length,
3048 if( !NT_SUCCESS( ntStatus))
3051 AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
3052 AFS_TRACE_LEVEL_ERROR,
3053 "AFSProcessShareSetInfo Failed to send request to service on pipe %wZ Status %08lX\n",
3054 &Ccb->DirectoryCB->NameInformation.FileName,
3057 try_return( ntStatus);
3060 AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
3061 AFS_TRACE_LEVEL_VERBOSE,
3062 "AFSProcessShareSetInfo Completed request on pipe %wZ Class %08lX\n",
3063 &Ccb->DirectoryCB->NameInformation.FileName,
3064 ulFileInformationClass);
3075 AFSProcessShareQueryInfo( IN IRP *Irp,
3080 NTSTATUS ntStatus = STATUS_SUCCESS;
3081 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
3082 ULONG ulOutputBufferLen = 0, ulInputBufferLen;
3083 FILE_INFORMATION_CLASS ulFileInformationClass;
3084 void *pPipeInfo = NULL;
3089 ulFileInformationClass = pIrpSp->Parameters.QueryFile.FileInformationClass;
3091 AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
3092 AFS_TRACE_LEVEL_VERBOSE,
3093 "AFSProcessShareQueryInfo On pipe %wZ Class %08lX\n",
3094 &Ccb->DirectoryCB->NameInformation.FileName,
3095 ulFileInformationClass);
3097 pPipeInfo = AFSLockSystemBuffer( Irp,
3098 pIrpSp->Parameters.QueryFile.Length);
3100 if( pPipeInfo == NULL)
3103 AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
3104 AFS_TRACE_LEVEL_ERROR,
3105 "AFSProcessShareQueryInfo Failed to lock buffer on pipe %wZ\n",
3106 &Ccb->DirectoryCB->NameInformation.FileName);
3108 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
3112 // Send the request to the service
3115 ntStatus = AFSNotifyQueryPipeInfo( Ccb,
3116 (ULONG)ulFileInformationClass,
3117 pIrpSp->Parameters.QueryFile.Length,
3119 (ULONG *)&Irp->IoStatus.Information);
3121 if( !NT_SUCCESS( ntStatus))
3124 AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
3125 AFS_TRACE_LEVEL_ERROR,
3126 "AFSProcessShareQueryInfo Failed to send request to service on pipe %wZ Status %08lX\n",
3127 &Ccb->DirectoryCB->NameInformation.FileName,
3130 try_return( ntStatus);
3133 AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
3134 AFS_TRACE_LEVEL_VERBOSE,
3135 "AFSProcessShareQueryInfo Completed request on pipe %wZ Class %08lX\n",
3136 &Ccb->DirectoryCB->NameInformation.FileName,
3137 ulFileInformationClass);
3148 AFSProcessPIOCtlQueryInfo( IN IRP *Irp,
3151 IN OUT LONG *Length)
3154 NTSTATUS ntStatus = STATUS_SUCCESS;
3155 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
3156 FILE_INFORMATION_CLASS ulFileInformationClass;
3161 ulFileInformationClass = pIrpSp->Parameters.QueryFile.FileInformationClass;
3163 switch( ulFileInformationClass)
3166 case FileBasicInformation:
3169 AFSDbgLogMsg( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
3170 AFS_TRACE_LEVEL_VERBOSE,
3171 "AFSProcessPIOCtlQueryInfo (FileBasicInformation)\n");
3173 if ( *Length >= sizeof( FILE_BASIC_INFORMATION))
3175 PFILE_BASIC_INFORMATION pBasic = (PFILE_BASIC_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
3177 pBasic->CreationTime.QuadPart = 0;
3178 pBasic->LastAccessTime.QuadPart = 0;
3179 pBasic->ChangeTime.QuadPart = 0;
3180 pBasic->LastWriteTime.QuadPart = 0;
3181 pBasic->FileAttributes = FILE_ATTRIBUTE_SYSTEM;
3183 *Length -= sizeof( FILE_BASIC_INFORMATION);
3187 ntStatus = STATUS_BUFFER_TOO_SMALL;
3193 case FileStandardInformation:
3196 AFSDbgLogMsg( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
3197 AFS_TRACE_LEVEL_VERBOSE,
3198 "AFSProcessPIOCtlQueryInfo (FileStandardInformation)\n");
3200 if ( *Length >= sizeof( FILE_STANDARD_INFORMATION))
3202 PFILE_STANDARD_INFORMATION pStandard = (PFILE_STANDARD_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
3204 pStandard->NumberOfLinks = 1;
3205 pStandard->DeletePending = 0;
3206 pStandard->AllocationSize.QuadPart = 0;
3207 pStandard->EndOfFile.QuadPart = 0;
3208 pStandard->Directory = 0;
3210 *Length -= sizeof( FILE_STANDARD_INFORMATION);
3214 ntStatus = STATUS_BUFFER_TOO_SMALL;
3220 case FileNameInformation:
3223 ULONG ulCopyLength = 0;
3224 AFSFcb *pFcb = NULL;
3225 AFSCcb *pCcb = NULL;
3226 USHORT usFullNameLength = 0;
3227 PFILE_NAME_INFORMATION pNameInfo = (PFILE_NAME_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
3228 UNICODE_STRING uniName;
3230 AFSDbgLogMsg( AFS_SUBSYSTEM_PIOCTL_PROCESSING,
3231 AFS_TRACE_LEVEL_VERBOSE,
3232 "AFSProcessPIOCtlQueryInfo (FileNameInformation)\n");
3234 pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
3235 pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
3237 if( *Length < FIELD_OFFSET( FILE_NAME_INFORMATION, FileName))
3239 ntStatus = STATUS_BUFFER_TOO_SMALL;
3243 RtlZeroMemory( pNameInfo,
3246 usFullNameLength = sizeof( WCHAR) +
3247 AFSServerName.Length +
3248 pCcb->FullFileName.Length;
3250 if( *Length >= (LONG)(FIELD_OFFSET( FILE_NAME_INFORMATION, FileName) + (LONG)usFullNameLength))
3252 ulCopyLength = (LONG)usFullNameLength;
3256 ulCopyLength = *Length - FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
3257 ntStatus = STATUS_BUFFER_OVERFLOW;
3260 pNameInfo->FileNameLength = (ULONG)usFullNameLength;
3262 *Length -= FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
3264 if( ulCopyLength > 0)