问题遇到的现象和发生背景
CEF自制浏览器HOOK下载的文件,拦截写文件过程
1、保存的文件路径是C盘发现CEF下载过程是先写数据到.tmp文件,最后通过重命名的方式生成目标文件,导致DLL里面HOOK WriteFile勾不到实际的文件。
2、在OnBrowserDownloadUpdated里面获取到的SuggestedFileName是空的。
3、但是设置保存路径是D盘就直接是写目标文件。
问题相关代码,请勿粘贴截图
//写文件钩子函数
NTSTATUS WINAPI NtWriteFileHook(
HANDLE FileHandle,
HANDLE Event,
PIO_APC_ROUTINE ApcRoutine,
PVOID ApcContext,
PIO_STATUS_BLOCK IoStatusBlock,
PVOID Buffer,
ULONG Length,
PLARGE_INTEGER ByteOffset,
PULONG Key
)
{
NTSTATUS status = 0;
std::wstring strPath = FileHandleToPath(FileHandle);
std::string strTemp = TCHARToChar(strPath.c_str());
if (strTemp.find(g_config.tempPath) != std::string::npos)
{
ULONG size = Length;
myFileInfo pkt;
pkt.data = (BYTE*)Buffer;
pkt.dataSize = Length;
pkt.filePath = strPath;
mergePacket(pkt);
memcpy(Buffer, g_nullData, size);//稀疏文件
}
status = _NtWriteFileFunc(FileHandle, Event, ApcRoutine, ApcContext, IoStatusBlock, Buffer, Length, ByteOffset, Key);
return status;
}
//文件下载线程
unsigned int cef_DonwloadListManager::AsynDownload()
{
while(!m_bExit)
{
std::this_thread::sleep_for(std::chrono::milliseconds(100));
asynDownloadItem item;
m_mtxAsynDownload.lock();
if(!m_lsAsynDownload.empty())
{
item = m_lsAsynDownload.front();
m_lsAsynDownload.pop();
}
m_mtxAsynDownload.unlock();
if(item.callback != NULL)
{
char chFile[1024] = { 0 };
std::string strName = item.fileName.toStdString();;
char *pFile = chFile;
cef_DonwloadListManager::instance()->SendFileNameToCloudDoc(strName.c_str(),&pFile);//这里会返回一个文件的绝对路径
pFile = NULL;
QFile f(chFile);
if(f.exists())
{
f.remove();
}
CefString temp(chFile);
item.callback->Continue(temp, false);
item.callback = NULL;
qDebug()<<__FUNCTION__<< QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz ")<< "begin download file = " << chFile <<endl;
}
}
return 0;
}
我的解答思路和尝试过的方法
1、尝试过Hook SetInformationFile里面的rename,但是和设计不符,设计是通过HOOK WriteFile获取到每次的数据buffer,再以流的形式上传服务器。
我想要达到的结果
1、怎么样才能让CEF下载直接写目标文件,而不是通过重命名.temp的方式生成目标文件?