Specifically I want to see all interfaces in the MSHTML library. I can't decompile it because it's written in a native language
If you load the dll or the tlb file into any COM Interface viewer you will be able to see all the Interfaces it declares. COM Interfaces are public so you don't need to decompile they are designed to be easily read.
There is a list here of Type Library Viewers, or you could look up the documentation for MSHTML online
Related
As mentioned in Microsoft documentation there are two ways to create COM objects:
The module that implements the object might provide a function specifically designed to create instances of that object.
Alternatively, COM provides a generic creation function named CoCreateInstance.
In direct3D you can use first method to create Objects like you use D3D11CreateDevice()
but how you do this by the second method.maybe you need CLSID_D3D11CreateDevice which I didn't find.Is there any library to include or maybe it's impossible to create by the second way.
Also I really like to know if there is a way to see COM objects and what interfaces they implement.
DirectX APIs are not "true COM". These APIs derive from IUnknown for reference counting and polymorphic interfaces for versioning, but they do not follow all the other rules of COM objects. The lifetime rules are also modified for "child" objects, and DirectX APIs only support COINIT_MULTITHREADED.
This is a design pattern known informally as "COM lite" or "nano-COM".
Objects are created with a Win32 "flat" factory function
Objects generally support only IUnknown, the main interface, and derived versions of the main interface
Methods on interfaces can return void or HRESULT
Not all methods need to be thread-safe
They do not support COM aggregation
Interface pointers as parameters do not support client-provided implementations
Direct2D/DirectWrite and Windows Imaging Component (WIC) support CoCreateInstance as did did the original XAudio2 for Windows up to version 2.7 and legacy XACT. Otherwise, "DirectX" components do not support registry-based or manifest-based creation.
This pattern provides a stable "Application Binary Interface (ABI)" and maps well to C++ single-inheritance of pure-virtual classes. It provides an easy way to extend with new versions to add methods, and reference-counting for lifetime management. The resulting APIs are generally compatible with the IID_PPV_ARGS macro as well as COM smart-pointers like Microsoft::WRL::ComPtr, winrt::com_ptr, or the older ATL CComPtr.
See Microsoft Docs: Programming DirectX with COM
More recent versions of DirectX like DirectX 12 have adopted "strongly-typed bitmasks" which were not used in older versions. See this blog post.
While historically the DirectX "COM lite" APIs have provided C support through macros, the most recent guidance is to just support C++ and make use of C++11 features like strongly-typed enumerations (a.k.a. scoped enumerations). You'll see this reflected in the DXCore interfaces.
I understand how COM can achieve compiler agnostic C++ code, since it defines an ABI by being careful what features of the C++ language to use. It's just C++ code talking to C++ code in a really clever way. However I still don't understand how it can allow for language interop with C# or Javascript for example.
Where is the boundary? The only explanation I have right now is that the language compiler itself must have special support for COM so that it can generate the proper assembly code to allow for accurate communication between caller/callees.
Since you've tagged your question with WinRT, I assume you're asking specifically about how this is achieved by WinRT language projections. In that case, all languages must have some way to map their natural language constructs to the COM ABI that WinRT defines. That ABI is derived from metadata encoded in the ECMA 335 standard and special rules are applied to transform the abstract metadata into a concrete ABI. There are naturally different ways to achieve this. The CLR itself was updated to support WinRT in C#. The Visual C++ compiler was (sadly) updated with language extensions to support WinRT via C++/CX. The C++/WinRT approach is very different in that it requires only a standard C++ compiler and all of the knowledge about WinRT is delivered via a standard C++ header-only library. Other languages might take different approaches, but at the end of the day they must agree on the way that types expressed in metadata are transformed into objects and virtual function calls on the ABI based on COM.
And while this process is not well documented at the moment, C++/WinRT is one of the only open source language projections and thus acts as a useful reference implementation for those who need to understand how WinRT works under the hood.
https://github.com/microsoft/cppwinrt
The "Type Library" is what enables interop of COM components between different languages.
https://learn.microsoft.com/en-us/windows/desktop/midl/com-dcom-and-type-libraries
A type library (.tlb) is a binary file that stores information about a
COM or DCOM object's properties and methods in a form that is
accessible to other applications at runtime. Using a type library, an
application or browser can determine which interfaces an object
supports, and invoke an object's interface methods. This can occur
even if the object and client applications were written in different
programming languages. The COM/DCOM run-time environment can also use
a type library to provide automatic cross-apartment, cross-process,
and cross-machine marshaling for interfaces described in type
libraries.
The other approach for language interop (e.g. C++ projecting objects to Javascript) is that a COM object can implement IDispatch.
It’s not magic, of course.
COM sets up rules for language interop. It’s just a contract, with some helpful tooling. Each language that wants to support COM has to find a way to abide by the rules on its own. They all have to provide their own compatible mechanism one way or another.
In the case of C++, the rules appear to come for free as you mentioned, but be aware there is one caveat: the language standard does not specify the layout and mechanism of classes and virtual functions. The method mimicked by COM is one extremely common implementation of virtual calling (“the VTable”), and COM follows the exact layout used by the Microsoft compiler. But you can have a perfectly valid C++ compiler where classes with virtual functions would not be compatible with the COM layout. It’s just that nobody does that, at least not in Windows compilers. So even in C++ there is some “meeting in the middle” by the compiler.
In C, you have to do the whole thing by hand. Other languages might allow you to do the same thing (assembler of course).
To help compiled languages exchange information about specific contracts, COM provides Type Libraries and mechanisms to read them. A compiler or language that want to take advantage of them also has to “meet in the middle” and learn how to process them (for example, the Microsoft C++ #import directive; the VB6 Libraries menu).
No every language will support everything you can do in COM, because there is a point (in more obscure features) where the return on investment in implementing support in the language doesn’t pan out. Each language has to pick its own limitations. There is plenty of stuff that you can do in COM (read the IDL specs) that VB6 cannot do.
Because following COM rules in a script-like language is between inpractical and impossible, COM offers a higher-level approach (Automation) that is more amenable to dynamic languages, even if more limited. But a language implementer that wants to provide client support for Automation has to implement an understanding of the IDispatch interface, an activation mechanism, and a translation to its language’s proper facilities. And a scripting language wanting to provide support for creating COM servers has to work even harder to implement a valid COM IDispatch implementation and a standalone host engine on behalf of the user scripts. Even VBScript couldn’t do this at the beginning, until Microsoft added .SCR support with the Windows Scripting Host. “Meeting in the middle” again.
If a language wants to support both pure COM and Automation, they need to work double hard; support for one does not automatically give you support for the other.
For .NET languages like C#, most of the work is done for both native COM and Automation inside of the .NET Runtime, which provides the implementation of the COM Callable Wrappers (CCW) and Runtime Callable Wrappers (RCW) necessary to interact with COM, and handling the conflicts between the Reference Count approach of COM and the GC approach of .NET. Microsoft did all the work in one place so individual .NET language designers didn’t have to.
So, yes, the language implementer has to work extra to give the language special support for COM: following the binary layout rules, implementing a translation layer when needed, and/or possibly providing tooling to read Type Libraries.
Language Interop requires both sides (the caller and the callee) to “meet in the middle” somewhere. COM is just a specification that gives designers that middle ground, “a place where all can meet”.
I know I can read the CLSID from a COM class object in the registry from Classes\<CLASSNAME>\CLSID\#.
I suspect on a registered COM interface I can read up the IID from Classes\<CLASSNAME>\IID\# or Classes\CLSID\<CLSID>\IID.
I've read the article COM IDs & Registry keys in a nutshell and this question is still open to me. Unfortunately, I have no test case right now.
The registry was not meant to be a programming resource, registry entries are only there when the COM infrastructure needs them. The CLSID key for example is necessary to help COM find the executable file that implements a server, the programmer has to supply the CLSID guid.
He needs to know the IID as well, passes it to QueryInterface() to obtain the interface pointer. There might be an entry in HKLM\Software\Classes\Interface but it isn't terribly common. The COM infrastructure needs it when an interface needs to be marshaled from one apartment to another, the registry key contains the CLSID of the proxy that helps to get that job done. A quick look with Regedit.exe in that key ought to convince you that it isn't likely to be helpful at all, there is no connection whatsoever with the server itself. Only if you are very lucky might you find a Type library LIBID there.
There are two basic ways that the COM programmer supplies you with CLSID and IID values. The unfriendly way is an .idl or .h file, several Windows components (DirectX, Media Foundation, WASAPI, etc) are like that. Good enough to see the IIDs back.
The friendly way is a type library, a language-independent description of the implemented coclasses and interfaces that just about any compiler knows how to read. Sometimes supplied as separate .tlb or .olb file but usually embedded as a resource in the executable file. Best way to have a look at it is with the Oleview.exe SDK utility. Use File > View Typelib and select the .tlb or .dll file. It decompiles the type library back into IDL, the language that a COM author uses to describe his component. You'll have no trouble finding the IIDs back. Only thing you have to know is the name of the executable file.
Be sure to take advantage of the type library in your compiler, assuming you found one. You can now use friendly names instead of raw GUIDs, get syntax checking on your code and rarely have to do anything dramatic when the version changes and the author properly used new IIDs. Be sure to talk to the author if you can't find one, a small hint can save you an enormous amount of trouble.
I would like to know the exact differences between API and DLL.
Thank you.
Pretty much the only connection between the two terms is that if you do native Windows programming, APIs you use or write will usually manifest as DLL files. But neither is this the only concrete form an API can take, nor does every DLL represent an API.
API means "Application Programming Interface" - it's an abstract term for a collection of code entities (functions, classes, etc. - depends on the programming language) that's intended to be used by programmers at large to access the functionality of an application or library.
A DLL is a file format on Windows that contains executable code as a way to modularize applications.
An application programming interface (API) is an interface implemented by a software program that enables it to interact with other software. It facilitates interaction between different software programs similar to the way the user interface facilitates interaction between humans and computers. - Wikipedia
A Dynamic Link Library (DLL) is a one way of providing an API. (Interface to the programmer) You may have various other methods, like Web services.
A DLL is a library of code, and API is an interface to a library of code.
DLL = Dynamic-link library
API = Application programming interface
A DLL is just a file on Windows systems that has some code in that can be used by other executable files. An API is a way of using one piece of software, or a software library, to be used with another. For example there is a Windows Registry API that allows you to use the registry, but the code that runs when you use the API is stored in a DLL.
Updates:
DLL (Dynamic Link Library) is a code component (some what like the Beans in Java). DLLs contains the methods or functions or routines or whatever you call those code fragments.
And an API is an interface between an application and that DLL. Most of the time DLLs are used to provide services to other applications, these DLLs are called Server DLLs and if a DLL is requesting some service by using the API call or its dynamic invocation then it is said to be the Client DLL. So simple think, APIs are nothing but the methods or functions which are accessible from outside of that DLL.
Hope you got the idea now.
API are the header files (.h) which contain function and class declarations (input and output parameters), the implementation of these declaration i.e definitions of class or functions will be in particular dlls.
But to connect (dynamic linking) both these .h and .dll files, you require .lib files, these files will resolve the address of function definition during run-time and that particular dll files are loaded. Hence, libraries contain (APIs(.h), lib and dll files).
APIs make application development independent of underlying library implementations.
Example:
if you write a program in C to print "Hello World". And if you run the
same program in windows and Linux.
Both these executable will use different system libraries to display it on screen, as C language provides set of APIs like "STDIO.h","STDLIB.h", You need not worry about the underlying library implementations.
So you can think, API as header files, which connect function/class declarations with function/class definitions. Hence, the name "Application program interface".
You will have to be specific. DLL can stand for:
Data Link Layer,
Dynamic Link Library (Shared library on Windows Platform). It can also be a resource library too.
An API (Application Programming Interface) is an interface that's implemented by software programs to interact with other sotware. E.g. JDBC api is needed if a database connection is required in java.
From Wikipedia:
An API is implemented by applications,
libraries, and operating systems to
determine their vocabularies and
calling conventions, and is used to
access their services.
The purpose of a DLL (Dynamic libraries almost always offer some form of sharing, allowing the same library to be used by multiple programs at the same time).
In essence, the WINAPI (Windows API) are all implemented in DLL files, such as mmsystem.dll for MMSYSTEM Sound API.
References:
API
DLL
An API is an interface for communication of different components of an application, where dll is a library file which contains code so that your program can use using your API
Every DLL has some (is an?) interface (API) because otherwise it would be useless, but not every API is a DLL as in example You can have Web Api where You are using remote endpoints using in example HTTP protocol - not even a file like in DLL case
A simplified answer.
API is always (by definition) an application programming interface. It's a collection of methods that can be used as an interface to an app, a web service, etc.
DLL is a shared library file of the same format as executable. It contains code and data to be shared between other EXEs so you don't have to recompile them every time a DLL is updated. DLLs, for example, allow you upgrade Windows versions and keep the applications running on the latest version. It may contain code that's reusable by one or more executables, like an API. One the other hand, it may contain only data, like icons (.icl) and fonts (.fon).
Which WinAPI method or interface I can use to enumerate the interfaces, properties, methods(and parameters) of a COM Object programmatically?
You need to be more specific. There are two ways to interpret your question.
One is that you have a COM component (e.g. some library), and you want to programmatically enumerate interfaces/properties/methods of that. Usually (but not always), COM components come with a type library that contains full metainformation about all this - it's either embedded into the COM .exe or .dll, or is a separate .tlb file. In any case, if the COM component is properly registered in the system (e.g. using regsvr32), then COM provides a standard API to retrieve that type information, centered around ITypeLib and ITypeInfo interfaces.
Another interpretation is that you get a reference to a particular COM object, and you need to enumerate all methods/properties on that and/or invoke them by computed name, like Java or C# reflection, or Delphi RTTI. If so, then it is only possible if the COM object implements IDispatch interface, which allows you to do all of the above.
Well, COM objects are referenced through interfaces, which are opaque abstractions by design. You can't get at the underlying object without some black magic that will only work if you have a really good knowledge of the low-level details of the Delphi object model and the object was actually written in Delphi.
About the best you can do is examine the interface declaration itself, which will give you all the available information in its methods and properties.
I assume you want a list of all interfaces that will successfully QueryInterface. The answer is there's no intrinsic way in COM to do this. Some interfaces themselves provide this functionality like IServiceProvider.
You can get at everything you want from the registry, however this will take some time as the information is not ordered in such a way to give you the information you want without first analyzing most of it. If you download the utility OLEVIEW32 from the Microsoft platform SDK (available on MSDN) you can use it to explore the COM interfaces registered on the machine.
The fundamentals of COM work through the interfaces registered in the registry, under the HKEY CLASSES ROOT\CLSID. When you ask for a specific com object, it resolves to one of these guids, which in turn looks at the InprocServer32 section under this guid to determine what DLL/EXE to load, and what threading model to use. You could use this information to build a map of guids which also resolve to the same DLL (this is to get the classes)
In HKEY CLASSES ROOT\Interface is a link to all of the interfaces registered in the system. Again, its time to play lookup since much of this information is just pointers to another key, or type library. What IS here however and is useful is a list of GUID -> InterfaceName (default property of each guid).
In HKEY CLASSES ROOT\TypeLib is a link to all of the type libraries registered in the system.