Cannot load specific DLL from System32 or SysWOW64 Topic is solved

Do you have a typical platform dependent issue you're battling with ? Ask it here. Make sure you mention your platform, compiler, and wxWidgets version.
Post Reply
xygblarbin
In need of some credit
In need of some credit
Posts: 2
Joined: Tue Mar 28, 2017 5:06 pm

Cannot load specific DLL from System32 or SysWOW64

Post by xygblarbin »

Hello all,

I'm dealing with a problem getting my application to load a particular DLL that exists in System32 or SysWOW64 when wxWidgets is present.

I'll give a little back story for reference. We have DLLs that are being loaded successfully that are in the executable directory, so loading DLLs in general is not a problem. However, we've recently added a feature that requires a DLL from one of our suppliers. For some reason, that DLL will only work properly from System32 or SysWOW64*. As such, I am now required to get that to work.

* It seems that this affects ONLY this DLL; it will not load properly from the System folders when wx is present. It also seems that this DLL WILL load properly from the executable directory, but does not FUNCTION properly from the executable directory. It should also be noted that the supplier has been of little help, and I'm really hoping someone can shed some light on this.

I have written 3 different small projects:
1) A console application that does not use wxWidgets, and uses Windows DLL calls (this will load and execute the DLL just fine)
2) A wxWidgets application that uses wxDynamicLibrary (this will not load the dll)
3) A wxWidgets application that uses Windows DLL calls (this will not load the dll)

The only project that works is #1. I've pasted the relevant code below, but if anyone wants to see the entire projects, I can zip them up and add them. I will also include the DLL.

#1

Code: Select all

static HINSTANCE m_Dll;

bool LoadDll(void)
{
    m_Dll = LoadLibrary("linusb.dll");

    if (!m_Dll)
    {
        cout << "Could not locate dll." << endl;
        return false;
    }

    LinUsbOpen = NULL;
    LinUsbOpen = (TLinUsbOpen)GetProcAddress(m_Dll, "LinUsbOpen");

    if (!LinUsbOpen)
    {
        cout << "Could not locate function LinUsbOpen" << endl;
        return false;
    }

    LinUsbUnload = (TLinUsbUnload)GetProcAddress(m_Dll, "LinUsbUnload");

    if (!LinUsbUnload)
    {
        cout << "Could not locate function LinUsbUnload" << endl;
        return false;
    }

    LinUsbIsOpen = (TLinUsbIsOpen)GetProcAddress(m_Dll, "LinUsbIsOpen");

    if (!LinUsbIsOpen)
    {
        cout << "could not locate function LinUsbIsOpen" << endl;
        return false;
    }

    return true;
}
#2

Code: Select all

// m_LinUSBDLL is a wxDynamicLibrary

/*!
 * \brief Loads the DLL functions from linusb.dll and points them to our
 * local variables.
 *
 * \return
 * True on success, false on fail.
 */
bool TLinUSB::LoadLinUSBDLL( void )
{
    bool SymbolNotFound;
    wxString FileNameStr = _T("linusb.dll");

    if ( !m_LinUSBDLL.Load( FileNameStr ) )
    {
        AppendLog( wxString(_T("Unable to load linusb.dll: "))+
            FileNameStr );

        return false;
    }

    SymbolNotFound =false;

    // Attempt to load symbols from the DLL.
    LOAD_DLL_SYMBOL( _T("LinUsbOpen"), TLinUsbOpen, LinUsbOpen, m_LinUSBDLL,
        SymbolNotFound, FileNameStr );

    LOAD_DLL_SYMBOL( _T("LinUsbUnload"), TLinUsbUnload, LinUsbUnload,
        m_LinUSBDLL, SymbolNotFound, FileNameStr);

    LOAD_DLL_SYMBOL( _T("LinUsbClearBuffers"), TLinUsbClearBuffers,
        LinUsbClearBuffers, m_LinUSBDLL, SymbolNotFound, FileNameStr );

    return !SymbolNotFound;
}

#3

Code: Select all

// m_LinUSBDLL is a HINSTANCE.

/*!
 * \brief Loads the DLL functions from linusb.dll and points them to our
 * local variables.
 *
 * \return
 * True on success, false on fail.
 */
bool TLinUSB::LoadLinUSBDLL( void )
{
    wxString Lib = _T("linusb.dll");

	// Attempt to load the DLL, and output an error on failure.
	m_LinUSBDLL = LoadLibrary((wchar_t *)Lib.wx_str());

    if ( !m_LinUSBDLL )
    {
        AppendLog(_T("Unable to load linusb.dll"));

        return false;
    }


    // Attempt to load symbols from the DLL.

    LinUsbOpen = (TLinUsbOpen)GetProcAddress(m_LinUSBDLL, "LinUsbOpen");

    if (!LinUsbOpen)
    {
        AppendLog(_T("Unable to load LinUsbOpen"));
        return false;
    }

    LinUsbUnload = (TLinUsbUnload)GetProcAddress(m_LinUSBDLL, "LinUsbUnload");

    if (!LinUsbUnload)
    {
        AppendLog(_T("Unable to load LinUsbUnload"));
        return false;
    }

    LinUsbClearBuffers = (TLinUsbClearBuffers)
        GetProcAddress(m_LinUSBDLL, "LinUsbClearBuffers");


    if (!LinUsbClearBuffers)
    {
        AppendLog(_T("Unable to load LinUsbClearBuffers"));
        return false;
    }

    return true;
}
I think from those 3 examples that it shows that somehow wxWidgets is involved, but that since a different arbitrary DLL from the System folders can be loaded, shows that the DLL is also involved. The supplier also provided some code for a different piece of software which is somewhat irrelevant except that it was in Visual Basic, which COULD mean that they wrote this DLL in Visual Basic, using .NET. Not sure if that would be relevant, but adding just in case.

Does anyone have any ideas what could be going on here?
Attachments
linusb.zip
(47.94 KiB) Downloaded 101 times
User avatar
doublemax
Moderator
Moderator
Posts: 19160
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Cannot load specific DLL from System32 or SysWOW64

Post by doublemax »

As i don't know if i find time to test this myself:

Are all test executables and DLLs involved 32bit? If not, which ones are 64bit?

Use "procmon" or a similar tool to check where the system is looking for the DLL. Maybe it's looking where you don't expect it.

What's the Windows error code after loading the DLL without success?
Use the source, Luke!
PB
Part Of The Furniture
Part Of The Furniture
Posts: 4204
Joined: Sun Jan 03, 2010 5:45 pm

Re: Cannot load specific DLL from System32 or SysWOW64

Post by PB »

In addition to what doublemax said...
xygblarbin wrote:For some reason, that DLL will only work properly from System32 or SysWOW64*.
I would start looking into the reason for this, the DLL should work from the app folder. I noticed that the DLL load-time links to two non-standard DLLs: WDAPI1021 and MSVC9 CRT. Are those two available when your program starts? As doublemax wrote, the return codes from the failed functions may shed some light on what is going on...
xygblarbin
In need of some credit
In need of some credit
Posts: 2
Joined: Tue Mar 28, 2017 5:06 pm

Re: Cannot load specific DLL from System32 or SysWOW64

Post by xygblarbin »

It turns out that the WDAPI1021 dll was the issue. It wasn't in any directory on the path hierarchy. Adding it to the executable directory solved the issue. Thank you for your answers!
Post Reply