I've been given the task of trying to recreate a DLL that has slight modifications to the original DLL, which will be executed if another program runs. Basically a mocked up version of the DLL for testing/simulating other parts of a larger system.
I've searching to see if there is any method to check if the library is COM or DCOM but have not found any. I am aware of the differences, but given a DLL library, how can I tell if it is a COM or DCOM library?
Additionally, is there any way to swap out a COM/DCOM library with a newer technology but not change parts of the code that call the COM/DCOM library?
Having the executable code alone you cannot tell which it is except that if there're proxy/stub dll shipped with it you can assume it is DCOM.
The visible differences are in how the thing is registered. Digging into registration process can be easy or not so easy depending on how registration is implemented. If registration parameters are hand-glued inside code you'd have to reverse-engineer it the harder way. If registration uses a .rgs file which is stored in resources you can just extract it and see how registration is done. Anyway your best bet is to use a VM and export its registry, then register the component, export the registry again and see the difference - what was added.
Wow, you are going old school here!
If I remember correctly any valid COM object is can also participate in DCOM. Isn't the wiring for the remote procedure calls done at the operating system level?
From https://msdn.microsoft.com/en-us/library/aa295360(v=vs.60).aspx:
Once COM was adapted to work across a network, then any interface that
was not tied to a local execution model (some interfaces have inherent
reliance on local machine facilities, such as those drawing interfaces
whose methods have handles to device contexts as parameters) would
have the capability of being distributed: An interface consumer would
make a request for a given interface; that interface may be provided
by an instance of an object running (or to be run) on a different
machine. The distribution mechanism inside COM would connect the
consumer to the provider in such a way that method calls made by the
consumer would appear at the provider end, where they would be
executed. Any return values would then be sent back to the consumer.
To all intents and purposes, the act of distribution is transparent to
both the consumer and the provider.
Such a variety of COM does now exist. DCOM (for ‘distributed COM’), is
shipped with versions of Windows NT beginning with version 4.0. Since
late 1996, it has also been available for Windows 95 and its
derivatives. In both cases, DCOM comprises a set of replacement and
additional DLLs, with some utilities, which provide both local and
remote COM capabilities. It is therefore now an inherent part of
Win32-based platforms, and will be made available on other platforms
by other organizations over time.
Related
I intend to add a COM interface to an existing application (which, by the way, is written in C++ using Win32). I have some experience using COM objects, so I know the basic COM concepts of interfaces, etc., but this is the first time I'm actually implementing a component.
Ultimately I want to be able to use the COM interface to automate my application from scripts such as VB. I understand that there are two steps:
My application must act as an out-of-process server (i.e. I have to use MIDL and generate code for a proxy DLL and a stub DLL).
Once I have the server I can add automation capabilities by implementing the IDispatch interface.
Since the server-in-an-EXE thing with MIDL and what not is already a bit steep, I wanted to get a grasp on all that first before moving on to IDispatch.
I am reading the book "Inside COM" by Dale Rogerson and have completed the chapter on servers in EXEs (the following chapter will cover Automation).
The "Servers in EXEs" chapter provides example code that implements a server and a client. But it is necessary to start the server manually. This confuses me. Obviously, when my application (= server) is used by a client process, this extra manual step should not be necessary. Is there no mechanism to start the server automatically? Or is automation necessary to achieve that? At the moment, the prospect of having to start my server manually (once I even have one) makes me doubt I am moving in the right direction.
Hopefully someone with more knowledge of this can see what information I'm missing and point me in the right direction.
No, COM servers are not normally started by hand. Not sure why the book proposed it, possibly because it wanted to avoid talking about the registry keys you need to allow COM to automatically start the EXE. It isn't otherwise very complicated, you register the Application coclass of your app with the LocalServer32 key value giving the path to the EXE.
It is however not completely uncommon, especially with an existing program. One design decision to make is whether you let the client code completely control your program. Or if your program already has an existing user interface but you also want to expose services to other code. In the latter case it makes sense to let the user start the app by hand, like she'd normally does.
When your application is registered as LocalServer32, it will be invoked with the commandline specified there if no running process has registered a factory object for your CLSID yet.
This way, you can get the best of both worlds -- if the application is running already, this instance can provide the server side, and if it isn't, it will be started.
Automation is completely orthogonal to that -- your component becomes Automation compatible by implementing IDispatch.
It's hard to explain our situaction.
We have a 3-tier application. The engine is a DLL coded in C++, then we have a VB6 ActiveX EXE that access to the engine via API calls, and at the top level we have a Excel Addin (in C# using VSTO framework) calling the middle layer with an interop DLL. At this time, each "connection" from the Addin to the engine creates a new EXE (VB6 uses API calls to access to the engine) and all works fine.
Now we are moving the middle layer to .NET, it works 'presumably' fine (it pass all our Unit test) but, we found an error when we open 2 "connections" at same time (ups, no unit test check this situation because it's a new behavour). The DLL have static objects that it's shared over all instances in the same process and we have interactions between "connections". In our old version each "connection" creates a new EXE with no memory sharing between processes, now it's the same process and they share memory and the static objects.
Following the tips from this question. We tried to build a COM EXE in C# to do an out-of-process objects in the middle layer but we have the same result. They share the static objects, at the end, each connection not creates a independent process.
It's clear, but not affordable at this time, moving API calls to ATL or changing the static objects to instanciable references with a handle and change all the API calls to get/set this handlers. I reviewed all examples in MS All-in-one but I didn't find any solution. Neither it's possible to keep only one connection at time, each workbook can have one connection and in the future we want to explore a Web application with multiple connections at same time.
Any suggestion?
Thanks in advance,
Whether COM starts new EXE per each COM object, or uses single EXE to instantiate all the object is controlled by flags parameters passed to CoRegisterClassObject. See
http://msdn.microsoft.com/en-us/library/ms693407(v=vs.85).aspx, and
http://msdn.microsoft.com/en-us/library/ms679697(v=vs.85).aspx
You need to pass REGCLS_SINGLEUSE or REGCLS_MULTI_SEPARATE flags.
Now, the trick is to pass this flag, as you might not call this method directly - the details depend on how you implemented the COM EXE.
it's not clear from the question, but it sounds like the "middle layer" you have was built as a VB6 EXE, and you're trying to replace it with a .net DLL. If that's the case, you'll definitely get the behavior you describe.
With a VB6 EXE com project, instantiating a new object starts a new process. With a .net dll (or a Vb6 dll really) you +won't+ get a new process.
You'd either need to create a .net EXE that exposes COM objects just like your VB6 exe does, or (sounds like you've already investigated this) you'll need to refactor your EXE objects to properly handle multiple instances within a single process.
Honestly, it'd probably be better to do that latter, since relying on singletons like this is generally a bad code smell. But it a pinch, you should be able to replicate the behavior of the VB6 exe with a .net project. You just can't do it in a dll.
Was your middle layer created in .Net? If it was, you might be facing the issue that your COM class is been created as a native .net object instead of a COM object. The solution usually involve using Primary Interop Assemblies. Take a look on this SO question to see if it matches your problem.
Through COM, one can potentially gain absolute control over a target system. For example: using javascript's ActiveXObject object in IE, one can create certain objects which were designed to have direct access or interaction with system properties and files. One would think common sense dictates users disable ActiveX features in IE immediately after installing the browser to ensure their system is protected while surfing the net, or at least paying close attention to which websites they permit. But, I doubt many average PC users know how or why to do this, or just get tired of mirco-managing it over time. I think any PC user or admin my COM class caters to would greatly appreciate not having to deal with that. Thankfully it looks like IE versions come packaged with ActiveX disabled by default nowadays.
I've built a very versatile COM class library in VB. I didn't intend for it to be callable from any website, but that feature is just part of the COM platform. I'd like to prevent the library from being called from IE unless the website is on a white-listed domain to proactively protect the user (and ultimately their entire intranet) from harm from malicious websites. What would be the best method in VB.Net to tell which application called my DLL, to be able to tell if it was called from any command or process originating from IE? And, what domain called my dll?
Edit: I believe this might be a duplicate. See: Calling Assembly to get Application Name VB.NET
System.Environment.GetCommandLineArgs()(0) gets me the calling application path. With this info, I can compare it to a black/white-list of applications. Problem solved for now.
Don't mark the control as Safe for Scripting.
Default security settings will not allow such controls to be scripted.
Self-answer, and possibly duplicate, I suppose. See System.Environment.GetCommandLineArgs()(0) from Calling Assembly to get Application Name VB.NET
In this case, the class never was marked as safe for scripting and the intent was already never to mark it safe. The issue was how to obtain the calling application info so I could add additional security measures in case those which the calling application had were not enough.
I need to write a stub module which, when given a PE (DLL/EXE) as input, will determine whether it is a normal Win32 DLL/EXE or COM DLL/EXE. I need to determine this programatically.
Are there any Windows APIs for this purpose?
I suspect that this is something that would be very hard to do with near 100% accuracy. Some thoughts though:
A COM DLL will export functions like DllRegisterServer and DllUnregisterServer. You could use LoadLibrary() to load the Dll, and then GetProcAddress() to check for the presence of these functions. If they're there then its highly likely that its a COM dll.
A plain win32 Dll will export DllMain. You could use the same technique to check for that. If you find it then its very likely that its win32.
I'm not aware of a way to discover if an exe is a COM server. Servers written using ATL often have a registration script embedded in their resource table, but they don't have to. And you don't need to use ATL to write a COM server. Services using "registry-less com" will similarly have an embedded manifest. You could scan the registry (below HKLM/Classes/Software/) to see if the exe is registered, but it may be that the exe is using registry-less com or just hasn't been regisered yet.
Hope that helps.
For traditional COM DLL, you can look for the wellknown exported methods (search on msdn for these methods)
DllGetClassObject
DllRegisterServer
DllUnregisterServer
DllCanUnloadNow
I am not sure about EXE COM servers though because they generally use command line parameters for registration/unregistration and for class object usually calls CoRegisterClassObject when the EXE starts.
Most of the COM servers traditionally also registered in the Registry but you can create registration free servers now.
Are you also looking for a .NET assembly with some COM visible classes?
Windows still use DLLs and Mac programs seem to not use DLL at all. Are there benefits or disadvantages of using either technique?
If a program installation includes all the DLL it requires so that it will work 100% well, will it be the same as statically linking all the libraries?
MacOS X, like other flavours of Unix, use shared libraries, which are just another form of DLL.
And yes both are advantageous as the DLL or shared library code can be shared between multiple processes. It does this by the OS loading the DLL or shared library and mapping it into the virtual address space of the processes that use it.
On Windows, you have to use dynamically-loaded libraries because GDI and USER libraries are avaliable as a DLL only. You can't link either of those in or talk to them using a protocol that doesn't involve dynamic loading.
On other OSes, you want to use dynamic loading anyway for complex apps, otherwise your binary would bloat for no good reason, and it increases the probably that your app would be incompatible with the system in the long run (However, in short run static linking can somewhat shield you from tiny breaking changes in libraries). And you can't link in proprietary libraries on OSes which rely on them.
Windows still use DLLs and Mac
programs seem to not use DLL at all.
Are they benefits or disadvantages of
using either technique?
Any kind of modularization is good since it makes updating the software easier, i.e. you do not have to update the whole program binary if a bug is fixed in the program. If the bug appears in some dll, only the dll needs to be updated.
The only downside with it imo, is that you introduce another complexity into the development of the program, e.g. if a dll is a c or c++ dll, different calling conventions etc.
If a program installation includes all
the DLL it requires, will it be the
same as statically linking all the
libraries?
More or less yes. Depends on if you are calling functions in a dll which you assume static linkage with. The dll could just as well be a "free standing" dynamic library, that you only can access via LoadLibrary() and GetProcAddress() etc.
One big advantage of shared libraries (DLLs on Windows or .so on Unix) is that you can rebuild the library and its consumers separately while with static libraries you have to rebuild the library and then relink all the consumers which is very slow on Unix systems and not very fast on Windows.
MacOS software uses "dll's" as well, they are just named differently (shared libraries).
Dll's make sense if you have code you want to reuse in different components of your software. Mostly this makes sense in big software projects.
Static linking makes sense for small single-component applications, when there is no need for code reuse. It simplifies distribution since your component has no external dependencies.
Besides memory/disk space usage, another important advantage of using shared libraries is that updates to the library will be automatically picked up by all programs on the system which use the library.
When there was a security vulnerability in the InfoZIP ZIP libraries, an update to the DLL/.so automatically made all software safe which used these. Software that was linked statically had to be recompiled.
Windows still use DLLs and Mac programs seem to not use DLL at all. Are they benefits or disadvantages of using either technique?
Both use shared libraries, they just use a different name.
If a program installation includes all the DLL it requires so that it will work 100% well, will it be the same as statically linking all the libraries?
Somewhat. When you statically link libraries to a program, you will get a single, very big file, with DLLs, you will have many files.
The statically linked file won't need the "resolve shared libraries" step (which happens while the program loads). A long time ago, loading a static program meant that the whole program was first loaded into RAM and then, the "resolve shared libraries" step happened. Today, only the parts of the program, which are actually executed, are loaded on demand. So with a static program, you don't need to resolve the DLLs. With DLLs, you don't need to load them all at once. So performance wise, they should be on par.
Which leaves the "DLL Hell". Many programs on Windows bring all DLLs they need and they write them into the Windows directory. The net effect is that the last installed programs works and everything else might be broken. But there is a simple workaround: Install the DLLs into the same directory as the EXE. Windows will search the current directory first and then the various Windows paths. This way, you'll waste a bit of disk space but your program will work and, more importantly, you won't break anything else.
One might argue that you shouldn't install DLLs which already exist (with the same version) in the Windows directory but then, you're again vulnerable to some bad app which overwrites the version you need with something that breaks your neck. The drawback is that you must distribute security fixes for your app yourself; you can't rely on Windows Update or similar things to secure your code. This is a tight spot; crackers are making lots of money from security issues and people will not like you when someone steals their banking data because you didn't issue security fixes soon enough.
If you plan to support your application very tightly for many, say, 20 years, installing all DLLs in the program directory is for you. If not, then write code which checks that suitable versions of all DLLs are installed and tell the user about it, so they know why your app suddenly starts to crash.
Yes, see this text :
Dynamic linking has the following
advantages: Saves memory and
reduces swapping. Many processes can
use a single DLL simultaneously,
sharing a single copy of the DLL in
memory. In contrast, Windows must load
a copy of the library code into memory
for each application that is built
with a static link library. Saves
disk space. Many applications can
share a single copy of the DLL on
disk. In contrast, each application
built with a static link library has
the library code linked into its
executable image as a separate
copy. Upgrades to the DLL are
easier. When the functions in a DLL
change, the applications that use them
do not need to be recompiled or
relinked as long as the function
arguments and return values do not
change. In contrast, statically linked
object code requires that the
application be relinked when the
functions change. Provides
after-market support. For example, a
display driver DLL can be modified to
support a display that was not
available when the application was
shipped. Supports multilanguage
programs. Programs written in
different programming languages can
call the same DLL function as long as
the programs follow the function's
calling convention. The programs and
the DLL function must be compatible in
the following ways: the order in which
the function expects its arguments to
be pushed onto the stack, whether the
function or the application is
responsible for cleaning up the stack,
and whether any arguments are passed
in registers. Provides a mechanism
to extend the MFC library classes. You
can derive classes from the existing
MFC classes and place them in an MFC
extension DLL for use by MFC
applications. Eases the creation
of international versions. By placing
resources in a DLL, it is much easier
to create international versions of an
application. You can place the strings
for each language version of your
application in a separate resource DLL
and have the different language
versions load the appropriate
resources. A potential
disadvantage to using DLLs is that the
application is not self-contained; it
depends on the existence of a separate
DLL module.
From my point of view an shared component has some advantages that are somtimes realized as disadvantages.
shared component defines interfaces in your process. So you are forced to decide which components/interfaces are visible outside and which are hidden. This automatically defines which interface has to be stable and which does not have to be stable and can be refactored without affecting any code outside the component..
Memory administration in case of C++ and Windows must be well thought. So normally you should not handle memory outside of an dll that isn't freed in the same dll. If you do so your component may fail if: different runtimes or compiler version are used.
So I think that using shared coponents will help the software to get better organized.