News:

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

Main Menu

Implementation of the COM interface FileOpenDialog

Started by jorgon, February 19, 2025, 11:31:58 AM

Previous topic - Next topic

NoCforMe

Quote from: jorgon on February 20, 2025, 04:27:17 PMIn:
MOV EAX,[iFILEOPENDIALOG]
CALL [EAX+0Ch]

First line: EAX is given a pointer to the vtable held in Windows memory/data.
Second line: your exe calls the value 12 bytes into the vtable held in Windows memory/data. This is the address in the Windows code of the function that your exe wants to call.

This address is a value put into the vtable held in Windows memory/data when the COM interface is loaded.  This address will probably change from time to time as the COM dlls are updated.

So as I wrote, the vtables get filled in at runtime, right?
And when exactly is the COM interface loaded? Is it the call to CoInitializeEx()?
Assembly language programming should be fun. That's why I do it.

jorgon

Quote from: NoCforMe on February 20, 2025, 05:14:34 PMOK. So where does one get those files? I don't have any C compilers here, no Visual Studio, none of that stuff.
Sorry to keep bugging you, but your answers only trigger more questions.

I believe there is a forum here called "MASM include files", which may have them.
As you say, you could download something like Visual Studio which has them.
Or I find it quite easy simply to put the name of the file in a search engine and they come up in a result in GitHub.

jorgon

Quote from: NoCforMe on February 20, 2025, 05:17:24 PMAnd when exactly is the COM interface loaded? Is it the call to CoInitializeEx()?

I think it's more likely they are loaded in the call to CoCreateInstance, because it is only then that the system knows which part of the COM library you want to use.  It will identify this from the GUIDs passed as parameters to that function (that is, the CLSID_ and the IID_) which identify the class of the "object" and the COM interface which you want to use respectively.

I haven't checked this in the debugger.

NoCforMe

The MASM include files subforum (and its subforum Windows include files) doesn't contain any of those files.

You mentioned ShObjidl_core.h; that's not even an assembler include file (which would be an .inc file).

I'm not about to mess around with Visual Studio.

OK, I found that header file in some GitHub repository: https://github.com/tpn/winsdk-10/blob/master/Include/10.0.14393.0/um/ShObjIdl_core.h

Looking through it, I find a bunch of what look like vtable structures, like so:
    typedef struct IShellLinkWVtbl
    {
        BEGIN_INTERFACE
       
        HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
            __RPC__in IShellLinkW * This,
            /* [in] */ __RPC__in REFIID riid,
            /* [annotation][iid_is][out] */
            _COM_Outptr_  void **ppvObject);
       
        ULONG ( STDMETHODCALLTYPE *AddRef )(
            __RPC__in IShellLinkW * This);
       
        ULONG ( STDMETHODCALLTYPE *Release )(
            __RPC__in IShellLinkW * This);

However, comparing it to what you posted, I'm expecting to find the following sequence of "methods" (I guess that's what they're called in C++?):
  • QueryInterface
  • AddRef
  • Release
  • Show

which is what you have in your vtable, IFileOpenDialog.

But there's no such sequence in that header file. Nor is there anything like what you called your structure, "IFileOpenDialog".

So what am I missing here?
Assembly language programming should be fun. That's why I do it.

_japheth

Quote from: NoCforMe on February 20, 2025, 06:03:18 PMThe MASM include files subforum (and its subforum Windows include files) doesn't contain any of those files.

In the WinInc include files there are some assembly COM include files, also ShlobjIdl.inc: https://github.com/Baron-von-Riedesel/WinInc/tree/main/Include

I doubt however, that they are easier to read/understand than their C++ counterparts.


Quote from: NoCforMe on February 20, 2025, 06:03:18 PMSo what am I missing here?

You're lacking the basics of COM knowledge.
It's not that hard, actually. A COM object usually is a dynamically allocated STRUCT. It's not allocated by you, but usually by a dll that implements the COM object - if you call CoCreateInstance (or similar functions), the dll will allocate and initialize that STRUCT. However, for you ( or rather: your program ), all members of the STRUCT are hidden, except one: the ominous VTBL. So all you can do with that STRUCT is to call functions included in that "virtual function table".
Dummheit, gepaart mit Dreistigkeit - eine furchtbare Macht.

jorgon

QuoteBut there's no such sequence in that header file. Nor is there anything like what you called your structure, "IFileOpenDialog".

So what am I missing here?

Well, this is where, as an assembler programmer, you have to clean up the mess.

If you go to this part of the ShObjIdl_core.h file:

#ifdef COBJMACROS

#define IFileOpenDialog_QueryInterface(This,riid,ppvObject) \
    ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )

#define IFileOpenDialog_AddRef(This) \
    ( (This)->lpVtbl -> AddRef(This) )

#define IFileOpenDialog_Release(This) \
    ( (This)->lpVtbl -> Release(This) )

#define IFileOpenDialog_Show(This,hwndOwner) \
    ( (This)->lpVtbl -> Show(This,hwndOwner) )

#define IFileOpenDialog_SetFileTypes(This,cFileTypes,rgFilterSpec) \
    ( (This)->lpVtbl -> SetFileTypes(This,cFileTypes,rgFilterSpec) )
The definitions are easier to follow, and you can see that on the assumption that each #define is a dword (which they would be because each resolves to an address of a function in the vtable) then the first is QueryInterface, the second is AddRef and so on.  The part in brackets after the name of the function contains the parameters and so this produces the table in my FileOpenDialog file. 

Header file converters have been written to try to automate this but when you only want one vtable it can be done quite quickly on the keyboard.

NoCforMe

But what you show isn't even in that file!
Don't believe me? Go there and do a search for "IFileOpenDialog". Not found.
(I'm referring to that GitHub file I linked to above. ShObjIdl_core.h)
Assembly language programming should be fun. That's why I do it.

NoCforMe

Well, whaddya know: this file has that stuff in it.

So now the question is, how do you even know which file (which version, I guess) to use?

This all is still very mysterious. Not the way it works--I get how the vtable works--but just how to find the right file and the code you need to create the structures in assembly language.

Still a lot of handwaving going on here ...
Assembly language programming should be fun. That's why I do it.

jorgon

QuoteSo now the question is, how do you even know which file (which version, I guess) to use?

Yes exactly.

If you look on the internet at the problems higher level programmers raise, they are quite often whether the platform is properly set up with the correct files, the correct configuration etc. 

As assembler programmers we are able to reduce these issues to the minimum.

Since the header files or includes come in different versions but with the same names, I much prefer to have that part of the includes in the asm file itself.

I'm wondering whether I've earned my award yet.

NoCforMe

Well, that's nice, but you didn't answer the question. So sorry, no award for you yet.

I still have no clue how to determine which version of a file (say, ShObjIdl_core.h) is the correct one. Or, let's say, a version that will at least work for converting to an .inc file. (And yes, I can do that by hand.)
Assembly language programming should be fun. That's why I do it.

sinsi

The latest version will be in the latest Windows Kit (currently 10.0.26100.0).

NoCforMe

Assembly language programming should be fun. That's why I do it.


jorgon

Quote from: NoCforMe on February 20, 2025, 07:22:52 PMWell, that's nice, but you didn't answer the question. So sorry, no award for you yet.

I still have no clue how to determine which version of a file (say, ShObjIdl_core.h) is the correct one. Or, let's say, a version that will at least work for converting to an .inc file. (And yes, I can do that by hand.)

In order to win my award, I answer as follows.

You can't tell which is the correct one, apart from looking inside to see if it has what you are looking for, but it matters a lot less than you would think because the names of the functions, the number of parameters the function expects, and the types of those parameters will never change.  If they did, progs compiled using the old headers would fail.

GoAsm does not check that the number or types of parameters matches those in the header file, so getting the correct header file is even less important.  So GoAsm works without any header files or includes.  This means that in GoAsm if you pass the wrong number or type of parameter to a Windows API the prog just crashes.  If this happens you can check the code to see if you've passed the correct number or type of parameters to the API.

When calling a Windows API it is often crucial to get the structures passed to the API correct, and in GoAsm this can be done within the source code in the same way as you have seen from the FileOpenDialog file when calling a COM function.

TimoVJL

#29
DELETED
May the source be with you