The following code crashes. Am I missing something here?



.data
pishl dd 0
CLSID_ShellLink GUID {00021401h, 0, 0, 0C0h,0,0,0,0,0,0,46h}
IID_IShellLink GUID {000214EEh, 0, 0, 0C0h,0,0,0,0,0,0,46h}

.code
invoke CoInitialize, 0
invoke CoCreateInstance,
@ CLSID_ShellLink, \ ; class identifier
0, \ ; not part of aggregate
CLSCTX_INPROC_SERVER, \ ; context
@ IID_IShellLink, \ ; Interface identifier
@ pishl ; ptr to storage of interface ptr
.if eax == S_OK
mov edx, pishl
mov edx, [edx]
call .d[edx+8] ; .Release
.endif
invoke CoUninitialize
Posted on 2003-09-03 16:02:38 by gfalen
No, looks good (if macros @ and .d are correct). At least no reason to "crash".

Possibly have a look at the assembly listing.
Posted on 2003-09-04 02:21:51 by japheth

No, looks good (if macros @ and .d are correct). At least no reason to "crash".

Possibly have a look at the assembly listing.


Hmmmm, there should be a "push edx" before the call to Release
Posted on 2003-09-04 02:28:17 by Morris
After reviewing my docs I found out what's wrong. I have seen several tutes which state that the proper way to call a COM interface is:

mov edx, ppv
push edx ; <=== this is WRONG
mov edx,
invoke INTERFACE ptr .function, args...

This is incorrect. The 'THIS' pointer should be the first argument in the invoke command. Also you may need ()'s around the ptr reference.
This works:

mov edx, ppv
mov edx,
invoke ppv, (INTERFACE ptr ).function, args...
Posted on 2003-09-04 02:35:33 by gfalen
Originally posted by gfalen
After reviewing my docs I found out what's wrong. I have seen several tutes which state that the proper way to call a COM interface is:

mov edx, ppv
push edx ; <=== this is WRONG
mov edx,
invoke INTERFACE ptr .function, args...


But this should be OK

.if eax == S_OK
mov edx, pishl
mov edx,
push edx ; <=== place a "push" here
call .d ; .Release
.endif
Posted on 2003-09-04 02:45:46 by Morris
NO - the THIS ptr must be the first arg in the invoke (just check your C++ source) which means it's the LAST arg pushed (STDCALL)!

That's why I changed it to

invoke ppv, (INTERFACE ptr ).function, args...

ppv is the THIS ptr.
Posted on 2003-09-04 02:49:11 by gfalen
Check this out. This program actually assembles and runs on my system - you need my macros to compile it.




include app32.inc
include com.inc

.data
CLSID_ShellLink GUID {00021401h, 0, 0, 0C0h,0,0,0,0,0,0,46h}
IID_IShellLink GUID {000214EEh, 0, 0, 0C0h,0,0,0,0,0,0,46h}
IID_IPersistFile GUID {00000010h, 0, 0, 0C0h, 0, 0, 0, 0, 0, 0, 46H}

.code
main proc
local sr:WIN32_FIND_DATA, des[260]:byte

IShellLink ishl

ishl@getinst @ CLSID_ShellLink, @ IID_IShellLink
.if eax == S_OK
ishl@SetPath "%windir%\explorer.exe"
ishl@SetDescription "my description"
ishl@GetPath dll$, 260, @ sr, 0
ishl@GetDescription @ des, 260
ishl@Release
msgbox @ des, dll$
.endif
ret
main endp

.end
Posted on 2003-09-04 02:54:16 by gfalen
Originally posted by gfalen
NO - the THIS ptr must be the first arg in the invoke (just check your C++ source) which means it's the LAST arg pushed (STDCALL)!


Tell me, how many arguments does the Release method expect?
Posted on 2003-09-04 02:55:05 by Morris
1 the THIS ptr
Posted on 2003-09-04 02:55:47 by gfalen

1 the THIS ptr


So, does it matter if you push it as the first or the last argument?
Posted on 2003-09-04 02:57:54 by Morris
No of course, not with the 'Release' method. But if you try & call a function with args, the proposed method will always fail - this was my problem.

BTW Did u see the source file I posted above?
Posted on 2003-09-04 03:01:22 by gfalen
Originally posted by gfalen
No of course, not with the 'Release' method. But if you try & call a function with args, the proposed method will always fail - this was my problem.


All the time I was referring to your original post - I noticed a problem with calling the Release method and gave you a hint.

Of course I know how to call CoMethods.


BTW Did u see the source file I posted above?

The first or the second one?
Posted on 2003-09-04 03:06:30 by Morris
Scroll back & look for it. I posted some source code i'm workin on. I think i finally have it workin now - ready to post my .inc files for COM.
Posted on 2003-09-04 03:09:01 by gfalen
Here's some files for u to play with. I think everything u need is there. The Interfaces are defined in Com.inc but it makes use of some existing macros so i put the other files in there with it. Comtest.asm is a llittle demo. Let me know if u can/can't assemblle it.
Posted on 2003-09-04 03:21:36 by gfalen
I must be blind, 'cause I can't see no files that I "can/can't assemblle".
Posted on 2003-09-04 03:26:26 by Morris
The previous attach failed. Ill try again. Oh it was a .rar/
Posted on 2003-09-04 03:32:55 by gfalen
Delete that 'include app32.inc' in comtest.asm & replace with your own include/includelib's

Edit:
You might need to add this macro to the top of com.inc

; Create pr0..pr24, and ptr's (ppr0..ppr24) and equates of the form
; "proto0 equ proto :dword"

makeproto MACRO _count
$args EQU <PROTO>
REPEAT _count
$args CATSTR $args, <, :DWORD>
ENDM
cnt@ TEXTEQU %_count
% pr&cnt@ TYPEDEF $args ; pr0, pr1... lower case
% ppr&cnt@ TYPEDEF ptr pr&cnt@ ; ppr0, ppr1...
% proto&cnt@ EQU $args ; proto0, proto1...
% PR&cnt@ TYPEDEF $args ; PR0, PR1... UPPER case
% PPR&cnt@ TYPEDEF ptr pr&cnt@ ; PPR0, ppr1...
% PROTO&cnt@ EQU $args ; PROTO0, PROTO1...
ENDM

i@ = 0
WHILE i@ lt 25
makeproto i@
i@ = i@ + 1
ENDM
Posted on 2003-09-04 03:35:26 by gfalen
I have a very custumized compile environment. I'm trying to figure out the minimum files needed. You might also need this guy.
Posted on 2003-09-04 03:43:45 by gfalen
I couldn't make it assemble, sorry.

I do not have those includes

wintypes.inc
classes.inc
crtdll.inc

and that may be the source of the problem.

Anyway, what you're trying to prove with the code you sent?
Posted on 2003-09-04 03:49:23 by Morris
A new upload

Edit:
Comment out the crtdll.inc & dialogs.inc references from lib32.inc
Posted on 2003-09-04 03:55:37 by gfalen