Old 23rd March 2009, 10:08   #1
ExEyer
Junior Member
 
Join Date: Mar 2009
Posts: 10
CoCreateInstanceEx sample

Hi,

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

I have some troubles with passing COSERVERINFO and MULTI_QI structures.
ExEyer is offline   Reply With Quote
Old 23rd March 2009, 10:41   #2
Anders
Moderator
 
Anders's Avatar
 
Join Date: Jun 2002
Location: ${NSISDIR}
Posts: 5,449
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...

IntOp $PostCount $PostCount + 1
Anders is offline   Reply With Quote
Old 23rd March 2009, 10:55   #3
ExEyer
Junior Member
 
Join Date: Mar 2009
Posts: 10
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".
ExEyer is offline   Reply With Quote
Old 23rd March 2009, 11:08   #4
Anders
Moderator
 
Anders's Avatar
 
Join Date: Jun 2002
Location: ${NSISDIR}
Posts: 5,449
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

IntOp $PostCount $PostCount + 1
Anders is offline   Reply With Quote
Old 23rd March 2009, 11:39   #5
ExEyer
Junior Member
 
Join Date: Mar 2009
Posts: 10
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"
ExEyer is offline   Reply With Quote
Old 23rd March 2009, 11:49   #6
Anders
Moderator
 
Anders's Avatar
 
Join Date: Jun 2002
Location: ${NSISDIR}
Posts: 5,449
"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

IntOp $PostCount $PostCount + 1
Anders is offline   Reply With Quote
Old 23rd March 2009, 11:59   #7
ExEyer
Junior Member
 
Join Date: Mar 2009
Posts: 10
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)
ExEyer is offline   Reply With Quote
Old 23rd March 2009, 12:51   #8
Anders
Moderator
 
Anders's Avatar
 
Join Date: Jun 2002
Location: ${NSISDIR}
Posts: 5,449
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

IntOp $PostCount $PostCount + 1
Anders is offline   Reply With Quote
Old 23rd March 2009, 13:01   #9
ExEyer
Junior Member
 
Join Date: Mar 2009
Posts: 10
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.
ExEyer is offline   Reply With Quote
Old 23rd March 2009, 14:02   #10
Anders
Moderator
 
Anders's Avatar
 
Join Date: Jun 2002
Location: ${NSISDIR}
Posts: 5,449
I don't think IActiveDesktop supports running as anything other than inprocess

IntOp $PostCount $PostCount + 1
Anders is offline   Reply With Quote
Old 23rd March 2009, 14:11   #11
ExEyer
Junior Member
 
Join Date: Mar 2009
Posts: 10
You can use CLSCTX_INPROC_SERVER for CoCreateInstanceEx in this case.
ExEyer is offline   Reply With Quote
Old 23rd March 2009, 14:18   #12
Anders
Moderator
 
Anders's Avatar
 
Join Date: Jun 2002
Location: ${NSISDIR}
Posts: 5,449
Quote:
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.

IntOp $PostCount $PostCount + 1
Anders is offline   Reply With Quote
Old 23rd March 2009, 15:29   #13
ExEyer
Junior Member
 
Join Date: Mar 2009
Posts: 10
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.
ExEyer is offline   Reply With Quote
Old 23rd March 2009, 15:41   #14
Anders
Moderator
 
Anders's Avatar
 
Join Date: Jun 2002
Location: ${NSISDIR}
Posts: 5,449
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)

code:

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


IntOp $PostCount $PostCount + 1
Anders is offline   Reply With Quote
Old 23rd March 2009, 15:51   #15
ExEyer
Junior Member
 
Join Date: Mar 2009
Posts: 10
Could you please send the full nsi file?
ExEyer is offline   Reply With Quote
Old 23rd March 2009, 15:58   #16
Anders
Moderator
 
Anders's Avatar
 
Join Date: Jun 2002
Location: ${NSISDIR}
Posts: 5,449
why? all the important parts are right there in the sample code

IntOp $PostCount $PostCount + 1
Anders is offline   Reply With Quote
Old 23rd March 2009, 16:02   #17
ExEyer
Junior Member
 
Join Date: Mar 2009
Posts: 10
I have Access violation in your sample. I think I made some mistake in my code.
ExEyer is offline   Reply With Quote
Old 23rd March 2009, 18:43   #18
ExEyer
Junior Member
 
Join Date: Mar 2009
Posts: 10
Thumbs up

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!
ExEyer is offline   Reply With Quote
Reply
Go Back   Winamp & Shoutcast Forums > Developer Center > NSIS Discussion

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump