masm32开发com组件介绍[一][二][三]
作 者: combojiang
时 间: 2007-12-10,14:09
链 接: http://bbs.pediy.com/showthread.php?t=56328
声明:本贴参考网站:http://ourworld.compuserve.com/
[一]基础知识篇
组件对象模型(Com)在windows操作系统中应用越来越广泛。com因为大量的技术细节显得很复杂,但是正是这种复杂才使com组件的调用显得十分简单。 com和使用程序采用server/client架构。下面我们将在后续的两篇中介绍com组件的编写与调用。
com编程时当前程序开发的热点,各种编程语言都为组件编写提供了很好的支持,但是汇编语言例外,汇编语言开发组件没有优势。但是透过汇编开发的了解,可以使我们了解com组件的工作原理。好了,闲话少说,开始介绍:)
所有的inc头文件都要满足如下特点:
1) masm32松散的类型定义约定将继续使用。就是说参数可以被定义为他们的基本类型,代表性的如:DWORD
2) 里面不能创建任何的代码,仅仅包含定义信息,头文件里面需要包含代码,则必须定义为宏。
3) 结构体应该参照他们的C原形来定义。
4) GUID 结构定义在windows.inc文件中,GUID的值应该通过textequ宏来定义,这样不会直接产生任何代码。
5) 接口定义分为两步:
1.一个通用的宏产生一个通用的接口结构。
2.使用接口名字来修饰结构自身的方法名字。
这种方式可以有效地避免namespace冲突,并且方便接口定义结构继承。
6)COM接口函数调用使用coinvoke宏。
GUIDS
EXAMPLE:
sIID_IUnknown TEXTEQU <{000000000H, 00000H, 00000H,
{0C0H, 000H, 000H, 000H, 000H, 000H, 000H, 046H}}
可以被用来定义
IID_IUnknown GUID sIID_IUnknown
接口:
由于MASM32原形约定松散的类型检查,主要检查编译时函数的参数的个数。因此可以非常简单的定义接口函数,如下所示,用下表值来表示函数参数的个数。
comethod1Proto typedef proto :DWORD
comethod2Proto typedef proto :DWORD, :DWORD
comethod3Proto typedef proto :DWORD, :DWORD, :DWORD
comethod4Proto typedef proto :DWORD, :DWORD, :DWORD, :DWORD
comethod4Proto typedef proto :DWORD, :DWORD, :DWORD, :DWORD, :DWORD
函数指针如下:
comethod1 typedef ptr comethod1Proto
comethod2 typedef ptr comethod2Proto
comethod3 typedef ptr comethod3Proto
comethod4 typedef ptr comethod4Proto
comethod5 typedef ptr comethod4Proto
IUnknown接口: IUnknown接口是基本接口,其他所有接口都是派生于它。函数原形定义如上,其定义如下:
_vtIUnknown MACRO CastName:REQ
; IUnknown methods
&CastName&_QueryInterface comethod3 ?
&CastName&_AddRef comethod1 ?
&CastName&_Release comethod1 ?
ENDM
IUnknown STRUCT
_vtIUnknown IUnknown
IUnknown ENDS
其展开如下:
IUnknown STRUCT
IUnknown_QueryInterface comethod3 ?
IUnknown_AddRef comethod1 ?
IUnknown_Release comethod1 ?
IUnknown ENDS
IClassFactory 接口
IClassFactory派生于 IUnknown.它的结构开始是 IUnknown 的方法, 后面添加了 2个自己的方法.
_vtIClassFactory MACRO CastName:REQ
; IUnknown methods
_vtIUnknown CastName
; IClassFactory methods
&CastName&_CreateInstance comethod4 ?
&CastName&_LockServer comethod2 ?
ENDM
IClassFactory STRUCT
_vtIClassFactory IClassFactory
IClassFactory ENDS
展开如下:
IClassFactory STRUCT
IClassFactory_QueryInterface comethod3 ?
IClassFactory_AddRef comethod1 ?
IClassFactory_Release comethod1 ?
IClassFactory_CreateInstance comethod4 ?
IClassFactory_LockServer comethod2 ?
IClassFactory ENDS
Coinvoke宏
;---------------------------------------------------------------------
; coinvoke MACRO
; pInterface pointer to a specific interface instance
; Interface the Interfaces struct typedef
; Function which function or method of the interface to perform
; args all required arguments
; (type, kind and count determined by the function)
;
coinvoke MACRO pInterface:REQ, Interface:REQ, Function:REQ, args:VARARG
LOCAL istatement, arg
FOR arg, <args> ;; run thru args to see if edx is lurking in there
IFIDNI <&arg>, <edx>
.ERR <edx is not allowed as a coinvoke parameter>
ENDIF
ENDM
istatement CATSTR <invoke (Interface PTR[edx]).&Interface>,<_>,<&Function, pInterface>
IFNB <args> ;; add the list of parameter arguments if any
istatement CATSTR istatement, <, >, <&args>
ENDIF
mov edx, pInterface
mov edx, [edx]
istatement
ENDM
;---------------------------------------------------------------------
例如:QueryInterface方法调用如下:
coinvoke ppv ,IUnknown, QueryInterface, ADDR IID_SomeOtherInterface,
ADDR ppnew
HRESULTS
任何一个com接口函数的返回值类型都是一个hResult, 4个字节长。返回值在eax寄存器中。可以用这个值来判断函数调用是否成功。
.IF !SIGN?
; function passed
.ELSE
; function failed
.ENDIF
接下来,我们定义了宏来简化它:
.IF SUCCEEDED ; TRUE if SIGN bit not set
.IF FAILED &n
上一篇: 总结进入RING0的方法
下一篇: 遭遇密码丢失 教你如何进行破解