• Welcome to Theos PowerBasic Museum 2017.

Exploring Excel typelib

Started by Lars Jäderberg, October 05, 2009, 08:12:13 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Lars Jäderberg

I am exploring Excel type library with a masm coded application. My first version included the tlb32inf.dll but now I am writing the app without it.

With ITypeLib and ITypeInfo interfaces I can get almost all data from the Excel typelib except three. For a couple of weeks I have tryed to solve this without success. No decisive result of my request on the Masm forum.

It seems to me as if this forum has a profound knowledge of com and automation. Hopefully my problem could be solved.

My three problems are:

1. How do I retrieve the names of imported libraries.

library Excel
{
    importlib("VBE6EXT.OLB");
    importlib("MSO.DLL");
    importlib("stdole2.tlb");

2. How do I retrieve the names of inherited interfaces.

Excel -> Dual interfaces -> _Application -> Inherited interface = IDispatch,
Excel -> Dual interfaces -> Adjustments -> Inherited interface = _IMsoDispObj etc.

3. How do I retrieve the names and classes of return parameters.

Excel -> Dual interfaces -> _Application -> Application -> Return type = Application <coclass>,
Excel -> Dual interfaces -> _Application -> Creator -> Return type = XLCreator <enum>,
Excel -> Dual interfaces -> _Application -> ActiveCell -> Return type = Range <dispinterface> etc.

I only get [retval,out], VT_PR, VT_HRESULT and RHS

I would very much appreciate if someone could give me a hint on the way of solving this. No code is needed.

José Roca

Quote
1. How do I retrieve the names of imported libraries.

I have no idea. I haven't find yet information about how to retrieve it.

Quote
2. How do I retrieve the names of inherited interfaces.

You have to call the GetRefTypeOfImplType method of the ITypeInfo interface.

Quote
3. How do I retrieve the names and classes of return parameters.
[...] I only get [retval,out], VT_P[T]R, VT_HRESULT and RHS

When you get VT_PTR, the lptdesc member of the TypeDesc structure is a pointer to another TypeDesc structure (yes, it is a recursive structure).

See this article for more detailed information: http://spec.winprog.org/typeinf2/

Lars Jäderberg

Thank you for answering. I have already read Sean Baxter's text about com and I have already messed around with recursive structure but I am totally lost in this. At least you have now know confirmed that ELEMDESC is th right way to go.

I concentrate on the returned name.

The FUNCDESC structure contains partly a pointer to an array of ELEMDESC structures and partly the ELEMDESC structure of the return parameter.

The return parameter structure gives me VT_HRESULT and the lptdesc holds zero.

The last element of the array hold desciption of the return parameter. It gives me [retval,out] from "ELEMDESC.paramdesc.PARAMDESC.wPARAMFlags" and VT_PR from "ELEMDESC.tdesc.vt"

This is the way. I have the pointer to the FUNCDESC.


mov eax,ppFuncDesc
mov edi,[eax].FUNCDESC.lprgelemdescParam ;pointer to first element of array of ELEMDESC structures
mov eax,sizeof ELEMDESC
mov ecx,1 ;the second element of the array
mul ecx
add edi,eax
movzx edx,[edi].ELEMDESC.paramdesc.PARAMDESC.wPARAMFlags ;retval and out
movzx edx,[edi].ELEMDESC.tdesc.vt ;VT_PTR


If I go futher I get this.

mov eax,ppFuncDesc
mov edi,[eax].FUNCDESC.lprgelemdescParam ;pointer to first element of array of ELEMDESC structures
mov eax,sizeof ELEMDESC
mov ecx,1 ;the second element of the array
mul ecx
add edi,eax
movzx edx,[edi].ELEMDESC.tdesc.lptdesc.TYPEDESC.vt ; word = 00 1A => VT_PTR
mov edx,[edi].ELEMDESC.tdesc.lptdesc.TYPEDESC.lptdesc ;pointer to a new TYPEDESC
movzx edi,[edx].TYPEDESC.vt ; word = 00 1D => VT_USERDEFINED ??
mov edi,[edx].TYPEDESC.lptdesc ; dword = 00 00 B2 20 (not a pointer) ??


I cannot figure out if B220h is an index or offset or what.

José Roca

 
If [edx].TYPEDESC.vt is VT_USERDEFINED then you have to get a pointer to a new ITypeInfo interface calling the GetRefTypeInfo method of the previous ITypeInfo interface passing [edx].TYPEDESC.hreftype (hope this is the correct instruction, I'm not an ASM guy) as the parameter and start again to call GetDocumentation, GetTypeAttr, etc., with this new ITypeInfo interface. All this stuff is recursive.

Lars Jäderberg

That did it. For a couple of weeks I have read alot of com articles and tryed different ways of solving this. How on earth could one be able to know how to do it.

For each function I do:

invoke ppTypeInfo.GetNames, memid, addr Array, cArray, addr pcFound
.if eax==S_OK && pcFound>0
xor ecx,ecx
inc ecx
.while ecx<pcFound
push ecx
push ecx
lea edi,Array[0]
mov eax,4
mul ecx
add edi,eax

;edi is pointer to parameter names. Return parameter name is RHS

pop edx
dec edx
push edx

;Function giving parameter attributes

pop edx
pop ecx
inc ecx
.endw
.endif

inc edx
mov ecx,edx
.if ecx<pcFound
mov eax,ppFuncDesc
mov edi,[eax].FUNCDESC.lprgelemdescParam
mov eax,sizeof ELEMDESC
mul ecx
add edi,eax
movzx edx,[edi].ELEMDESC.tdesc.vt
.if edx==VT_PTR || edx==VT_SAFEARRAY || edx==VT_CARRAY
mov edx,[edi].ELEMDESC.tdesc.lptdesc.TYPEDESC.lptdesc
mov edi,[edx].TYPEDESC.hreftype
invoke ppTypeInfo.GetRefTypeInfo, edi, addr ppRefTypeInfo
.if eax==S_OK
invoke ppRefTypeInfo.GetDocumentation, -1, addr var.bstrVal, 0, 0, 0
.if eax==S_OK

;Name of return pointer. For example "Range"

.endif
.endif
.elseif edx==VT_USERDEFINED
mov edi,[edi].ELEMDESC.tdesc.hreftype
invoke ppTypeInfo.GetRefTypeInfo, edi, addr ppRefTypeInfo
.if eax==S_OK
invoke ppRefTypeInfo.GetDocumentation, -1, addr var.bstrVal,0,0,0
.if eax==S_OK

;Name of return param. For example "XLCreator"

.endif
.endif
.endif
.endif


Not sure if any of excel functions return edx==VT_SAFEARRAY or edx==VT_CARRAY.

I will work a litle more with this isue and then I will set to work at inherited interfaces. I hope I can get back if I get stuck. Thank you.

Lutfie Ahmad

QuoteHow on earth could one be able to know how to do it.
I can assure you that youve come to the right place and with the right person,
I accomplished my COM Browser http://www.freebasic.net/arch/file.php?id=44 with support of Mr. Jose.

Quote1. How do I retrieve the names of imported libraries.
if you mean treat COM or ActiveX as dll or static lib, there 2 possibilities.
1. the COM itself allow you to access some function directly from its dll via module.
eg. DirectX 8 matrix function or some VBA function
2. use GetProcAddress winapi command to get function address, but it need COM have dual intervace/direct vtable access.

but I dont know how to make it with asm

Lars Jäderberg

No, I mean how to retrieve the imported libs from a typelib. I have retrieved imported libs when exploring inherited interfaces. But I have not gone further with this isue at this point.

Lars Jäderberg

Now I have done a deep dive into the complicated build-up of ms type libraries. The result is a masm coded typelib browser. I don't know if it is allowed to send exe files but I attach one in the zip-file. My next step is to make a coding tool of it for assembler coding.

No installation is needed. Some appdata are written to registry under "HKEY_CURRENT_USER\Software\MINOR28\AutomationEXE" like window position and saved data.


Tab 3, CoClass methods. A click on column "Point at" value will bring you to that position.