📄 ndqueryinterface.asm
字号:
;-------------------------------------------------------------------------------
; colibrary procedure NDQueryInterface
;
; -------------------------------------------------------
; This procedure was written by Ernest Murphy 9/27/00
;
; Copyright (c) 9/28/00 Ernest Murphy
; For educational use only. Any commercial re-use only by written license
;
; -------------------------------------------------------
.NOLIST
.386
.model flat, stdcall ; 32 bit memory model
option casemap :none ; case sensitive
include mini_win.inc ; 'just enough' of windows.inc (speeds build)
include \masm32\include\ole32.inc
include \masm32\include\oleaut32.inc
include \masm32\COM\include\oaidl.inc
include \masm32\COM\include\language.inc
include colib.inc
externdef IID_IUnknown:GUID
externdef IID_IDispatch:GUID
PUBLIC vtINDUnknown
.data
;-------------------------------------------------------------------------------
vtINDUnknown IUnknown \
{ NDQueryInterface,
NDAddRef,
NDRelease }
.LISTALL
.code
;-------------------------------------------------------------------------------
NDQueryInterface PROC PUBLIC this_:DWORD, iid:DWORD, ppv:DWORD
;-------------------------------------------------------------------------------
; implimentation of the non-delegated IUnknown::NDQueryInterface function
;
; performs the NDQueryInterface function
;
; EXAMPLE:
; coinvoke ppv, NDIUnknown, QueryInterface, ADDR iid, ADDR pv
;
; Uses: eax, ecx, edx
;
;
;-------------------------------------------------------------------------------
LOCAL pBase:DWORD, pClassItem:DWORD, pIMap:DWORD
LOCAL ICount:DWORD, pObjectEntry:DWORD, pcIMap:DWORD
.IF !ppv
mov ppv, 0
mov eax, E_POINTER
ret
.ENDIF
mov edx, this_ ; get object
mov eax, (ObjectEntry PTR[edx]).m_pBase ; walk to base data
; interfaces we support
mov pBase, eax
invoke IsEqualGUID, iid, pIID_IUnknown
.IF (eax)
; asking for an IUnknown interface, return pUnkOuter
mov edx, pBase
mov eax, (ObjectData PTR[edx]).m_pUnkOuter
mov ecx, ppv
mov [ecx], eax
jmp returnOK
.ENDIF
; compute ObjectEntry0 point
mov ecx, pBase
mov eax, ecx
mov edx, (ObjectData PTR[ecx]).m_pClassItem
add eax, [edx].ClassItem.m_ObjectSize
add eax, SIZEOF ObjectData
mov pObjectEntry, eax
; check if our object support IDispatch
mov ecx, (ObjectData PTR[ecx]).m_pClassItem
mov pClassItem, ecx
mov eax, (ClassItem PTR[ecx]).m_pIMap
mov pIMap, eax
mov pcIMap, eax
mov eax, (ClassItem PTR[ecx]).m_Flags
AND eax, DISPINTERFACE
.IF (eax)
; check for a request for an IDispatch interface RQ, return ObjectEntry1
invoke IsEqualGUID, iid, pIID_IDispatch
.IF eax
; IS an IDispatch request
mov eax, pObjectEntry
add eax, SIZEOF ObjectEntry ; cast to default interface
mov ecx, ppv
mov [ecx], eax
jmp returnOK
.ENDIF
.ENDIF
; now we hunt thru our IMap
mov ICount, 1
mov ecx, pcIMap
mov eax, (InterfaceItem PTR [ecx]).m_refiid
.WHILE eax
invoke IsEqualGUID, iid, eax
.IF !eax
inc ICount
; no match, point to next element
add pcIMap, SIZEOF InterfaceItem ; point to next item
mov ecx, pcIMap
mov eax, (InterfaceItem PTR [ecx]).m_refiid
.ELSE
; found a supported interface
; ICount indicates how far into the object we index
mov eax, ICount
imul eax, SIZEOF ObjectEntry
add eax, pObjectEntry
mov ecx, ppv
mov [ecx], eax
mov edx, ppv
mov edx, [edx]
returnOK:
; inc the ref count for the new pointer *we* created
coinvoke this_, IUnknown, AddRef
xor eax, eax
ret
.ENDIF
.ENDW
NoInterface:
mov ecx, ppv
mov eax, NULL
mov [ecx], eax ; good practice, always NULL bad pointers
; in case client doesn't check the SCODE in hResult
mov eax, E_NOINTERFACE ; and signal interface is not supported here
ret
NDQueryInterface ENDP
;-------------------------------------------------------------------------------
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -