Windows平台WebKit的Plugin机制(一)——搜索插件
来源:互联网 发布:plc虚拟仿真软件 编辑:程序博客网 时间:2024/05/18 12:38
本文探讨在Windows平台下,WebKit如何搜索插件。
用于测试的网页代码如下:
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=gb2312"> </head> <body> <script language=javascript> var len = navigator.plugins.length; document.write("你的浏览器共支持" + len + "种plug-in:<BR>"); document.write("<TABLE BORDER>"); document.write("<CAPTION>PLUG-IN 清单</CAPTION>"); document.write("<TR><TH>编号</TH><TH>名称</TH><TH>描述</TH><TH>文件名</TH></TR>"); for (var i=0; i<len; i++){ document.write("<TR><TD>" + i + "</TD>" + "<TD>" + navigator.plugins[i].name + "</TD>" + "<TD>" + navigator.plugins[i].description + "</TD>" + "<TD>" + navigator.plugins[i].filename) + "</TD></TR>"; } document.write("</TABLE>"); </script> </body></html>
这个网页的作用是列出当前浏览器支持的插件名称、描述和对应的文件。
WebKit的插件是延迟加载,并非一打开浏览器就加载所有插件。这个例子中,当JS执行到navigator.plugins.length时,才开始初始化插件信息,此刻的调用栈截图如下:
PluginDatabase对象构造完后,将会到几个特定的目录下寻找插件,这部分代码片段如下:
Vector<String> PluginDatabase::defaultPluginDirectories(){ Vector<String> directories; String ourDirectory = safariPluginsDirectory(); if (!ourDirectory.isNull()) directories.append(ourDirectory); addQuickTimePluginDirectory(directories); addAdobeAcrobatPluginDirectory(directories); addMozillaPluginDirectories(directories); addWindowsMediaPlayerPluginDirectory(directories); addMacromediaPluginDirectories(directories);#if PLATFORM(QT) addJavaPluginDirectory(directories);#endif return directories;}
其中:
sarariPluginsDirectory()返回的是WebKit当前目录(exe文件所在的目录)下的Plugins子目录;
addQuickTimePluginDirectory()到注册表HKEY_LOCAL_MACHINE\Software\AppleComputer, Inc.\QuickTime下寻找InstallDir键,取它的值;
addAdobeAcrobatPluginDirectory()到注册表HKEY_LOCAL_MACHINE\Software\Adobe\AcrobatReader下寻找InstallPath键,取它的值(同时也会记录Adobe的版本号);
addMozillaPluginDirectories()到注册表HKEY_LOCAL_MACHINE\Software\Mozilla,遍历其子目录,寻找Plugins键,取它的值;
addWindowsMediaPlayerPluginDirectory()首先加入“C:\PFiles\Plugins”这个路径,再加入注册表HKEY_LOCAL_MACHINE\Software\Microsoft\MediaPlayer下Installation Directory的值;
addMacromediaPluginDirectories()加入了“C:\Windows\system32\macromed\Flash”和“C:\Windows\system32\macromed\Shockwave10”目录。
接下来,WebKit会遍历加入的这些目录,寻找np打头的dll文件,或者,如果遍历的目录是以“Shockwave 10”结尾,则寻找Plugin.dll,记录其路径。做完这些之后,WebKit还会到注册表HKEY_LOCAL_MACHINE\Software\MozillaPlugins和HKEY_CURRENT_USER\Software\MozillaPlugins下,遍历子目录,寻找Path键,将值记录下来。
经过以上步骤,WebKit会得到Windows下可用作插件的dll文件路径的集合。WebKit还会记录这些文件的最后修改时间,将来如果要重新加载插件,而dll文件最后修改时间有更新,则可能要重新获取dll文件的信息和加载新的dll文件。
WebKit获取dll文件信息的逻辑实现在PluginPackageWin.cpp的PluginPackage::fetchInfo()里,代码如下:
bool PluginPackage::fetchInfo(){ DWORD versionInfoSize, zeroHandle; versionInfoSize = GetFileVersionInfoSizeW(const_cast<UChar*>(m_path.charactersWithNullTermination()), &zeroHandle); if (versionInfoSize == 0) return false; OwnArrayPtr<char> versionInfoData = adoptArrayPtr(new char[versionInfoSize]); if (!GetFileVersionInfoW(const_cast<UChar*>(m_path.charactersWithNullTermination()), 0, versionInfoSize, versionInfoData.get())) return false; m_name = getVersionInfo(versionInfoData.get(), "ProductName"); m_description = getVersionInfo(versionInfoData.get(), "FileDescription"); if (m_name.isNull() || m_description.isNull()) return false; VS_FIXEDFILEINFO* info; UINT infoSize; if (!VerQueryValueW(versionInfoData.get(), L"\\", (LPVOID*) &info, &infoSize) || infoSize < sizeof(VS_FIXEDFILEINFO)) return false; m_moduleVersion.leastSig = info->dwFileVersionLS; m_moduleVersion.mostSig = info->dwFileVersionMS; if (isPluginBlacklisted()) return false; Vector<String> types; getVersionInfo(versionInfoData.get(), "MIMEType").split('|', types); Vector<String> extensionLists; getVersionInfo(versionInfoData.get(), "FileExtents").split('|', extensionLists); Vector<String> descriptions; getVersionInfo(versionInfoData.get(), "FileOpenName").split('|', descriptions); for (unsigned i = 0; i < types.size(); i++) { String type = types[i].lower(); String description = i < descriptions.size() ? descriptions[i] : ""; String extensionList = i < extensionLists.size() ? extensionLists[i] : ""; Vector<String> extensionsVector; extensionList.split(',', extensionsVector); // Get rid of the extension list that may be at the end of the description string. int pos = description.find("(*"); if (pos != -1) { // There might be a space that we need to get rid of. if (pos > 1 && description[pos - 1] == ' ') pos--; description = description.left(pos); } // Determine the quirks for the MIME types this plug-in supports determineQuirks(type); m_mimeToExtensions.add(type, extensionsVector); m_mimeToDescriptions.add(type, description); } return true;}
这个方法使用Wndows API,获取dll文件的ProductName、FileDescription、Version、MIMEType、FileExtents、FileOpenName等信息(GetFileVersionInfoW(const_cast<UChar*>(m_path.charactersWithNullTermination()), 0, versionInfoSize, versionInfoData.get()),其中m_path存储了dll文件的路径)。我们测试网页中列出的插件名称和描述,就是在这个方法中获得的。这个方法还调用了另一个有意思的方法PluginPackage::isPluginBlacklisted()来判断插件是否被禁止。具体哪些插件被禁止以及为什么被禁止,想了解的人可以去看看这个方法。
通过以上步骤,PluginInfo获取完毕。我们的测试网页,在我的电脑上显示结果如下:
- Windows平台WebKit的Plugin机制(一)——搜索插件
- QT Webkit的插件Plugin设计实现
- QT Webkit的插件Plugin设计实现
- QT Webkit的插件Plugin设计实现
- 理解WebKit和Chromium: 插件机制(NPAPI Plugin)
- 理解WebKit和Chromium: 插件机制(NPAPI Plugin)
- WebKit windows 平台编译
- WebKit Windows平台编译
- Windows平台编译Webkit
- 一淘搜索之网页抓取系统分析与实现(3)—scrapy+webkit & mysql+django
- NPAPI插件开发学习:Webkit的插件机制
- NPAPI插件开发学习:Webkit的插件机制
- UE4.5.0的Kinect插件(Plugin)<一>
- webkit 加载plugin的过程分析(原)
- Windows Mobile平台下的WebKit简单分析
- WebKit 在Windows 平台下编译小结(转)
- Nutch学习——插件机制一
- Chromium插件(Plugin)机制简要介绍和学习计划
- 海量数据处理之Bloom Filter详解
- hdu 1080 Human Gene Functions(类最长公共子序列)
- PHP 大括号的用法
- 嵌入式Linux下修改IP
- d3d 图像处理模板(动态修改纹理)
- Windows平台WebKit的Plugin机制(一)——搜索插件
- hdu 2151 Worm(Easy DP)
- 111
- 毕业6年后第二次找工作
- wp主机
- MVC2.0中做分页和排序
- 值得看一看的话
- FICO凭证增强之保存前的修改
- Vtiger CRM 动态菜单的定制方法