星期四, 五月 14, 2009

时隔一年,编写DirectShow Filter时遇到的一些新旧问题的记录

掐指算来,上一次研究DirectShow Filter已经是一年前的事情了。技术这东西,一旦长时间不用,就会立刻生疏起来。因为一个小项目,最近又要重新拾起它来。本以为项目不是很困难,可是真正做起来,却发现遇到了好些个问题,这次记录下来,以备以后查看。

1、版本问题
上次开发主要使用了Visual C++ 6.0。时代变迁,电脑升级,这回改用Visual Studio 2005来生成工程。一开始打算使用Visual Studio 2005自带的DirectShow来做,不再安装其他的SDK。但发现VS2005并不带有编写DirectShow Filter所需要使用的BaseClasses例程,所以还是安装了Platform SDK for Windows Server 2003 R2, 以及一个DirectX SDK march 2009。

2、编译BaseClasses
分别在cmd下执行Microsoft Platform SDK for Windows Server 2003 R2\SetEnv.Cmd和Microsoft Visual Studio 8\VC\vcvarsall.bat设置运行环境变量,直接在BaseClasses下nmake

3、编译自己的Filter
上次刚开始研究编写Filter的时候,链接BaseClasses生成的库也总是出现unresolved external symbol链接错误,让我研究了好久才搞明白。这一次又出现了这样的问题,只知道是哪里的编译参数有错,但找不到具体位置。本来以为是因为wchar_t是否是默认类型的影响,来回设置了好几次也没有效果。最后受搜索结果的启发,想起来可能是因为UNICODE的原因导致的。将自己的Filter工程设置为非UNICODE之后,编译通过。

4、GraphEdit的Connect to Remote Graph功能
无法使用,运行程序之后,无法在GraphEdit中得到程序的Graph。
百思不得其解,搜索得到结果是,新的支持Vista的SDK下使用的组件与旧系统不同,注册propage.dll(在Microsoft SDKs\6.0A\)之后,问题解决。

5、向Graph中增加自己的Filter失败
纯属个人对COM不完全理解所至,应该是个很低级的错误:在编写的.def文件中应该至少包含如下几项:
DllMain PRIVATE
DllGetClassObject PRIVATE
DllCanUnloadNow PRIVATE
DllRegisterServer PRIVATE
DllUnregisterServer PRIVATE
一开始写的时候少了第二、三项,导致在CoCreateInstance的时候产生0x800401f9(Error in DLL)错误。

微软已经开始推广新的Media Foundation了,不知道DirectShow还能用几年:)
搞应用技术的,永远都要跟着标准厂商走,永远要学习……

还好我现在有一个走向低层开发的机会——当然一时还脱离不开Intel Architecture,不过Intel的变动性要比M$少得多了:D

星期日, 五月 10, 2009

关于Windows Vista/7上使用支付宝的数字证书的问题

昨天买了笔记本,有点好奇,安装了M$新出的Windows 7 RC版。除了有一堆软件不兼容无法安装,支付宝数字证书导入的兼容问题也让我着实头疼。

网上早已有了一堆解决方法,我这里只是想记录自己手动解决这个问题的方案——因为我担心从网上下载的相关文件会被hack过:)


先从技术的角度来解释,为什么不能导入数字证书(报错:80020009)。导入数字证书需要使用microsoft certificate enrollment插件(即xenroll.dll/cab),这一特性支持Windows2000(包括)之后,Vista(不包括)之前的操作系统,服务器使用Windows Server 2003。这个插件已经应用了很多年,Microsoft认为此插件已经不再足以提供必要的安全特性,因此新一代操作系统Vista/Windows Server 2008上使用了新的数字证书特性:CertEnroll。并且,原来的特性Xenroll在这两个操作系统上被禁用。Windows Server 2008则会根据客户端的类型自动选择其支持的certificate enrollment Web pages是使用Xenroll还是CertEnroll。


因此,为了在Vista/7系统上导入支付宝的数字证书,首先我们要允许Xenroll,且将Xenroll.dll注册为系统服务。网上有“一键解决”之类的解决方案,下面是我的手动解决方案(在我看来更安全一:)


一:修改注册表(网上复制来的,可以自己做.reg文件,也可以自己用regedit修改。(1.其实我不知道注册xenroll.dll是不是必须要经过这一步,你可以先看第二步,如果注册失败,再修改这里的注册表。2.当你注册完第二步的xenroll.dll之后,就可以恢复xenroll禁用状态了,至少我禁用之后仍然可以导入数字证书):
Microsoft Certificate Enrollment CAB禁用.reg
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\ActiveX Compatibility\{127698e4-e730-4e5c-a2b1-21490a70c8a1}]
"Compatibility Flags"=dword:00000400
"IeaDo"=-
Microsoft Certificate Enrollment CAB开锁 .reg
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\ActiveX Compatibility\{127698e4-e730-4e5c-a2b1-21490a70c8a1}]
"Compatibility Flags"=dword:00000000
"IeaDo"=dword:00000001
二:注册xenroll.dll
1.首先找一个XP系统,搜索到xenroll.dll(或者直接在Windows\system32\找到),复制到Vista/7系统的Windows\system32下。
2.新建一个快捷方式,命令输入cmd,建完之后,右击,选“以管理员身份运行”。




3.执行regsvr32 C:\Windows\System32\xenroll.dll(请根据你的Windows安装目录修改路径)。如果提示注册成功,你就可以导入支付宝的数字证书了。