News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

COM Typelib

Started by mabdelouahab, February 05, 2014, 10:30:02 AM

Previous topic - Next topic

mabdelouahab

hi ,
When it comes to Type Lib
I used the following method to get every time the next ELEMDESC (curFuncParam_) of current FuncDesc

mov edx,[edi].curFuncDesc_
mov eax,(FUNCDESC ptr[edx]).[b]lprgelemdescParam [/b]
mov L1,eax

mov eax,[edi].curFuncParam_
mov ebx,sizeof ELEMDESC +4
Mul ebx
add eax,L1; ecx,eax
mov edx,eax

mov ed,edx

There is no problem in the code because it gives me the correct result
But the problem is in the extraction wParamFlags,Always 0

mov edi,ed;
movzx edx,[edi].ELEMDESC.paramdesc.wParamFlags

At first I thought, that the problem is in the code
But when I returned to the assistant (http://msdn.microsoft.com/en-us/library/cc237611.aspx), I found that to remain on the value 0 when it comes to lprgelemdescParam Array
Quote
paramdesc: MUST contain a PARAMDESC that has the values as specified in section 2.2.40, if the ELEMDESC is a member of the lprgelemdescParam array in a FUNCDESC (section 2.2.42) structure. Otherwise, it MUST contain a PARAMDESC that has the data fields pparamdescex and wParamFlags set to NULL and 0 respectively.

Is there a way to get wParamFlags

jj2007

"Otherwise, it MUST contain a PARAMDESC that has the data fields pparamdescex and wParamFlags set to NULL and 0 respectively."

typedef struct tagPARAMDESC {
  PARAMDESCEX* pparamdescex;
  USHORT wParamFlags;
} PARAMDESC;

Something like PARAMDESC <0,0>? Can't test it obviously...

Actually, it looks as if and edx,[edi].ELEMDESC.paramdesc.wParamFlags, 0 could work, too.

mabdelouahab

Hello jj2007,
I'm sorry for the delay
The program included, if one wanted to kindly corrects
The problem is in the procedure XParameterFlag_
Variable wParamFlags is always 0 : "NONE"
FE:
Quote
              ->>> Param Name: lcid[-NONE:!:NONE-] <UI4>
              ->>> Param Name: wFlags[-NONE:!:NONE-] <UI2>
              ->>> Param Name: pdispparams[-NONE:!:NONE-] <PTR ( USERDEFINED ( DISPPARAMS )  ) >
              ->>> Param Name: pvarResult[-NONE:!:NONE-] <PTR ( VARIANT ) >
"NONE/IN/OUT/LCID/RETVAL/OPT/HASDEFAULT/HASCUSTDATA" 
You can test a program on any TLB by changing the value of Bstr_Name in Xmain

    mov Bstr_Name,CStr("C:\WINDOWS\help\sstub.dll")


jj2007

Hi mabdelouahab,

Yes, it seems that wParamFlags is always 0.

For pparamdescex I get many different values, but they are all in the byte range - typically 50...120

Unfortunately, COM is not my strong point. I hope some of the geniuses here can shed light on this problem...

mabdelouahab

I found this discussion in the Forum, But not the details, I do not know how to do it
http://www.masmforum.com/board/index.php?PHPSESSID=786dd40408172108b65a5a36b09c88c0&topic=13573.0;prev_next%3Dprev

In cpp, variable wParamFlags  reads directly
I found these examples:

bool TypeLib::ParameterIsHasX(int flag) {
  ELEMDESC e = curFuncDesc_->lprgelemdescParam[curFuncParam_];
  return e.paramdesc.wParamFlags & flag;
}

for (SHORT index = 0; index < pfd->cParams; index++)
{
ELEMDESC *pdesc = pfd->lprgelemdescParam + index;
flags.create();
if ((pdesc->paramdesc.wParamFlags & PARAMFLAG_FIN) ||
(pdesc->paramdesc.wParamFlags == PARAMFLAG_NONE))
flags.lappend("in");
if (pdesc->paramdesc.wParamFlags & PARAMFLAG_FOUT)
flags.lappend("out");
if (pdesc->paramdesc.wParamFlags & PARAMFLAG_FRETVAL)
flags.lappend("retval");


USHORT paramFlags = pfuncdesc->lprgelemdescParam[i].paramdesc.wParamFlags;

mabdelouahab

Did no one tell me what is the difference between me and:
http://www.jose.it-berater.org/smfforum/index.php?topic=3275.msg10738#msg10738

I think he succeeded in taking the values
I've experimented with what he has done literally, but the same problem

What ?
Is not there someone has a solution ?

dedndave

Lars seems to know as much about it as anyone - and he gave up   :redface:
he's a forum member and pops in once in a while (Minor28)

dedndave

hang on - looks like he might have had some success, afterall

try this link - and open the "Type lib browser" tab
http://minor28.divdev.se/Home.php

mabdelouahab

And finally
The problem in ELEMDESC  struct
lprgelemdescParam is a pointer to an array of ELEMDESC  :

Quote
lprgelemdescParam: MUST refer to an array of ELEMDESC that contains one entry for each element in the method's parameter table.
http://msdn.microsoft.com/en-us/library/cc237619.aspx

When we calculate the length of
ELEMDESC => (TYPEDESC +PARAMDESC )=>(DW+W+DW+W) =12
But length is given in array is 16.
And when we put [edi].ELEMDESC.paramdesc.wParamFlags the pointer indicates the byte No. 10
But wParamFlags  exists in byte No. 12

mov ecx,XcurFuncParam_ 
mov eax,XcurFuncDesc_
mov edi,[eax].FUNCDESC.lprgelemdescParam
mov eax,sizeof ELEMDESC+4 ; SiseOf ELEMDESC => 12+4 =16
mul ecx
add edi,eax
movzx edx,word ptr [edi+12]

I have no explanation
But I got it after I've examined the array byte byte
Secondly
The following does not give us the correct result
XGetPARAMFLAGString PROC  tf:dword
    LOCAL pstr_:dword 
.if tf    == PARAMFLAG_NONE
mov pstr_,chr$("NONE")
.elseif tf ==PARAMFLAG_FIN
mov pstr_,chr$("IN")               
.elseif tf ==PARAMFLAG_FOUT
mov pstr_,chr$("OUT")             
.elseif tf ==PARAMFLAG_FLCID
mov pstr_,chr$("LCID")           
.elseif tf ==PARAMFLAG_FRETVAL
mov pstr_,chr$("RETVAL")           
.elseif tf ==PARAMFLAG_FOPT
mov pstr_,chr$("OPT")               
.elseif tf ==PARAMFLAG_FHASDEFAULT
mov pstr_,chr$("HASDEFAULT")             
.elseif tf ==PARAMFLAG_FHASCUSTDATA
mov pstr_,chr$("HASCUSTDATA")           
.else
mov pstr_,chr$(33)
.endif
mov eax ,pstr_
ret
    XGetPARAMFLAGString ENDP

You have to replace it
XGetPARAMFLAGString PROC  tf:dword
    LOCAL pstr_:dword 
   
    mov pstr_,chr$(33)
   
    mov ecx, PARAMFLAG_NONE
and ecx,tf
.if ecx
mov pstr_,chr$("NONE")
.endif
    mov ecx, PARAMFLAG_FIN
and ecx,tf
.if ecx
mov pstr_,chr$("IN")
.endif
    mov ecx, PARAMFLAG_FOUT
and ecx,tf
.if ecx
mov pstr_,chr$("OUT")
.endif
    mov ecx, PARAMFLAG_FLCID
and ecx,tf
.if ecx
mov pstr_,chr$("LCID")
.endif
    mov ecx, PARAMFLAG_FRETVAL
and ecx,tf
.if ecx
mov pstr_,chr$("RETVAL")
.endif
    mov ecx, PARAMFLAG_FOPT
and ecx,tf
.if ecx
mov pstr_,chr$("IN OPT")
.endif
    mov ecx, PARAMFLAG_FHASDEFAULT
and ecx,tf
.if ecx
mov pstr_,chr$("HASDEFAULT")
.endif
    mov ecx, PARAMFLAG_FHASCUSTDATA
and ecx,tf
.if ecx
mov pstr_,chr$("HASCUSTDATA")
.endif
mov eax ,pstr_
ret
    XGetPARAMFLAGString ENDP

Thanks to all

jj2007

So it seems a structure alignment issue...

Compliments, you solved a very difficult problem :t

mabdelouahab

Thank you jj2007
Means that I have to do as follows


ELEMDESC struc DWORD
  tdesc         TYPEDESC    <>
    paramdesc   PARAMDESC   <>
ELEMDESC ends

As it is in OAIDL.IDL

typedef struct tagELEMDESC {    /* a format that MIDL likes */
    TYPEDESC tdesc;             /* the type of the element */
    PARAMDESC paramdesc;        /* IDLDESC is a subset of PARAMDESC */
} ELEMDESC;

And now I write code as follows:
mov ecx,XcurFuncParam_ 
mov eax,XcurFuncDesc_
mov edi,[eax].FUNCDESC.lprgelemdescParam
mov eax,sizeof ELEMDESC       ;+4
mul ecx
add edi,eax
movzx edx,[edi].ELEMDESC.paramdesc.wParamFlags         ;word ptr [edi+12]

Now is working correctly
Thank you

TWell

Quote from: mabdelouahab on February 09, 2014, 04:44:09 PM
Means that I have to do as follows


ELEMDESC struc DWORD
  tdesc         TYPEDESC    <>
    paramdesc   PARAMDESC   <>
ELEMDESC ends

As it is in OAIDL.IDL

typedef struct tagELEMDESC {    /* a format that MIDL likes */
    TYPEDESC tdesc;             /* the type of the element */
    PARAMDESC paramdesc;        /* IDLDESC is a subset of PARAMDESC */
} ELEMDESC;

fixed if TYPEDESC struc DWORD 8 and PARAMDESC struc DWORD 8

NZavaloff

"Otherwise, it MUST contain a PARAMDESC that has the data fields pparamdescex and wParamFlags set to NULL and 0 respectively."