@@ -789,15 +789,18 @@ NTSTATUS
789789P4vfsGetFileIdByFileName (
790790 _In_opt_ PFLT_INSTANCE pFltInstance ,
791791 _In_ PUNICODE_STRING pFileName ,
792- __out PLONGLONG pFileId
792+ _Out_ PUNICODE_STRING pOutFileIdPath
793793 )
794794{
795795 NTSTATUS status = STATUS_SUCCESS ;
796796 IO_STATUS_BLOCK ioStatus = {0 };
797797 OBJECT_ATTRIBUTES objAttributes = {0 };
798798 HANDLE hLocalFile = NULL ;
799799 PFILE_OBJECT pLocalFileObject = NULL ;
800- FILE_INTERNAL_INFORMATION internalInfo = {0 };
800+ FILE_ID_INFORMATION fileIdInfo = {0 };
801+ PFLT_VOLUME pVolume = NULL ;
802+ PFLT_INSTANCE pVolumeInstance = NULL ;
803+ UNICODE_STRING fileIdPath = {0 };
801804
802805 PAGED_CODE ();
803806
@@ -808,47 +811,73 @@ P4vfsGetFileIdByFileName(
808811 goto CLEANUP ;
809812 }
810813
811- if (pFileId == NULL )
814+ if (pOutFileIdPath == NULL )
812815 {
813816 status = STATUS_INVALID_PARAMETER ;
814- P4vfsTraceError (Core , L"P4vfsGetFileIdByFileName: pFileId is NULL" );
817+ P4vfsTraceError (Core , L"P4vfsGetFileIdByFileName: pOutFileIdPath is NULL" );
815818 goto CLEANUP ;
816819 }
817820
818821 InitializeObjectAttributes (& objAttributes ,
819- pFileName ,
820- OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE ,
821- NULL ,
822- NULL );
822+ pFileName ,
823+ OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE ,
824+ NULL ,
825+ NULL );
823826
824827 status = FltCreateFileEx2 (g_FltContext .pFilter ,
825- pFltInstance ,
826- & hLocalFile ,
827- & pLocalFileObject ,
828- 0 ,
829- & objAttributes ,
830- & ioStatus ,
831- NULL ,
832- FILE_ATTRIBUTE_NORMAL ,
833- FILE_SHARE_VALID_FLAGS ,
834- FILE_OPEN ,
835- FILE_NON_DIRECTORY_FILE | FILE_OPEN_REPARSE_POINT ,
836- NULL ,
837- 0 ,
838- IO_IGNORE_SHARE_ACCESS_CHECK ,
839- NULL );
828+ pFltInstance ,
829+ & hLocalFile ,
830+ & pLocalFileObject ,
831+ 0 ,
832+ & objAttributes ,
833+ & ioStatus ,
834+ NULL ,
835+ FILE_ATTRIBUTE_NORMAL ,
836+ FILE_SHARE_VALID_FLAGS ,
837+ FILE_OPEN ,
838+ FILE_NON_DIRECTORY_FILE | FILE_OPEN_REPARSE_POINT ,
839+ NULL ,
840+ 0 ,
841+ IO_IGNORE_SHARE_ACCESS_CHECK ,
842+ NULL );
840843
841844 if (!NT_SUCCESS (status ))
842845 {
843846 P4vfsTraceError (Core , L"P4vfsGetFileIdByFileName: FltCreateFileEx2 failed [%wZ] [%!STATUS!]" , pFileName , status );
844847 goto CLEANUP ;
845848 }
846849
850+ status = FltGetVolumeFromFileObject (g_FltContext .pFilter ,
851+ pLocalFileObject ,
852+ & pVolume );
853+
854+ if (!NT_SUCCESS (status ))
855+ {
856+ P4vfsTraceError (Core , L"P4vfsGetFileIdByFileName: FltGetVolumeFromFileObject failed [%wZ] [%!STATUS!]" , pFileName , status );
857+ goto CLEANUP ;
858+ }
859+
860+ if (pFltInstance == NULL )
861+ {
862+ status = FltGetVolumeInstanceFromName (g_FltContext .pFilter ,
863+ pVolume ,
864+ NULL ,
865+ & pVolumeInstance );
866+
867+ if (!NT_SUCCESS (status ) || pVolumeInstance == NULL )
868+ {
869+ P4vfsTraceError (Core , L"P4vfsGetFileIdByFileName: FltGetVolumeInstanceFromName failed [%wZ] [%!STATUS!]" , pFileName , status );
870+ goto CLEANUP ;
871+ }
872+
873+ pFltInstance = pVolumeInstance ;
874+ }
875+
847876 status = FltQueryInformationFile (pFltInstance ,
848877 pLocalFileObject ,
849- & internalInfo ,
850- sizeof (internalInfo ),
851- FileInternalInformation ,
878+ & fileIdInfo ,
879+ sizeof (FILE_ID_INFORMATION ),
880+ FileIdInformation ,
852881 NULL );
853882
854883 if (!NT_SUCCESS (status ))
@@ -857,7 +886,56 @@ P4vfsGetFileIdByFileName(
857886 goto CLEANUP ;
858887 }
859888
860- * pFileId = internalInfo .IndexNumber .QuadPart ;
889+ ULONG volumeNameLengthRequired = 0 ;
890+ status = FltGetVolumeName (pVolume , NULL , & volumeNameLengthRequired );
891+ if (!NT_SUCCESS (status ) && (status != STATUS_BUFFER_TOO_SMALL ))
892+ {
893+ P4vfsTraceError (Core , L"P4vfsGetFileIdByFileName: FltGetVolumeName length query failed [%wZ] [%!STATUS!]" , pFileName , status );
894+ goto CLEANUP ;
895+ }
896+
897+ status = RtlUShortAdd ((USHORT )volumeNameLengthRequired , sizeof (WCHAR )+ sizeof (fileIdInfo .FileId ), & fileIdPath .MaximumLength );
898+ if (!NT_SUCCESS (status ))
899+ {
900+ P4vfsTraceError (Core , L"P4vfsGetFileIdByFileName: RtlUShortAdd failed [%wZ] [%!STATUS!]" , pFileName , status );
901+ goto CLEANUP ;
902+ }
903+
904+ status = P4vfsAllocateUnicodeString (P4VFS_FILE_NAME_ALLOC_TAG , & fileIdPath );
905+ if (!NT_SUCCESS (status ))
906+ {
907+ P4vfsTraceError (Core , L"P4vfsGetFileIdByFileName: P4vfsAllocateUnicodeString failed [%wZ] [%!STATUS!]" , pFileName , status );
908+ goto CLEANUP ;
909+ }
910+
911+ status = FltGetVolumeName (pVolume , & fileIdPath , & volumeNameLengthRequired );
912+ if (!NT_SUCCESS (status ))
913+ {
914+ P4vfsTraceError (Core , L"P4vfsGetFileIdByFileName: FltGetVolumeName failed [%wZ] [%!STATUS!]" , pFileName , status );
915+ goto CLEANUP ;
916+ }
917+
918+ status = RtlAppendUnicodeToString (& fileIdPath , L"\\" );
919+ if (!NT_SUCCESS (status ))
920+ {
921+ P4vfsTraceError (Core , L"P4vfsGetFileIdByFileName: RtlAppendUnicodeToString separator failed [%wZ] fileIdPath [%wZ] [%!STATUS!]" , pFileName , & fileIdPath , status );
922+ goto CLEANUP ;
923+ }
924+
925+ UNICODE_STRING fileIdString ;
926+ fileIdString .Length = sizeof (fileIdInfo .FileId );
927+ fileIdString .MaximumLength = sizeof (fileIdInfo .FileId );
928+ fileIdString .Buffer = (PWCHAR )& fileIdInfo .FileId ;
929+
930+ status = RtlAppendUnicodeStringToString (& fileIdPath , & fileIdString );
931+ if (!NT_SUCCESS (status ))
932+ {
933+ P4vfsTraceError (Core , L"P4vfsGetFileIdByFileName: RtlAppendUnicodeToString fileIdString failed [%wZ] fileIdPath [%wZ] [%!STATUS!]" , pFileName , & fileIdPath , status );
934+ goto CLEANUP ;
935+ }
936+
937+ * pOutFileIdPath = fileIdPath ;
938+ fileIdPath .Buffer = NULL ;
861939
862940CLEANUP :
863941 if (hLocalFile != NULL )
@@ -870,6 +948,21 @@ P4vfsGetFileIdByFileName(
870948 ObDereferenceObject (pLocalFileObject );
871949 }
872950
951+ if (pVolume != NULL )
952+ {
953+ FltObjectDereference (pVolume );
954+ }
955+
956+ if (pVolumeInstance != NULL )
957+ {
958+ FltObjectDereference (pVolumeInstance );
959+ }
960+
961+ if (fileIdPath .Buffer != NULL )
962+ {
963+ ExFreePoolWithTag (fileIdPath .Buffer , P4VFS_FILE_NAME_ALLOC_TAG );
964+ }
965+
873966 return status ;
874967}
875968
@@ -889,80 +982,20 @@ P4vfsOpenReparsePoint(
889982 IO_DRIVER_CREATE_CONTEXT createContext = {0 };
890983 HANDLE hLocalFile = NULL ;
891984 PFILE_OBJECT pLocalFileObject = NULL ;
892- LONGLONG fileId = 0 ;
893985 UNICODE_STRING fileIdPath = {0 };
894- PFLT_VOLUME volume = NULL ;
895986
896987 PAGED_CODE ();
897988
898989 // We wish to open an existing reparse point file by using FILE_OPEN_BY_FILE_ID so as to avoid
899990 // directory notifications. Begin by finding the unique fileId by file path.
900991
901- status = P4vfsGetFileIdByFileName (pFltInstance , pFileName , & fileId );
992+ status = P4vfsGetFileIdByFileName (pFltInstance , pFileName , & fileIdPath );
902993 if (!NT_SUCCESS (status ))
903994 {
904995 P4vfsTraceError (Core , L"P4vfsOpenReparsePoint: P4vfsGetFileIdByFileName failed [%wZ] [%!STATUS!]" , pFileName , status );
905996 goto CLEANUP ;
906997 }
907998
908- // We will compose the fileIdPath with the current volume of this filter instance.
909-
910- status = FltGetVolumeFromInstance (pFltInstance , & volume );
911- if (!NT_SUCCESS (status ))
912- {
913- P4vfsTraceError (Core , L"P4vfsOpenReparsePoint: FltGetVolumeFromInstance failed [%wZ] [%!STATUS!]" , pFileName , status );
914- goto CLEANUP ;
915- }
916-
917- ULONG volumeNameLengthRequired = 0 ;
918- status = FltGetVolumeName (volume , NULL , & volumeNameLengthRequired );
919- if (!NT_SUCCESS (status ) && (status != STATUS_BUFFER_TOO_SMALL ))
920- {
921- P4vfsTraceError (Core , L"P4vfsOpenReparsePoint: FltGetVolumeName length query failed [%wZ] [%!STATUS!]" , pFileName , status );
922- goto CLEANUP ;
923- }
924-
925- RtlInitUnicodeString (& fileIdPath , NULL );
926- status = RtlUShortAdd ((USHORT )volumeNameLengthRequired , sizeof (LONGLONG )+ sizeof (WCHAR ), & fileIdPath .MaximumLength );
927- if (!NT_SUCCESS (status ))
928- {
929- P4vfsTraceError (Core , L"P4vfsOpenReparsePoint: RtlUShortAdd failed [%wZ] [%!STATUS!]" , pFileName , status );
930- goto CLEANUP ;
931- }
932-
933- status = P4vfsAllocateUnicodeString (P4VFS_FILE_NAME_ALLOC_TAG , & fileIdPath );
934- if (!NT_SUCCESS (status ))
935- {
936- P4vfsTraceError (Core , L"P4vfsOpenReparsePoint: P4vfsAllocateUnicodeString failed [%wZ] [%!STATUS!]" , pFileName , status );
937- goto CLEANUP ;
938- }
939-
940- status = FltGetVolumeName (volume , & fileIdPath , & volumeNameLengthRequired );
941- if (!NT_SUCCESS (status ))
942- {
943- P4vfsTraceError (Core , L"P4vfsOpenReparsePoint: FltGetVolumeName failed [%wZ] [%!STATUS!]" , pFileName , status );
944- goto CLEANUP ;
945- }
946-
947- status = RtlAppendUnicodeToString (& fileIdPath , L"\\" );
948- if (!NT_SUCCESS (status ))
949- {
950- P4vfsTraceError (Core , L"P4vfsOpenReparsePoint: RtlAppendUnicodeToString separator failed [%wZ] fileIdPath [%wZ] [%!STATUS!]" , pFileName , & fileIdPath , status );
951- goto CLEANUP ;
952- }
953-
954- UNICODE_STRING fileIdString ;
955- fileIdString .Length = sizeof (fileId );
956- fileIdString .MaximumLength = sizeof (fileId );
957- fileIdString .Buffer = (PWCHAR )& fileId ;
958-
959- status = RtlAppendUnicodeStringToString (& fileIdPath , & fileIdString );
960- if (!NT_SUCCESS (status ))
961- {
962- P4vfsTraceError (Core , L"P4vfsOpenReparsePoint: RtlAppendUnicodeToString fileIdString failed [%wZ] fileIdPath [%wZ] [%!STATUS!]" , pFileName , & fileIdPath , status );
963- goto CLEANUP ;
964- }
965-
966999 IoInitializeDriverCreateContext (& createContext );
9671000#if (NTDDI_VERSION >= NTDDI_WIN10_RS1 ) && defined(P4VFS_KERNEL_MODE )
9681001 createContext .SiloContext = PsGetHostSilo ();
@@ -986,9 +1019,9 @@ P4vfsOpenReparsePoint(
9861019 & ioStatus ,
9871020 NULL ,
9881021 FILE_ATTRIBUTE_NORMAL ,
989- FILE_SHARE_VALID_FLAGS ,
1022+ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE ,
9901023 FILE_OPEN ,
991- FILE_SYNCHRONOUS_IO_NONALERT | FILE_OPEN_REPARSE_POINT | FILE_NO_INTERMEDIATE_BUFFERING | FILE_OPEN_BY_FILE_ID ,
1024+ FILE_SYNCHRONOUS_IO_NONALERT | FILE_OPEN_REPARSE_POINT | FILE_OPEN_BY_FILE_ID ,
9921025 NULL ,
9931026 0 ,
9941027 IO_IGNORE_SHARE_ACCESS_CHECK ,
@@ -1018,11 +1051,6 @@ P4vfsOpenReparsePoint(
10181051 ObDereferenceObject (pLocalFileObject );
10191052 }
10201053
1021- if (volume != NULL )
1022- {
1023- FltObjectDereference (volume );
1024- }
1025-
10261054 if (fileIdPath .Buffer != NULL )
10271055 {
10281056 ExFreePoolWithTag (fileIdPath .Buffer , P4VFS_FILE_NAME_ALLOC_TAG );
0 commit comments