Can I use LoadLibrary inside my Win32 DLL? - c++

I have a device DLL Library "Device.DLL", I want to do a mask library of it "Mask.DLL". I only have the device DLL, not .lib.
My code:
// Load library
hLibHandle = LoadLibrary(L"Device.dll");
// GetProcAddress for my function
myDeviceFunc = (lpmyDeviceFunc)GetProcAddress(hLibHandle, "myDeviceFuncName");
// Calling function
myDeviceFunc();
This works very well in a Console Application, but no inside my Win32 DLL. When I run my MyDeviceFuncMask() from my Mask.DLL I get "Application has stopped working".
MyDeviceFuncMask() just do this:
EXPORT_DEFINE int MyDeviceFuncMask() {
// Load library
hLibHandle = LoadLibrary(L"Device.dll");
// GetProcAddress for my function
myDeviceFunc = (lpmyDeviceFunc)GetProcAddress(hLibHandle, "myDeviceFuncName");
// Calling function
int result = myDeviceFunc();
return result;
}
I've exported anothers functions and the DLL works well, for example:
EXPORT_DEFINE int TestFunc() {
return CONST_SUCCESS;
}

It's highly likely that your LoadLibrary call is failing, but there's not enough information here to diagnose it. So here's a list of reasons why LoadLibrary can fail:
It can't find the library. Read the documentation about naming, search order, etc.
The library is for the wrong architecture. For example, a 32-bit process cannot load a 64-bit DLL.
You're trying to load the library from DllMain, which will fail because the loader is holding the loader lock during DllMain to prevent the possibility that DLLs get loaded before the DLLs they depend on.
The DLL's DllMain returns FALSE from the DLL_PROCESS_ATTACH callback.
The DLL tries to do something in its DllMain that it shouldn't be doing (like calling LoadLibrary).
A transitive dependency of the DLL you're trying to load failed to load (for any of the previous reasons). For example, if you try to load foo.dll, and foo.dll is linked against bar.dll, then the loader will first try to load bar.dll, and perhaps that's what's failing.
In addition to outright failure, it's also possible to load the wrong DLL accidentally if the name conflicts with another DLL that's already loaded into the process. If you try to load foo.dll, but another foo.dll is already loaded into the process, you'll just get a fresh handle to the already loaded one. I believe you can load two DLLs with the same name only if you load it with an absolute file path.
If you do end up with a handle to the wrong DLL, that will likely result in the failure of a subsequent GetProcAddress. You can diagnose this quickly in the debugger by putting a breakpoint on your LoadLibrary call and then searching the OutputWindow to see whether another DLL of the same name has already been loaded. (But, really, you should be checking the return values of LoadLibrary and GetProcAddress anyway.)
I've made this a community wiki so others can add reasons why LoadLibrary can fail, and we can direct people here when they post questions about LoadLibrary failures.

Related

C++ COM DLL built in debug cannot be registered when depending on another C++ COM DLL built in release and vice versa

I am attempting to register a Visual C++ COM DLL that I have built with a debug configuration.
This COM DLL depends on another Visual C++ COM DLL that was built with a release configuration.
Both DLLs are being registered with regsvr32 (the release DLL has already been successfully registered).
I am using the 32 bit version of regsvr32 (located in SysWOW64) to register both DLLs (since they are both targeting x86).
The DLLs are compiled with the Visual C++ 2010 compiler (with Service Pack 1 installed).
When I attempt to register the debug DLL, regsvr32 fails with this error message. The blacked out text is just the name of the debug DLL I attempted to register.
The image of the error message has the following text:
RegSvr32
The module "REDACTED" failed to load.
Make sure the binary is stored at the specified path or debug
it to check for problems with the binary or dependent .DLL
files.
A dynamic link library (DLL) initialization routine failed.
I then attempted to debug the code in the debug DLL that gets called by regsvr32 to register it. The debug DLL initializes itself and then attempts to create a COM object from the release DLL that it depends on and call a method on that object.
The method in the release DLL that gets called then immediately calls the method AfxGetApp() to get a pointer to the application. This function returns a null pointer.
The application then attempts to dereference this null pointer and throws an exception.
It is my understanding that this function should not be returning a null pointer in this case.
It doesn't return one when both DLLs are built with a debug configuration or when both are built with a release configuration. It only returns null when the DLLs are built with opposite configurations.
What regsvr32.exe calls into:
BOOL DebugDLLApp::InitInstance()
{
if (CWinApp::InitInstance() == FALSE)
{
return FALSE;
}
ReleaseDLLClass releaseClass;
HINSTANCE hInstDll = releaseClass.LoadResourceDLL();
...
}
What the debug DLL calls into:
BOOL ReleaseDLLClass::LoadResourceDLL()
{
CWinApp* winApp = AfxGetApp(); // Returns null.
LPCSTR exeName = winApp->m_pszExeName; // Null reference exception occurs here.
...
}
So, my question is this:
Is there something inherent in COM that disallows registering DLLs with dependencies that were made with different build configurations?
If not, why would AfxGetApp() return a null pointer in these specific cases?
Thank you for any guidance you have.

cant load dll that contains call to CreateProcessAsUserW

i have a program that loads dlls, all dlls have only one simple c function "run". one dll contains call to CreateProcessAsUserW and when i try to load it, LoadLibrary reports error 127 "ERROR_PROC_NOT_FOUND". when i comment it out, dll loads normally and is callable. i was running dependency walker on this dll and CreateProcessAsUserW is marked red with error:
Error: At least one module has an unresolved import due to a missing export function in an implicitly dependent module.
this problem does not occur when using CreateProcessAsUserA, only when using CreateProcessAsUserW.
my setup:
xp sp3 updated to max
mingw64, gcc 4.9.1
i also have static libs and static runtime turned off
whats the source of my problem? how can i fix this so CreateProcessAsUserW will work?

Dynamic Linking to visa32.dll causes crash

I am trying to communicate with an oscilloscope over USB with NI-VISA 5.1.1. My 32-bit application is written in the Qt framework using C++ and the MinGW compiler (standard Qt 4.7 SDK).
My application has no problems communicating with the device when I statically link to visa32.lib. My dynamically linked code also runs fine on a Windows 7 64-bit platform, but crashes on two different computers running on Windows XP SP3 (32 bit). I have traced the line of code that causes the crash (it is the first call to viWrite).
The issue seems to be related to setup of global variables in the DLL itself. This might explain why it works in Windows 7 since in that case the 32-bit DLL file is only a stub which calls a 64-bit VISA DLL file.
This is how I dynamically link to the exported functions:
typedef long (*tviRead)(ViSession, ViPBuf, ViUInt32, ViPUInt32);
typedef long (*tviWrite)(ViSession, ViBuf, ViUInt32, ViPUInt32);
QLibrary visa32("visa32"); // Qt wrapper for LoadLibrary
if (!visa32.load()) throw "Unable to load visa32.dll";
pviWrite = (tviWrite) visa32.resolve("viWrite");
pviRead = (tviRead) visa32.resolve("viRead");
If I call the following (where the vi prefixed function are statically linked and pvi ones are runtime linked),
status = viOpenDefaultRM(&rm);
status = viFindRsrc(rm, query, &list, &itemCnt, desc);
status = viOpen(rm, desc, VI_NULL, VI_NULL, &vi);
status = pviWrite(vi, (ViByte*) idn, 5, &retCnt); // Crash right here
status = pviRead(vi, (ViByte*) id, sizeof(id), &retCnt);
everything works perfectly. However changing any of the three setup function to runtime linked causes a segmentation fault when calling pviWrite. There aren't AFAIK any other functions exported by the DLL to "setup global variables", in fact I can't see DllMain exported using the Dependency Walker tool. Has anyone ever runtime linked to visa32.dll successfully? I can't find any examples on the Internet.
I suspect you have the following problem:
http://msdn.microsoft.com/en-us/library/ms684179(v=vs.85).aspx
Scroll down to the remarks section, and look for "Visual C++": if the DLL contains _declspec-style thread local storage you can only load it dynamically in Vista or later.
I'm trying to achieve the same thing but apparently, for XP, we are simply out of luck...

VS2008 debugger and kernel32.dll

I've been just debugging a process (in C++/windows) which uses "GetThreadContext" which is in kernel32.dll.
I noticed that I could get it's address with
unsigned long address = (unsigned long)(&GetThreadContext);
but when I looked at the loaded modules tab - I saw that the symbols for kernel32.dll were not loaded!
How did the VS2008 know the address of "GetThreadContext"?
And how can I do it myself without having the PDBs?
thanks :)
This works for the same reason that
GetThreadContext(hThread, lpContext);
works. Named functions used in your code must be resolved at link-time, or the link would fail. Whether you are taking their address using & or calling them does not matter. At runtime, the DLL is loaded and the function name then resolves to a specific address in the process.
PDB files are used only to provide enhanced symbolic information during debugging. Normally, they are not used at runtime.
[I can't help thinking I'm missing something about this question. Tell me if this is not your problem.]

Loading an EXE as a DLL, local vftable

I have an exe named test.exe which is usually used as a stand-alone application. I want to use this exe as a module (a dll) inside another application, app.exe.
The code in test.exe does something really simple like:
void doTest()
{
MyClass *inst = new MyClass();
inst->someMethod();
}
Where someMethod() is virtual and MyClass has a virtual d'tor.
doTest() is exported from test.exe and thus a lib called test.lib is created
app.exe is linked with this lib to statically load test.exe when it starts.
When I'm running test.exe stand-alone it runs just fine but when I'm running it loaded from within app.exe it crashes.
Stepping into the code with the debugger revealed that the crash is in the call to the virtual method. It turns out that the vftable somehow goes bad.
After some investigations it turns out that when the code inside the constructor of MyClass is running , the vftable is one thing but when the call to new returns it is replace with something else called a "local vftable". I found this obscure discussion about why this is.
After about a day of debugging it occurred to me that the pointers in this "local vftable" are the same in both cases, when test.exe is stand alone and whenit is loaded as a module. This can't be right because test.exe is loaded into a different address...
To test this theory I changed the loading address in the linker options to the one where test.exe is loaded when it is in app.exe and now, lo and behold, everything works.
Obviously, this is not a permanent solution because next time this randomly selected address may be occupied and the same problem will occur again.
So my question: Why is this "local vftable" tied to the static loading address of the exe? is loading an exe as a module a bad thing? why does the exe assume it is loaded to its static address?
Just for context: this is all done with MSVC 2008, Windows XP x64.
VC++ strips out reloc info from .exes by default because normally they don't need to be relocatable.
You can force it to retain the reloc info with /fixed:no. See: http://msdn.microsoft.com/en-us/library/w368ysh2.aspx
The workaround I ended up using is to simply add a compile configuration and compile the exe as a real dll instead of forcing it to act like one.
using /fixed:no didn't solve the problem for some reason.
Another difference I between exes and DLLs is that the entry point is different. a DLL's entry point is DllMain where as an exe has its entry point in the CRT which eventually calls main() or WinMain().