[此贴子已经被作者于2022-11-20 16:48编辑过]
;======================== ;ComThread.def ;======================== LIBRARY ComThread.dll EXPORTS _ProcThread ;======================== ;ComThread.inc ;======================== include windows.inc include user32.inc include kernel32.inc includelib user32.lib includelib kernel32.lib include ole32.inc includelib ole32.lib include oleaut32.inc includelib oleaut32.lib include debug.inc includelib debug.lib include shlwapi.inc includelib shlwapi.lib DISPPARAMS struct rgvarg dd ? rgdispidNamedArgs dd ? cArgs dd ? cNamedArgs dd ? DISPPARAMS ends VARIANT struct vt word VT_EMPTY wReserved1 word 0 wReserved2 word 0 wReserved3 word 0 Union lVal sdword ? bVal word ? iVal sword ? fltVal real4 ? dblVal real8 ? boolVal word ? scode dword ? cyVal qword ? date qword ? bstrVal dword ? punkVal dword ? pdispVal dword ? parray dword ? pbVal dword ? piVal dword ? plVal dword ? pfltVal dword ? pdblVal dword ? pboolVal dword ? pscode dword ? pcyVal dword ? pdate dword ? pbstrVal dword ? ppunkVal dword ? ppdispVal dword ? pparray dword ? pvarVal dword ? byref dword ? cVal sbyte ? uiVal word ? ulVal dword ? intVal sword ? uintVal word ? pdecVal dword ? pcVal dword ? puiVal dword ? pulVal dword ? pintVal dword ? puintVal dword ? ends VARIANT ends OBJPARAMS struct lpObjName dd ? lpFunName dd ? lpParams dd ? OBJPARAMS ends .const IID_IDispatch GUID {00020400h,0000h,0000h,{0C0h,000h,000h,000h,000h,000h,000h,046h}} ;定义IID_IDispatch .data stObjParams OBJPARAMS <> .data? szDefPath db MAX_PATH dup (?) ;======================== ;ComThread.asm ;======================== .386 .model flat,stdcall option casemap:none include ComThread.inc .code DllEntry proc _dhInstance, _ddReason, _ddReserved mov eax, TRUE ret DllEntry Endp ; 调用对象的函数 ; lpIDispatch . COM对象指针 ; ddFunOffset . 函数在函数表的偏移,例如要调用第1个函数,偏移是0*4;第2个函数,偏移是1*4 ; ddParams .... 参数个数 ; lpParams .... 参数表指针 _ComInvoke proc c uses ecx edx _lpIDispatch, _ddFunOffset, _ddParams, _lpParams:vararg ;参数入栈 mov ecx, _ddParams .while ecx >= 1 dec ecx mov eax, dword ptr [_lpParams + ecx*4] push eax .endw ;调用函数 mov eax, _lpIDispatch mov edx, [eax] push _lpIDispatch mov eax, _ddFunOffset call dword ptr [edx + eax] ret _ComInvoke endp ; IDispatch函数调用,传入函数名和参数列表即可以调用,详情可以参考例子。 ; lpIDispatch . COM对象指针 ; lpFuncName .. 函数名 ; lpVar ....... VARIANT结构指针 ; numArgs ..... ;_Invoke, lpIDispatch, lpFunName, addr stVar, 1, VT_BSTR, lpParam _Invoke proc c uses esi edi ebx lpIDispatch, lpFuncName, lpVar, numArgs, args:VARARG ;vartype1,value1,vartype2,value2 LOCAL hMem:DWORD, tmpMem[128]:BYTE, dispid:DWORD, pointer:DWORD LOCAL stDP:DISPPARAMS LOCAL IDI_IID_NULL:GUID invoke RtlZeroMemory, addr IDI_IID_NULL, sizeof GUID invoke MultiByteToWideChar, CP_ACP, 0, lpFuncName, -1, addr tmpMem, 128 lea eax, tmpMem mov pointer, eax ; lpIDispatch.GetIDsOfNames() ; [restricted] Void GetIDsOfNames ( ; [in] riid :Ptr GUID, ; [in] rgszNames :Ptr Ptr I1, ; [in] cNames :UInt, ; [in] lcid :UI4, ; [out] rgdispid :Ptr I4 ) invoke _ComInvoke, lpIDispatch, 20, 5, addr IDI_IID_NULL, addr pointer, 1, 0, addr dispid ; (numArgs + 1) * sizeof VARIANT mov eax, numArgs inc eax imul eax, sizeof VARIANT ; 从堆中分配空间。GPTR...分配固定的内存并初始化为0,返回一个指针 invoke GlobalAlloc, GPTR, eax mov hMem, eax ;init params invoke RtlZeroMemory, addr stDP, sizeof DISPPARAMS .if numArgs > 0 mov eax, sizeof VARIANT imul eax, numArgs mov esi, hMem lea edi, args mov eax, numArgs shl eax, 3 ;numArgs*4*2 sub eax, 8 add edi, eax assume esi:ptr VARIANT mov ebx, 0 .while ebx < numArgs mov eax, [edi] mov [esi].vt, ax mov eax, [edi][4] mov [esi].lVal, eax mov eax, numArgs mov stDP.cArgs, eax mov eax, hMem mov stDP.rgvarg,eax add esi,sizeof VARIANT sub edi,8 inc ebx .endw assume esi:nothing .else mov stDP.rgvarg, 0 mov stDP.cArgs, 0 .endif ; lpIDispatch.Invoke() ; [restricted] Void Invoke ( ; [in] dispidMember :I4, ; [in] riid :Ptr GUID, ; [in] lcid :UI4, ; [in] wFlags :UI2, ; [in] pdispparams :Ptr DISPPARAMS, ; [out] pvarResult :Ptr Variant, ; [out] pexcepinfo :Ptr EXCEPINFO, ; [out] puArgErr :Ptr UInt ) invoke _ComInvoke, lpIDispatch, 24, 8, dispid, addr IDI_IID_NULL, 0, 1, addr stDP, lpVar, 0, 0 invoke GlobalFree, hMem ret _Invoke endp _ProcThread proc uses esi lpParam LOCAL szBuf[MAX_PATH] :BYTE LOCAL szGUID :GUID LOCAL lpIDispatch :DWORD LOCAL stVar :VARIANT LOCAL lpPar :DWORD mov esi, lpParam assume esi:ptr OBJPARAMS invoke CoInitialize, NULL ;创建对象 invoke MultiByteToWideChar, CP_ACP, 0, [esi].lpObjName, -1, addr szBuf, MAX_PATH invoke CLSIDFromProgID, addr szBuf, addr szGUID .if eax != S_OK invoke MessageBox, 0, CTEXT("找不到对象"), 0, 0 .endif invoke CoCreateInstance, addr szGUID, NULL, CLSCTX_INPROC_SERVER or CLSCTX_LOCAL_SERVER, offset IID_IDispatch, addr lpIDispatch .if eax != S_OK invoke MessageBox, 0, CTEXT("无法创建对象"), 0, 0 .endif ;调用对象函数 invoke MultiByteToWideChar, CP_ACP, 0, [esi].lpParams, -1, addr szBuf, MAX_PATH invoke SysAllocString, addr szBuf mov lpPar, eax invoke _Invoke, lpIDispatch, [esi].lpFunName, addr stVar, 1, VT_BSTR, lpPar invoke SysFreeString, lpPar assume esi:nothing ;释放对象 ; lpIDispatch.Release() ; [restricted] UI4 Release ( ) invoke _ComInvoke, lpIDispatch, 2*4, 0 invoke CoUninitialize ret _ProcThread endp End DllEntry
[此贴子已经被作者于2022-11-23 07:37编辑过]