Archive: CoCreateInstanceEx sample


CoCreateInstanceEx sample
Hi,

Is there any sample of usage System::Call "ole32::CoCreateInstanceEx" ?

I have some troubles with passing COSERVERINFO and MULTI_QI structures.


So you want to use a COM object on a remote machine?

You need to allocate those structs with System::Call '*( ........ )i.r0 or something like that (change ..... to the actual members of the struct, use i for DWORD's and pointers)

Post some of the code you already have...


Yes, I need make a remote call to another DCOM server.

Here is the my sample code:

; COSERVERINFO struct
System::Alloc 16
pop $3

; MULTI_QI struct
System::Alloc 12
pop $4

System::Call "ole32::CoCreateInstanceEx( \
g '${CLSID_PRNWATCH}', *i 0, \
i ${CLSCTX_REMOTE_SERVER}, \
*(i 0, t 'localhost', *i 0, i 0)i.r3 \
i 1, \
*(g 'GUID_IPRNWATCHSERVER', *i.r0, i 0)i.r4) \
i.r1"

I have got in #1 0x80070057 error - The parameter is incorrect.

CLSID_PRNWATCH and GUID_IPRNWATCHSERVER are correct values. It works fine with System::Call "ole32::CoCreateInstance".


you can't init the struct IN the call to the function.

you need to do System::Call '*$3(i 0,.....)' before calling CoCreateInstanceEx

See http://nsis.sourceforge.net/System_p...e#Setting_Data


Thank you for your help.
Unfortunately, the same error (The parameter is incorrect) with this code:

System::Alloc 16
pop $3
System::Alloc 12
pop $4

System::Call *$3(i 0, t 'localhost', i 0, i 0)
System::Call *$4(g '${GUID_IPRNWATCHSERVER}', *i .r0, i 0)

System::Call "ole32::CoCreateInstanceEx( \
g '${CLSID_PRNWATCH}', *i 0, \
i ${CLSCTX_REMOTE_SERVER}, \
i .r3, \
i 1, \
i .r4) \
i.r1"


"i .r3" means output in r3, remove the .

also, in System::Call *$4(g '${GUID_IPRNWATCHSERVER}', *i .r0, i 0), the *i part does not look right to me, i 0 might be enough


So how can I take the output IUnknown in MULTI_QI?

If I change -

System::Call *$4(g '${GUID_IPRNWATCHSERVER}', *i .r0, i 0)

to

System::Call *$4(g '${GUID_IPRNWATCHSERVER}', i 0, i 0)


without looking it up in msdn again, IIRC its a IUnknown*, so its just 4 bytes, after the call to CoCreateInstanceEx returns, those 4 bytes in the struct should now contain the address of the interface

If you can give me the CLSID and IID of something that would exist on a default XP install, I could maybe come up with some working code if you can't make it work. But first, test again without the . in .r3


Thank a lot!
You can use this object -

!define CLSID_ActiveDesktop {75048700-EF1F-11D0-9888-006097DEACF9}
!define IID_IActiveDesktop {F490EB00-1240-11D1-9888-006097DEACF9}

It presents in default XP system and works fine for CoCreateInstance.

I have changed .r -> r, but without any success.


I don't think IActiveDesktop supports running as anything other than inprocess


You can use CLSCTX_INPROC_SERVER for CoCreateInstanceEx in this case.


Originally posted by ExEyer
You can use CLSCTX_INPROC_SERVER for CoCreateInstanceEx in this case.
and that is pointless, the problem here is getting the structs to work, I was hoping I could test on my machine by just using \\machinename, but I need a COM object I can use first.

I do not think that it is CLSCTX_INPROC_SERVER/CLSCTX_REMOTE_SERVER problem. So it can be tested with inproc server, i.e. IActiveDesktop.

Anyway, I cannot find any standard DCOM server in default Windows XP. I can create DCOM Test Server and upload it.
Let me know if you need it.


clearly it could not be tested with inproc, getting inproc to work is easy.

Anyway, I got it working now. It uses a undocumented Windows Messenger interface (probably XP only)


Section
!include LogicLib.nsh

!define CLSCTX_REMOTE_SERVER 0x10

System::Call "kernel32::GetComputerNameA(t .r9,*i ${NSIS_MAX_STRLEN} )i"
!define REMOTEMACHINE "\\$9" ;"\\MACHINENAME"

System::Call '*(g "{7C95459B-C8E7-4605-B641-45EB06866659}",i0,i0)i.R0' ;MULTI_QI
System::Call '*(i0,w "${REMOTEMACHINE}",i0,i0)i.R1' ;COSERVERINFO
System::Call 'ole32::CoCreateInstanceEx( \
g "{AB1D8565-40E9-4616-984D-98465687E82C}",i0,i ${CLSCTX_REMOTE_SERVER},i R1,i1,i R0)i.s'
pop $0
DetailPrint CoCreateInstanceEx=$0
System::Free $R1
${If} $0 = 0
System::Call *$R0(i,i.r0,i.r1)
DetailPrint "IFace*=$0 hr=$1"
${If} $1 = 0
;use interface here
System::Call "$0->2()" ;Release
${EndIf}
${EndIf}
System::Free $R0


SectionEnd

Could you please send the full nsi file?


why? all the important parts are right there in the sample code


I have Access violation in your sample. I think I made some mistake in my code.


Now it's working.
My mistake was using
System::Call 'ole32::CoCreateInstanceEx(g '${CLSID_PRNWATCH}', ...)'

instead
System::Call 'ole32::CoCreateInstanceEx(g "${CLSID_PRNWATCH}", ...)'

Thank you Anders!