Hi guys,
I wrote a mini filter driver in Win 7 to redirect file I/Os from "C:" to “D:\Vm\C” directory, everything worked just fine, until yesterday I encountered a failure(STATUS_NAME_NOT_FOUND) during installing Windows update KB file . However, the kb file could be installed correctly if my driver was unloaded.
After debugging I found that it’s the “TrustInstaller.exe” in Win 7, which was responsible for installing the kb file, returned the STATUS_NAME_NOT_FOUND error. Its workflow was as following:
- Do someting necessary to verify KB and extract the dll files to “C:\Windows\WinSxS” folder;
- Create a hard link named ?c:\windows\system32\api-ms-win-core-file-l1-2-0.dll ? to file “C:\Windows\WinSxS\amd64_3ware.inf.resources_31bf3856ad364e35_6.3.9600.16384_en-us_36411501bece1b66\api-ms-win-core-file-l1-2-0.dll”.
------> It eventually called ZwSetInformationFile with FileLinkInformation class, the call returned STATUS_SUCCESS;
- Open the hard link ?c:\windows\system32\api-ms-win-core-file-l1-2-0.dll ? (return STATUS_SUCCESS).
The above process worked if my driver was unloaded. However, with my driver loaded, the workflow would be:
- Do someting necessary to verify KB and extract the dll files to “D:\Vm\C\Windows\WinSxS” folder;
- Create a hardlink named ?D:\Vm\C\windows\system32\api-ms-win-core-file-l1-2-0.dll ? to file “D:\Vm\C\Windows\WinSxS\amd64_3ware.inf.resources_31bf3856ad364e35_6.3.9600.16384_en-us_36411501bece1b66\api-ms-win-core-file-l1-2-0.dll”;
------> It eventually called FltSetInformationFile with FileLinkInformation class, and since I have munged the hard link name in LinkInfo structure from C:\xxx to D:\Vm\C\xxx,
the FltSetInformationFile call would return STATUS_SUCCESS. However, the hard link ?D:\Vm\C\windows\system32\api-ms-win-core-file-l1-2-0.dll ? was not created as expected.
- Open the hard link ?D:\Vm\C\windows\system32\api-ms-win-core-file-l1-2-0.dll ? (It returned STATUS_NAME_NOT_FOUND -----> Error).
More weird is, with my driver loaded, I could create the hard link successfully by run “mklink /h C:\Windows\xxx C:\Windows\WinSxS\xxx” in cmd.exe, which followed the same workflow as above(that is, munged “C:\xxx” to “D:\Vm\C\xxx”). I also checked all parameters in FltSetInformationFile with WinDbg, they were the same.
My code snippet was posted below:
FLT_PREOP_CALLBACK_STATUS
PreSetLinkInformation (
Inout PFLT_CALLBACK_DATA Data,
In PCFLT_RELATED_OBJECTS FltObjects,
Flt_CompletionContext_Outptr PVOID *CompletionContext
)
{
…
// If the file was in our mapping
if(FilePath.InMapping) {
…
Status = NcConstructPath( PagedPool,
&HostLinkFilePath,
&MungedLinkFilePath,
);
if (!NT_SUCCESS( Status )) {
ReturnValue = FLT_PREOP_COMPLETE;
goto PreSetLinkInformationCleanup;
}
MungedLinkInfoSize = sizeof(FILE_LINK_INFORMATION) + MungedLinkFilePath.Length;
PMungedLinkInfo = ExAllocatePoolWithTag( PagedPool,
MungedLinkInfoSize,
NC_SET_LINK_BUFFER_TAG );
PMungedLinkInfo->ReplaceIfExists = OriginalLinkInfo->ReplaceIfExists;
PMungedLinkInfo->RootDirectory = NULL;
PMungedLinkInfo->FileNameLength = MungedLinkFilePath.Length;
RtlCopyMemory( &PMungedLinkInfo->FileName, MungedLinkFilePath.Buffer, MungedLinkFilePath.Length );
Status = FltSetInformationFile( FltObjects->Instance,
FltObjects->FileObject,
PMungedLinkInfo,
MungedLinkInfoSize,
FileLinkInformation );
if(!NT_SUCCESS(Status)) {
DbgPrint(“PreLink(%wZ -> %wZ) failed with 0x%x\n”,
&FltObjects->FileObject->FileName,
&MungedName,
Status);
}
ReturnValue = FLT_PREOP_COMPLETE;
goto PreSetLinkInformationCleanup;
…
//
}
So my question is, why the hard link was not created, even the FltSetInformationFile returned STATUS_SUCCESS?
Any help will be highly appreciated, Thanks!
Jason