Attempting to load a DLL on Windows using LoadLibrary when a dependent DLL is missing - c

I have an application that uses LoadLibrary on Windows to dynamically load plugins. However some of the plugins have other dependent DLLs, such as database client DLLs.
When you attempt to load such a DLL and one of the dependent DLLs doesn't exist you get a nasty Windows dialog:
"The program can't start because xxx.ddl is missing from your computer. Try reinstalling the program to fix this problem."
Is there any easy way to avoid this dialog? I was hoping one could use LoadLibraryEx and pass a flag that says "don't give me that annoying dialog", but it doesn't seem like it.
What I'd like is for the application to handle that error, rather than Windows handling it for me, especially as the text of the message is incorrect (the problem isn't that the program can't start, the program is running quite happily, it just can't load this plugin).
What I'd like to avoid is having to rewrite the plugins that have these external dependencies to make them themselves do a dynamic load of any dependent modules and then query for any entry points.
Anyway, any suggestions would be gratefully received.

Use SetErrorMode(). Use it with SEM_NOOPENFILEERRORBOX | SEM_FAILCRITICALERRORS before you load the DLL and with 0 right after.

From MSDN:
To enable or disable error messages displayed by the loader during DLL loads, use the SetErrorMode function.
Link here

Related

LLDB: Execute a python callback after target create to inject symbols

I'm trying to execute a python function after target create so I can iterate over all modules of the target, download missing symbols from the internet (based on GetUUIDString) and then override the GetSymbolFileSpec() directory and path to what I downloaded.
Unfortunately I cannot figure out how to actually get a function invoked at the right time so that the program did not execute yet, the target is created and lldb.target.modules is populated and lets me modify the symbols.
Is there some documentation on how to hook into this? I am aware that there is a theoretical way to fetch symbols on demand via a shell script however that is only implemented on macos and not other platforms.
You probably don't want to do this on target create since there's no guarantee that a target will know all the libraries that will load into it before it actually runs. And plus, you probably also want to handle libraries that are dynamically loaded as the program runs. The real place to do this is on Module add (which is where the hook for DebugSymbols happens in lldb.)
It looks like Linux and Windows don't have the notion of a call-out to some agent to pull in debug symbols. They do look in /usr/local/debug for pre-cached symbols, but there's no mechanism to have a call-out like with dsymForUUID.
If you're up for a little lldb hacking, it would be pretty straightforward to add such a callout. Just make a setting that takes the name of a program. That program would takes as input a UUID, and returns as output the file name for the debug info. Then you could have lldb run this in the same place where lldb currently calls LocateMacOSXFilesUsingDebugSymbols (in LocateSymbols.cpp).
Perhaps a simpler way to do this would be to add a target stop-hook that calls some python based command you've written that looks at the module list and fetches debug information for any new libraries that have shown up. If you want to use this for debugging running programs, you only care that the symbols get added before control returns to the user. So a stop hook would be an appropriate place to do this.

why windows installer doesn't use my EmbeddedUIHandler when it is dependent to other DLLs?

I'm trying to handle all of User Interfaces (UI) dialogs in .msi installing pakage, with EmbeddedUIHandler to do this I have created a setupui.dll which contains three methods: InitializeEmbeddedUI, ShutdownEmbeddedUI, EmbeddedUIHandler, and put it inside of MsiEmbeddedUI table (using installshield) and it worked just fine.
The problem is when setupui.dll is dependent to other external DLLs, this time windows installer won't use my dll and it uses default ui, I have added other DLL dependencies with Installshield as follow:
I'm uncertain of what Windows Installer allows here. There are, however, three things that jump out at me as things to look into:
The MsiEmbeddedUI table's Attributes column should probably have a 3 for SetupUI.dll (as it does), and 0 for the rest. Per the docs, the 2 bit is ignored if the 1 bit isn't present, but all the other files are better described as "It may be a resource used by the user interface."
The verbose log: does it indicate what's going on? Does it show a failure loading SetupUI.dll that provides a useful error code (hint: file not found probably refers to a dependency)? Does it indicate it didn't even try to load your DLL? Look for lines with EEUI, at least in the successful case.
If Windows Installer does attempt to load SetupUI.dll, how far does it get? If it gets far enough for you to run some code and, say, show a message box, what files are already extracted at that point? If the dependencies are extracted, can you ensure that its directory is on the DLL path via SetDllDirectory or AddDllDirectory? If the dependencies are not extracted, are they present at a later point so approches like delay loading could help?
For the third point, Process Monitor may help you diagnose what's going on if you can't get a message box in there, but it will probably be less clear. Alternately, using Loader Snaps and Debug View might get you a related set of information, but it may be drowned in additional noise.

Add non .NET DLL to ColdFusion

I am currently faced with a dilemma in regards to adding any kind of DLL to a ColdFusion project. I have done a ton of research but nothing seems to be simplistic enough to grasp an understanding. I have a Winform that uses the same DLL in the Reference which makes life easy. When looking to add the same DLLs to a ColdFusion project, it doesn't seem to be working. I have tried using the following:
<cfobject type="com" name="myObj" assembly="C:\DocViewer\AxInterop.SHDocVw.dll">
Here is the error message I am receiving as well:
Attribute validation error for tag CFOBJECT. It has an invalid
attribute combination: assembly,name,type.
This site has been very helpful in the past and I am hoping to learn how this DLL in CF9 works so that I do not have to completely rewrite an entire program when the current one works perfectly.
From comments
I tried adding the DLL using the regsvr32 but here is my error now:
the module was loaded but the entry-point dllregisterserver was not found
Well it looks to me like you're using the cfobject attributes for a .NET object instead of for a COM object. The cfobject tag is one of those tags where the attributes vary by action/type, like cfcontent, cffile and cfdirectory (and a bunch of others that don't immediately spring to mind).
So you need the documentation for accessing COM objects specifically, which for the latest version of Adobe's CFML engine is located here: https://wikidocs.adobe.com/wiki/display/coldfusionen/cfobject%3A+COM+object
There's a typo on the docs page, but it looks like this should work for you (although I'll admit it's been a while since I've invoked a COM object):
<cfobject
type = "com"
class = "path.to.com.Class"
name = "myObj"
action = "create|connect">
It looks like you would use action="connect" if you have it installed as a Windows Service, or create if you want CF to instantiate the DLL, but I would guess having it installed as a service would be easier. I'm just guessing, but I think "path.to.com.Class" would be the name of the service if you're using it that way, or it would be the logical path to the .dll file if the CF server is instantiating it. If neither of those options work, then there might either be a version incompatibility if this is being moved to a newer OS, or the service might be misconfigured.
The error message from registering the DLL sounds like (and I'm guessing because I've never created a windows service DLL) it's looking for a specific class or function in the DLL in order to register it as a service in Windows and it can't find that "entry point" in the DLL (i.e. in the same way that Java will look for a "public static void Main(String args)" as the entry-point to a Java program). That may be necessary for a Service, but it's probably not necessary for a generic DLL that might be accessed and used in some other way, so it's possible this DLL might work, but not be compatible with Service registration.
So going back to your sample code, this might work:
<cfobject type="com" name="myObj" action="create"
class="C:\DocViewer\AxInterop.SHDocVw.dll">

WPF application shows managed has exited with code -1073740771 (0xc000041d) in InitializeComponent call

When I launch my WPF application and when it goes to InitializeComponent function call of one user control, it silently quits and only leaves one message in the output window saying Managed (v4.0.30319)' has exited with code -1073740771 (0xc000041d). When I say "silently", I mean there is no exception is caught even if I wrap this InitializeComponent call with a try-catch block (that's how I normally find where the problem is)
Here is what I did: in this application project we need to use a reference Microsoft.Office.Interop.Owc.dll, with version number 10.0.4504.0. Since it is an interop library, when I added this reference in VS2012, it automatically sets the property Embedded Interop Types as true, which I assume means it will not keep an individual dll in the output folder but instead embed this library into the main output (at least this is how it seems in our other references, for example, Microsoft.Office.Interop.Outlook.dll). However, when I launch the project, it throws an XamlParseException saying:
"Could not load file or assembly 'Microsoft.Office.Interop.Owc, Version=10.0.4504.0,
Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The system
cannot find the file specified.":"Microsoft.Office.Interop.Owc, Version=10.0.4504.0,
Culture=neutral, PublicKeyToken=31bf3856ad364e35""
It seems that the reference was not embedded(or the version is not currect. But I verified that the reference version is indeed 10.0.4504.0)
Next I copied this dll directly to the output folder bin\Debug\, to make sure that it can find this library. This time the exception is not thrown, but the whole application just silently quits as I described in the beginning. I tried to google the code -1073740771 (0xc000041d) but there is no article about it. I tried to set the Embedded Interop Types to true/false but the problem is the same.
UPDATE:
I'd like to add more description here. As mentioned above, the problematic library is OWC(Office Web Component)10. I followed this link to make OWC work with VB.NET desktop application: HOW TO: Handle Events for the Office Web Components in Visual Studio .NET. But this official article is so old so I had to make a lot of changes to compile the wrapper dll(mainly because of namespace mismatch). Then when I add the reference to the actual interop library Microsoft.Office.Interop.Owc, if I follow the default setting and let the Embedded Interop Types as True, at runtime it will complain (throw a XamlParseException) that the assembly cannot be loaded (see description above). What the hell? I thought make it as "embedded" would guarantee this library will be found. Then I copy this dll to the output folder, then I have this silently quit problem. But it might be worth mentioning that this time the output window shows the Microsoft.Office.Interop.Owc.dll is indeed loaded. Actually it is the last message before the managed has exited message. So it must still relate to this library.
All of this only happens with OWC10. There is actually a similar way to do that in OWC11(the latest, but unfortunately still pretty old version since it came with Office2003): HOW TO: Handle Events for the Office 2003 Web Components in Visual Studio .NET. But it actually works and the control is displayed on my application. It is because of some other reason that I wanted to try OWC10 instead of OWC11
When I launch my WPF application and when it goes to InitializeComponent function call of one user >control, it silently quits and only leaves one message in the output window saying Managed
(v4.0.30319)' has exited with code -1073740771 (0xc000041d). When I say "silently", I mean there is >no exception is caught even if I wrap this InitializeComponent call with a try-catch block (that's >how I normally find where the problem is)
Next I copied this dll directly to the output folder bin\Debug\, to make sure that it can find this >library. This time the exception is not thrown, but the whole application just silently quits as I >described in the beginning. I tried to google the code -1073740771 (0xc000041d) but there is no >article about it. I tried to set the Embedded Interop Types to true/false but the problem is the >same.
I had exactly the same thing happening to me today, "has exited with code -1073740771 (0xc000041d)." (This happened in both a VB and C# .NET WinForms application for me). I tried debugging and saw I never even got into the Form_Load code block.
I "solved" this in the end by running visual studio as an administrator (and then just opening & building and running the project via the menu).
This is a win8 security issue and it isn't well explained anywhere.
(I got distracted and just opened up a specific project straight out of my task bar/solution file which caused this to happen to me).
You've probably found this out by yourself by now, hope you didn't lose any hair over it :)
Just pointing this out for other people who might have this error occuring somewhere.
Also had this issue, the 'silent' exit with code -1073740771 (0xc000041d) on x64 platforms, on x86 platforms everything was OK.
Part of my application is unmanaged C++, another part is C#. It turned out that my C++ code was not completely ready for the x64 platform. The following change fixed the issue in my case:
// before
g_OrigWndProc = reinterpret_cast<WNDPROC>(::SetWindowLongPtr(hWnd, GWLP_WNDPROC,
reinterpret_cast<LONG>(WindowProc)));
// fixed version
g_OrigWndProc = reinterpret_cast<WNDPROC>(::SetWindowLongPtr(hWnd, GWLP_WNDPROC,
reinterpret_cast<LONG_PTR>(WindowProc)));
So, the generic recommendation is to verify that your code is completely ready for the x64 platform.

Obfuscate Silverlight library using Dotfuscator

I'm attempting to use Dotfuscator 4.7.1000 to obfuscate a Silverlight library that is strongly named. When I attempt to do so, I get the following error message:
External type not found
System.Data.Services.Client.LoadCompletedEventArgs,System.Data.Services.Client,
Version=2.0.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35.
I have tried adding this assembly to the GAC, and have tried adding user defined assembly load paths to the configuration to locations where this assembly is located to no avail.
I then tried adding System.Data.Services.Client to the input assemblies and ran it again. This time it gets further, but ultimately I get:
Warning: Password protected Strong Name files are not supported
sn returned 1.
It appears as though it is attempting to run sn.exe on System.Data.Services.Client.dll with my local key. I've tried excluding this assembly from any obfuscation tasks, but it continues to do so.
Is there something I'm missing when trying to obfuscate this library? Is there some other way to directly point it to the DLL it can't seem to find that I don't know about? Or can I include the DLL in the project without it trying to obfuscate the Silverlight library?
And for the moment, please no suggestions on alternate obfuscators. My company has a license for Dotfuscator and I'd like to get this running using that. Thanks!
Somehow I must have been screwing up my user defined assembly load paths. As soon as I re-added the path to the Silverlight 4.0 client DLLs everything worked without having to reference System.Data.Services.Client.

Resources