📄 allocobject.asm
字号:
;-------------------------------------------------------------------------------
; colibrary procedure AllocObject
;
; -------------------------------------------------------
; This procedure was written by Ernest Murphy 9/27/00
;
; revised 3/3/01 to simplify object creation
; and remove ObjectData.m_pEntry0
; revised 2/21/01 to remove pCustomData destructor
;
;
; 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\oleaut32.inc
include \masm32\include\ole32.inc
include \masm32\COM\include\oaidl.inc
include colib.inc
externdef vtINDUnknown:IUnknown
externdef g_ObjectCount:DWORD
.code
;-------------------------------------------------------------------------------
AllocObject PROC PUBLIC pObject:DWORD, pClassItem:DWORD,
pUnkOuter:DWORD, pCustomData:DWORD
;-------------------------------------------------------------------------------
; implimentation of the AllocObject method
;
; internal function to create COM objects
;
; EXAMPLE:
; invoke AllocObject ADDR Object, ADDR ObjectDesc, ADDR UnkOuter, ADDR CustomData
;
; Uses: eax, ecx, edx
;
;
;-------------------------------------------------------------------------------
LOCAL pBase:DWORD, pIMap:DWORD, pObjectEntry:DWORD
LOCAL ObjectSize:DWORD, ICount:DWORD
mov ecx, pObject
mov eax, NULL
mov [ecx], eax ; NULL the returned object
; now we define all our object data
mov ecx, pClassItem
mov ecx, (ClassItem PTR [ecx]).m_pIMap
mov pIMap, ecx ; preserve pointer for later
mov ICount, 0
; count how many interfaces we support
.REPEAT
; we're counting 1 too many by assuming next one exists
; but thats OK, cause we need the +1 for the aggregation interface
mov eax, (InterfaceItem PTR [ecx]).m_refiid
inc ICount ; assume next one exists
add ecx, SIZEOF InterfaceItem
.UNTIL !eax
; now figure the complete object size
; size = SIZEOF ObjectData + (bytes requested) + (IMap + 1) * 8
mov ecx, pClassItem
mov eax, (ClassItem PTR [ecx]).m_ObjectSize
mov ObjectSize, eax
mov edx, ICount
rol edx, 3 ; count = count * 8 (8 bytes per InterfaceItem)
add eax, edx
add eax, SIZEOF ObjectData
mov ObjectSize, eax
invoke CoTaskMemAlloc, eax
.IF (eax==0)
; alloc failed
mov eax, E_OUTOFMEMORY ; signal the failure
ret
.ENDIF
; alloc succeeded
mov pBase, eax
inc g_ObjectCount ; adjust the global lock count
dec ICount ; fix ICount for later use
; compute object entry point ObjectEntry0
mov ecx, pBase
mov edx, pClassItem
add ecx, [edx].ClassItem.m_ObjectSize
add ecx, SIZEOF ObjectData
mov pObjectEntry, ecx
; init m_RefCount
mov edx, pBase
mov (ObjectData PTR [edx]).m_RefCount, 1
; init p->delegated IUnknown
mov eax, pUnkOuter
.IF !eax
mov eax, pObjectEntry
.ENDIF
mov (ObjectData PTR [edx]).m_pUnkOuter, eax ; delegated IUnknown
; init type info ptr m_pti
mov (ObjectData PTR [edx]).m_pti, NULL
; init the current LCID to a bad lcid
mov eax, -1
mov (ObjectData PTR [edx]).m_lcid, eax
; init the list to aggregated objects
mov (ObjectData PTR [edx]).m_pAggList, NULL
; init pClassItem ptr to pClassItem
mov ecx, pClassItem
mov (ObjectData PTR [edx]).m_pClassItem, ecx
; now we set up the Object Entries
; INDUnknown first
mov edx, pObjectEntry ; NDIunk ObjectEntry
mov ecx, pClassItem
mov eax, OFFSET vtINDUnknown
mov (ObjectEntry PTR [edx]).m_pVtbl, eax
mov eax, pBase
mov (ObjectEntry PTR [edx]).m_pBase, eax
; now the other interfaces
mov edx, pObjectEntry ; NDIunk ObjectEntry
add edx, SIZEOF ObjectEntry
mov ecx, pIMap
.WHILE ICount
mov eax, (InterfaceItem PTR [ecx]).m_pVtbl
mov (ObjectEntry PTR [edx]).m_pVtbl, eax
mov eax, pBase
mov (ObjectEntry PTR [edx]).m_pBase, eax
add edx, SIZEOF ObjectEntry
add ecx, SIZEOF InterfaceItem
dec ICount
.ENDW
; now need to call the constructor
; get pointer to custom data area in object
mov ecx, pClassItem
mov ecx, (ClassItem PTR [ecx]).m_pConstructor
.IF ecx
mov eax, pObjectEntry ; NDIunk ObjectEntry
add eax, SIZEOF ObjectEntry ; cast to IUnknown
; and get the constructor ptr
invoke Constructor PTR ecx, eax, pCustomData ; and call it
.IF !eax
; Constructor worked
xor eax, eax ; mov eax, S_OK
.ELSE
; something went wrong, destroy the newborn object
invoke CoTaskMemFree, pBase
mov eax, E_FAIL
ret
.ENDIF
.ENDIF
; cast the returned object to an IUnknown
mov eax, pObjectEntry
add eax, SIZEOF ObjectEntry
mov ecx, pObject
mov [ecx], eax
ret
AllocObject ENDP
;-------------------------------------------------------------------------------
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -