flat assembler
Message board for the users of flat assembler.
Index
> Windows > sIID_IShellExtInit from MASM to FASM |
Author |
|
ManOfSteel 25 Jul 2007, 06:50
Any idea?
|
|||
25 Jul 2007, 06:50 |
|
madmatt 25 Jul 2007, 08:44
Give this a try.
Code: format PE GUI 4.0 entry start include 'win32a.inc' struct GUID Data1 dd ? Data2 dw ? Data3 dw ? Data4 db 8 dup(?) ends interface IShellExtInit,\ QueryInterface,\ AddRef,\ Release,\ Initialize section '.data' data readable writeable MyShellExtInit IShellExtInit IID_IShellExtInit GUID $214E8, 0, 0, <$C0,0,0,0,0,0,0,$46> section '.code' code readable executable invoke CoInitialize, NULL invoke CoCreateInstance, NULL, NULL, CLSCTX_INPROC_SERVER, IID_IShellExtInit, MyShellExtInit cominvk MyShellExtInit, Initialize |
|||
25 Jul 2007, 08:44 |
|
ManOfSteel 26 Jul 2007, 10:06
I figured it all out yesterday. My final code was not far from yours. But thanks anyway.
By the way, I'm trying to program a shell extention and it's quite tough. You would not by chance know of anyone written in fasm? |
|||
26 Jul 2007, 10:06 |
|
madmatt 27 Jul 2007, 07:50
No I don't, sorry.
|
|||
27 Jul 2007, 07:50 |
|
ManOfSteel 28 Jul 2007, 14:55
Hello,
I've been trying to make an "easier" COM server that only shows a simple message box when a client requests its object. But it's not working any better than my previous attempt. For the last few days, I've been reading dozens MSDN pages and tutorials on COM, and checking C++ and MASM source code to no avail. I can't make it work. Almost everytime I try to register the server (with 'regsvr32 /c'), I get the following exception. Sometimes the error doesn't show, but the server is not registered and the client - which works well with other servers of the same kind - returns an error code. What is constant is the system going awry after any registration attempt. I've attached the code and would greatly appreciate any help. Quote:
|
|||||||||||
28 Jul 2007, 14:55 |
|
SFeLi 29 Jul 2007, 06:31
In DllRegisterServer/DllUnregisterServer:
Code: invoke RegOpenKey,HKEY_CLASSES_ROOT,szCLSID,[hKey] Quote: phkResult — Points to a variable that receives the handle of the opened or created key. Code: lea eax,[hKey] invoke RegOpenKey,HKEY_CLASSES_ROOT,szCLSID,eax In DllGetClassObject (and later): Code: mov eax,[eax] ;Get POINTER to VTABLE from object. call dword [eax + 0] ;And call the first method (QueryInterface). ; and pICF IClassFactory ;<-- Invalid. Must be POINTER to INITIALIZED vtable. ICFRefCount dd 1 Also look at the include/macro/com32 — you're incorrectly using interface macro. Construct vtable manually or use structures. PS: What extension do you want to write? |
|||
29 Jul 2007, 06:31 |
|
ManOfSteel 29 Jul 2007, 18:15
Hello SFeLi and thanks for your reply.
Quote:
I don't really understand. pICF is like a shortcut to the IClassFactory interface pointer whose methods (i.e. vtable) are all pointing to the implemented procedures (QueryInterface_CF, AddRef_CF, etc). Quote: Also look at the include/macro/com32 ? you're incorrectly using interface macro. How should I use it? I've always used it that way in my COM clients (ShellLink, ActiveDesktop, DirectSound, etc) without any problem. Why should it be different with servers? Quote: Construct vtable manually or use structures. Are you suggesting I use dword arrays like this: Code: IClassFactory: dd ? dd QueryInterface_CF dd AddRef_CF dd Release_CF dd CreateInstance dd LockServer IMsgbox: dd ? dd QueryInterface_MC dd AddRef_MC dd Release_MC dd DoMsgbox or Code:
struct IClassFactory
interface dd ?
QueryInterface_CF dd ?
AddRef_CF dd ?
Release_CF dd ?
CreateInstance dd ?
LockServer dd ?
ends
IMsgbox:
interface dd ?
QueryInterface_MC dd ?
AddRef_MC dd ?
Release_MC dd ?
DoMsgbox dd ?
ends
Correct me if I'm wrong, but isn't that what the interface macro actually does? Quote: PS: What extension do you want to write? This code is not an extension. It only allows the client to use DoMsgbox to display a message box. I'm just trying to learn how COM servers work. My previous (failed) attempt at COM servers was a context menu shell extension. |
|||
29 Jul 2007, 18:15 |
|
SFeLi 29 Jul 2007, 21:14
Quote: interface macro. How should I use it? I've always used it that way in my COM clients. Why should it be different with servers? The only thing that interface macro does is generate offsets for methods. For example: Code: interface IXyzzy,\ QueryInterface,\ AddRef,\ Release,\ Foo,\ Bar,\ Baz ;will generate virtual-at-0 equivalent of label IXyzzy.QueryInterface dword at 0x00000000 label IXyzzy.AddRef dword at 0x00000004 label IXyzzy.Release dword at 0x00000008 … If you want to define vtable, then: Code: ;either define it manually: IXyzzyVtbl dd IXyzzy_QueryInterface dd IXyzzy_AddRef dd IXyzzy_Release dd … ;or create a structure for it: struct IXyzzy QueryInterface dd ? AddRef dd ? Release dd ? … ends IXyzzyVtbl IXyzzy IXyzzy_QueryInterface,\ IXyzzy_AddRef,\ IXyzzy_Release Quote: pICF is like a shortcut to the IClassFactory interface pointer whose methods (i.e. vtable) are all pointing to the implemented procedures (QueryInterface_CF, AddRef_CF, etc). See above. It points to NULL in your code: Quote: Output of “pICF IClassFactory” is: 0x004010b1: 0x00000004 bytes (00 00 00 00) Quote: Are you suggesting I use dword arrays Yes. But (hint!) why not to have static vtables? I attached my old source, that implements fake COM object, maybe you can find something useful there.
Last edited by SFeLi on 30 Jul 2007, 17:39; edited 1 time in total |
|||||||||||
29 Jul 2007, 21:14 |
|
ManOfSteel 30 Jul 2007, 13:41
Hello and thanks for the source code.
I went over my code and corrected all errors about interfaces and vtables. I defined the ClassFactory object as a static object. When I try to register it, regsvr32 shows a successful registration message, but the server is still not registered properly. I've attached the modified code. Thanks for continuing to help me.
|
|||||||||||
30 Jul 2007, 13:41 |
|
SFeLi 30 Jul 2007, 17:37
Quote: the server is still not registered properly Now you pass hKey correctly, but forgot about hKey2 and hKey3. Code: proc CreateInstance pUnknownOuter,iid,ppv You forgot “this”. And after fixing these errors… it works! Congratulations! Not critical, but violates COM binary interface: Code: proc DllGetClassObject pCLSID,pIID,ppv … .else mov [hr],CLASS_E_CLASSNOTAVAILABLE .endif “ppv — indirect pointer to the requested interface or, if an error occurs, to NULL.” Same errors in CreateInstance (E_OUTOFMEMORY and CLASS_E_NOAGGREGATION cases). Code: call [IMsgbox.QueryInterface + eax] mov [hr],eax .if eax = 0 ; query failed, no valid pointer, release object Failed? It returns HRESULT, not BOOL. And 0 is S_OK. Must be “.if eax < 0”. And… Why do you release static class factory in DllGetClassObject? DllGetClassObject doesn't create ClassFactory object, nor increase its reference count, so it must not decrease it's reference count or call Release after calling QueryInterface. |
|||
30 Jul 2007, 17:37 |
|
ManOfSteel 31 Jul 2007, 18:05
Hello SFeLi.
Yes, I had made some silly mistakes but it all works perfectly now. I've also corrected the rest. Now, I'll try my best with shell extensions. Your help has been very useful. Thank you very much. |
|||
31 Jul 2007, 18:05 |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.