I am trying to add an extension to the Windows SNMP agent and have followed the sketchy documentation that is available. The dll has been built and the two entries have been placed into the registry. Restarting the SNMP service seems to load the DLL. DllMain is called with the following reasons: DLL_PROCESS_DETACH, DLL_PROCESS_ATTACH, DLL_THREAD_ATTACH, DLL_PROCESS_DETACH. But SnmpExtensionInit never seems to get called. Any ideas? TIA.
Can you give the declaration of your SnmpExtensionInit. Sorry it's in french, but try your DLL with slxSNMPInfo tool. This tool just load your DLL and try to invoke SnmpExtensionInit.
Edited (after your comment)
"Err SNMP DLL not detected !" in slwSNMPInfo.exe attest that your DLL does not export "SnmpExtensionInit" function. You can also verify this with Dependency Walker tool.
To export correctly your functions in a Windows DLL you can use a definition file (a .def file) like this :
LIBRARY YOUR-DLL-NAME
DESCRIPTION 'SNMP Extension Agent for Windows NT.'
SEGMENTS
_TEXT PRELOAD
INIT_TEXT PRELOAD
HEAPSIZE 1024
EXPORTS
SnmpExtensionInit
SnmpExtensionTrap
SnmpExtensionQuery
Or you can change your functions déclarations (all the three)
__declspec(dllexport) BOOL SnmpExtensionInit (DWORD dwTimeZeroReference,
HANDLE *hPollForTrapEvent,
AsnObjectIdentifier *supportedView);
Related
I have a question, I came across running an x86 app on XP x64 that throws up a couple (2) of the "The application has failed to start because XYZ.DLL was not found". My question is, it still runs fine! So how does that work? I know if some function is missing you get that and the app doesn't actually run. What causes this message yet it runs fine? I don't think LoadLibrary() would put up a message? Is it from some #pragma comment( lib, "XYZ.lib" ) in a library even if that module not used?
TIA!!
My question is, it still runs fine! So how does that work?
If a DLL function is statically linked and can't be found at runtime, the OS will fail to create and run the process at all. So, the obvious answer is that the DLL function is linked dynamically instead via calls to LoadLibrary() and GetProcAddress() at runtime.
I know if some function is missing you get that and the app doesn't actually run.
If the missing DLL function is linked statically, yes.
What causes this message yet it runs fine? I don't think LoadLibrary() would put up a message?
Actually, it can. Use SetErrorMode() to avoid that. This is stated as much in the LoadLibrary() documentation:
To enable or disable error messages displayed by the loader during DLL loads, use the SetErrorMode function.
See Silently catch windows error popups when calling LoadLibrary().
Is it from some #pragma comment( lib, "XYZ.lib" ) in a library even if that module not used?
Linking to a DLL's .lib creates static linkage to the DLL. Unless the linker has a delay-load feature available AND the project is making use of that feature, in which case any static calls to the lib's referenced DLL functions are converted into runtime calls to LoadLibrary()/GetProcAddress() by the compiler+linker for you.
I have the following situation:
I have a delphi application {$APPTYPE GUI}. (APP1)
If APP1 gets started, it runs the code between
begin and end., just as it should be.
Later, APP1 will be transformed to a DLL (another application will do that - APP2).
APP2 adds the IMAGE_FILE_DLL flag to the Characteristics in the NTFileHeader of APP1.
Then APP2 tries to load the DLL (APP1) with LoadLibrary (or some other COM Command to load a dll) but it returns the error:
Windows encountered an internal error while initializing COM
libraries.
I've done all this with a C project and used the WinMain function. However it seems not to work in Delphi (APP1 gets not started as a DLL). How is it possible to convert APP1 to a working DLL?
EDIT:
I'm trying to port this code from C to Delphi : http://level-23.info/forum/showthread.php?14721-UAC-Bypass-for-Windows-7-RTM-SP1-Windows-8-DP&p=31749
I've ported it correctly and everything works but the CRYPTBASE.dll (APP1) doesn't start . (See Error above)
In a nutshell:
Create a delphi application, add the IMAGE_FILE_DLL characteristics in the file header. Rename it to CRYPTBASE.dll and copy it to C:\Windows\System32\sysprep. Then start sysprep.exe
INFOS HERE: http://www.pretentiousname.com/misc/W7E_Source/win7_uac_poc_details.html
WinMain is a just a name, by convention, to use as the entry point of an executable. The convention for DLL's is to use the name DllMain. The Windows loader does not search for WinMain and LoadLibrary does not search for DllMain, it just calls the entrypoint in the pe header.
Delphi doesn't use either, the exported name of the entry point is start.
WinMain signature differs from DllMain (WinMain takes four parameters), my suggestion is to declare a function DllMain and export it in your exe:
function DllMain(hinstDLL: THandle; fdwReason: DWORD; lpvReserverd: Pointer): BOOL; stdcall;
begin
// do something
end;
exports
DllMain;
The code that modifies your exe (in mem I presume) to be a dll should set the entry point to DllMain (get it's address by walking the EAT).
Also: make sure that the relocation table it not stripped (in release mode) as DLL's require it when they are rebased.
I don't think you should do that at all. Code is compiled with different assumptions when building EXE and DLLs, it will not work if you simply flip the flag and change the extension.
Trying something like that is a good way to experiment and learn stuff but it's a bad idea for production.
Tell us what are you trying to achieve, in more concrete terms than "To run my DLL as EXE". Why do you need to run your DLL as EXE?
For instance, you can build DLL and then load and call it with rundll32. If you need this for COM, you can build an COM host exe and rely on COM's automatic marshalling to achieve the effect of "as if my code was in the same process". It's all already present in COM.
When one should implicitly or explicitly link to a DLL and what are common practices or pitfalls?
It is fairly rare to explicitly link a DLL. Mostly because it is painful and error prone. You need to write a function pointer declaration for the exported function and get the LoadLibrary + GetProcAddress + FreeLibrary code right. You'd do so only if you need a runtime dependency on a plug-in style DLL or want to select from a set of DLLs based on configuration. Or to deal with versioning, an API function that's only available on later versions of Windows for example. Explicit linking is the default for COM and .NET DLLs.
More background info in this MSDN Library article.
I'm assuming you refer to linking using a .lib vs loading a DLL dynamically using LoadLibrary().
Loading a DLL statically by linking to its .lib is generally safer. The linking stage checks that all the entry points exist in compile time and there is no chance you'll load a DLL that doesn't have the function you're expecting. It is also easier not to have to use GetProcAddress().
So generally you should use dynamic loading only when it is absolutely required.
I agree with other who answered you already (Hans Passant and shoosh). I want add only two things:
1) One common scenario when you have to use LoadLibrary and GetProcAddress is the following: you want use some new API existing in new versions of Windows only, but the API are not critical in your application. So you test with LoadLibrary and GetProcAddress whether the function which you need exist, and use it in the case. What your program do if the functions not exist depend total from your implementation.
2) There are one important options which you not included in your question: delayed loading of DLLs. In this case the operating system will load the DLL when one of its functions is called and not at the application start. It allows to use import libraries (.lib files) in some scenarios where explicitly linking should be used at the first look. Moreover it improve the startup time of the applications and are wide used by Windows itself. So the way is also recommended.
I'm looking at incorporating Lua into a C++ project, and am a bit confused by the presence of the two binaries (lua51.dll and lua5.1.dll) in the distribution from Luabinaries.
According to the docs...
In Windows your library or application
must be linked with a stub library. A
stub library is a library with only
the function declarations that will
bind your DLL with the Lua DLL.
Why? I've never needed stub DLLs before when linking with third-party DLLs?
A stub library is a .lib file, not a DLL. It contains function declarations for all the exported functions in the DLL, which just forward the call into the DLL itself. So if you build an application that you want to link with lua51.dll, you tell the linker to link with lua51.lib, and all calls to exported functions will be forwarded to the DLL. If you didn't do this, you would get a lot of "unresolved external symbol" errors when linking.
This is only needed when statically linking with a DLL (so that it is loaded automatically when the application is run). It is not needed when loading the DLL dynamically with LoadLibrary.
Regarding why they have two different DLLs, The manual says this:
The LuaBinaries DLL packages have a dll proxy called "lua51.dll". It can be used to replace other "lua51.dll" released by other distributions. It will simply forward calls to the "lua5.1.dll". There is no compiled source code involved in the forwarding.
Basically, some existing applications link with lua5.1.dll while others link with lua51.dll and they want to support them both. In any case this is not related to the stub libraries.
I believe it's to do with __declspec(import) and __declspec(export) vs GetProcAddress. However, I don't actually know for sure.
For various reasons (questioning the reasons is not helpful to me), I'd like to implement my own extended mapi dll for windows xp. I have a skeleton dll now, just a few entrypoints exist for testing, but the system mapi stub (c:\windows\system32\mapi32.dll, I've checked that it's identical to mapistub.dll) will not pass through calls to my dll, while it happily passes the same calls through to MS Outlook's msmapi32.dll, (MAPIInitialize, MAPILoginEx are two such calls). There's some secret handshake between the stub and the extended mapi dll wherein the stub checks that "yup, it's an extended mapi dll": maybe it's the presence of some additional entrypoints I haven't implemented yet, maybe it's the return value from some function, I don't know. I've tried tracing a sample app I wrote that calls MAPIInitialize with STraceNT and ProcessMonitor but that didn't show anything obvious. Tracing has shown that indeed the stub loads my dll, but then finds the secret sauce is missing apparently, and returns an error code instead of calling my dll's function. What more could be needed for calling MAPIInitialize than the presence of MAPIInitialize in my dll's exports table? GetProcAddress says it's there.
What I'd like to know is how to minimally extend my skeleton extended mapi dll so that the stub mapi dll will pass through extended mapi calls to my dll. What's the secret sauce? I'd rather not spend a painful week in msvc reverse engineering the stub behavior.
Figured it out by loading MS's debugging symbols and diving in to the stub library code in the debugger. The stub library doesn't load "MAPIInitialize", it loads "MAPIInitialize#4". I added MAPIInitialize#4=_MAPIInitialize#4 to my EXPORTS section of the .def file and all works fine now.
By the way, in order to get symbols for system libraries, don't download MS's debugging symbol package for XP SP3, the symbols were not updated correctly and won't work in the debugger. Instead point VS to MS's online symbol server (http://msdl.microsoft.com/download/symbols) and let VS slurp the symbols to a local symbol cache directory.