I'm trying get the address of GetProcAddress with GetProcAddress (yes. calling it on itself).
When I'm doing it from an empty exe project I get a valid address (between the allocated address of kernel32).
When I'm calling it from a dll, I'm getting invalid address (not in the range of the allocated kernel32)
What is the difference?
I'm running on windows 7 with 64 bit.
The project are compiled as 32 bit.
Here is the code that I'm running:
typedef FARPROC (WINAPI * GetProcAddressType)(HMODULE , LPCSTR );
HMODULE kernel32Hmodule = LoadLibraryW(L"c:\windows\system32\kernel32.dll");
GetProcAddressType abc = (GetProcAddressType)GetProcAddress(kernel32Hmodule, "GetProcAddress");
I also tried to get the address like this: void* a = GetProcAddress;
but it returns the same invalid address when running from a dll...
Please help.
Exe are normally loaded at their preferred addresses, DLL are often relocated (not loaded at their preferred addresses) when they opt for ASLR and when the relocation is needed (e.g. their preferred address is already taken). This could explain the delta you experienced between the behaviours.
ok i found the problem. when i loaded the dll with rundll32 it acted wierd... when i build a loader by myself (loadlibrary, than getprocaddress) it worked fine. rundll32 is the one caused the problems
Related
I have an existing project, originally implemented as a Vxworks 5.5 style kernel module.
This project creates many tasks that act as a "host" to run external code. We do something like this:
void loadAndRun(char* file, char* function)
{
//load the module
int fd = open (file, O_RDONLY,0644);
loadModule(fdx, LOAD_ALL_SYMBOLS);
SYM_TYPE type;
FUNCPTR func;
symFindByName(sysSymTbl, &function , (char**) &func, &type);
while (true)
{
func();
}
}
This all works a dream, however, the functions that get called are non-reentrant, with global data all over the place etc. We have a new requirement to be able to run multiple instances of these external modules, and my obvious first thought is to use vxworks RTP to provide memory isolation.
However, no matter what I try, I cannot persuade my new RTP project to compile and link.
error: 'sysSymTbl' undeclared (first use in this function)
If I add the correct include:
#include <sysSymTbl.h>
I get:
error: sysSymTbl.h: No such file or directory
and if i just define it extern:
extern SYMTAB_ID sysSymTbl;
i get:
error: undefined reference to `sysSymTbl'
I havent even begun to start trying to stitch in the actual module load code, at the moment I just want to get the symbol lookup working.
So, is the system symbol table accessible from VxWorks RTP applications? Can moduleLoad be used?
EDIT
It appears that what I am trying to do is covered by the Application Programmers Guide in the section on Plugins (section 4.9 for V6.8) (thanks #nos), which is to use dlopen() etc. Like this:
void * hdl= dlopen("pathname",RTLD_NOW);
FUNCPTR func = dlsym(hdl,"FunctionName");
func();
However, i still end up in linker-hell, even when i specify -Xbind-lazy -non-static to the compiler.
undefined reference to `_rtld_dlopen'
undefined reference to `_rtld_dlsym'
The problem here was that the documentation says to specify -Xbind-lazy and -non-static as compiler options. However, these should actually be added to the linker options.
libc.so.1 for the appropriate build target is then required on the target to satisfy the run-time link requirements.
Hi everyone.
I have to work with old utility: which converts xls into txt.
There was a small problem in logic of the utility, but the problem is in other thing...
The utility consists of two parts: exe module and dll module, and uses MFC.
In exe project we have
pInit = (t_bXR_Init)GetProcAddress(hExcel, _T("bXR_Init"));
and
pInit("logfiles",false);
In dll project we have
typedef bool (*t_bXR_Init) (CString const &strlogfilespath, bool btxtfile);
XLSREADER_API bool bXR_Init(CString const &strlogfilespath, bool btxtfile);
The problem is when we send argument "logfiles" into the function it doesn't get it. It's strange, 'cause all other parameters are send properly.
The reason is somehow connected with using of CString. But I don't know how...
XLSREADER_API is defined as:
#define XLSREADER_API extern "C" __declspec(dllimport)
Also I've added
AFX_MANAGE_STATE(AfxGetStaticModuleState());
in the beginning of function's body (for bXR_Init). But it didn't help.
Also I tried to change some settings for these two projects, all settings are the same (e.g. calling conversion is __cldecl(/Gd); I build either debug versions exe and dll or release version of exe and dll simultaneously).
Also I tried to use CString instead of CString& - the same situation. It works properly if use char*, but boss says to find what the origin of the problem is at first.
What may lead to the problem (the function doesn't get CString parameter)?
To pass a complex type such as a CString across a DLL boundary you have to make sure that both the DLL and the exe are using the exact same DLL libraries. Set "Runtime Library" to multi-threaded DLL and set "Use of MFC" to Use MFC in a Shared DLL. Also, don't mix debug and release modules: Both must be the same.
Without these conditions you get two different heaps, and you can't keep the allocations/deletions compatible with two heaps.
Try passing an actual CString parameter to the call:
CString sPath = "logfiles";
pInit(sPath,false);
wtfigo! (what the f is going on)
the problem is solved.
I discovered, that exe project had "character set" = "use multibyte character set"
and dll project had "character set" = "use unicode character set".
So, dll function got CString with char* inside, but considered it as CString with wchat_t* inside. And it looked as garbage (as complete garbage on my pc and as chinese symbols on my workmate's pc).
I changed "character set" for exe project to "use unicode character set" and discovered about 60 errors.
Then I read an article http://habrahabr.ru/post/164193/ (in russian; or in english: http://www.codeproject.com/Articles/76252/What-are-TCHAR-WCHAR-LPSTR-LPWSTR-LPCTSTR-etc).
And fixed all errors, widely used macroses from TCHAR.h (MSDN helped me).
Thanks everybody for your help.
Hallo fellow members,
I run into a very strange problem today and I am not exactly sure as to what is causing it. Here is a function which I use to get the current working directory :
#ifdef _WIN32
#include <direct.h>
#define GetCurrentDir _getcwd
#else
#error "There is currently no support for non windows based systems!"
#endif
const std::string getCurrentPath()
{
char CurrentPath{_MAX_PATH];
GetCurrentDir(CurrentPath, _MAX_PATH);
CurrentPath[_MAX_PATH - 1] = '/0';
return std::string(CurrentPath);
}
This function works well as a stand alone function. However if I declare it as a static function inside a class :
static __declspec(dllexport) const std::string getCurrentPath(void);
and a .dll I get "debug assertion failed error" when I try to do
std::cout<<CUtilities::getCurrentPath()<<std::endl;
If I instead write :
std::string dir = CUtilities::getCurrentPath();
std::cout<<"Dir is : "<<dir<<std::endl;
it works fine. I am totally confused as to what I am doing wrong. Any ideas?
I finally found out what the problem was. The project was compiled with /MT options , therefore the .dll had a different heap than the original file. So when the string size was bigger than it's initial size (15) then heap was allocated from the .dll's side. However the string had it's destructor called from the main program side and then the destructor was trying to deallocate memory from the .dll's heap thus resulting in "heap corruption error"
The solution was to simply compile with /MD options.
I'm trying to build a small program that hosts vst effects and I would like to scan a folder for plugin dlls.
I know how to find all the dlls but now I have the following questions:
What is the best way to determine if a given dll is a vst plugin?
I tried to just see if the ddl exports the proper function and this works fine for plugins made with the more recent versions of the vst sdk since it exports a method called "VstPluginMain" but older versions export a rather generic "main" function.
How do I determine if the plugin is an effect or an instrument?
How do I scan vst shell plugins?
Shell plugins are basically dlls that somehow contain multiple effects. An example of this are the plugins made by Waves Audio http://www.waves.com/
ps: If there is a library that can do all of this for me please let me know.
How to determine a VST plugin?
Once you've found main/VSTPluginMain... call it!
If what's returned is NULL, it's not a VST.
If what's returned is a pointer to the bytes "VstP" (see VstInt32 magic; ///< must be #kEffectMagic ('VstP') in aeffect.h), then you have a VST.
The VSTPluginMain returns a pointer to an AEffect structure. You will need to look at this structure.
Effect or instrument? AEffect::flags | (effFlagsIsSynth = 1 << 8)
Shell VSTs are more complex:
Category will be kPlugCategShell
Support the "shellCategory" canDo.
Use effShellGetNextPlugin to enumerate.
To instance, respond to audioMasterCurrentId in your callback with the ID you want.
#Dave Gamble nailed it, but I wanted to add a few things on VST shell plugins, since they are a bit tricky to work with.
To determine if a VST is a shell plugin, send the effGetPlugCategory opcode to the plugin dispatcher. If it returns kPlugCategShell, then it's a shell plugin. To get the list of sub-plugins in the shell, you basically call effShellGetNextPlugin until it returns 0. Example code snippit (adapted from a working VST host):
// All this stuff should probably be set up far earlier in your code...
// This assumes that you have already opened the plugin and called VSTPluginMain()
typedef VstIntPtr (*Vst2xPluginDispatcherFunc)(AEffect *effect, VstInt32 opCode, VstInt32 index, VstIntPtr value, void *ptr, float opt);
Vst2xPluginDispatcherFunc dispatcher;
AEffect* plugin;
char nameBuffer[40];
while(true) {
memset(nameBuffer, 0, 40);
VstInt32 shellPluginId = dispatcher(pluginHandle, effShellGetNextPlugin, 0, 0, nameBuffer, 0.0f);
if(shellPluginId == 0 || nameBuffer[0] == '\0') {
break;
}
else {
// Do something with the name and ID
}
}
If you actually want to load a plugin in a VST shell, it's a bit trickier. First, your host needs to handle the audioMasterCurrentId opcode in the host callback. When you call the VST's VSTPluginMain() method to instantiate the plugin, it will call the host callback with this opcode and ask for the unique ID which should be loaded.
Because this callback is made before the main function returns (and hence, before it delivers an AEffect* to your host), that means that you probably will need to store the shell plugin ID to load in a global variable, since you will not be able to save a pointer to any meaningful data in void* user field of the AEffect struct in time for it to be passed back to you in the host callback.
If you want to develop your VST Host application in .NET take a look at VST.NET
I'm evaluating Server 2008. My C++ executable is getting this error. I've seen this error on MSDN that seems to have required a hot-fix for several previous OSes. Anyone else seen this? I get the same results for the 32 & 64 bit OS.
Code snippet:
HRESULT GroupStart([in] short iClientId, [in] VARIANT GroupDataArray,
[out] short* pGroupInstance, [out] long* pCommandId);
Where the GroupDataArray VARIANT argument wraps a single-dimension SAFEARRAY of VARIANTs wrapping a DCAPICOM_GroupData struct entries:
// DCAPICOM_GroupData
[
uuid(F1FE2605-2744-4A2A-AB85-1E1845C280EB),
helpstring("removed")
]
typedef struct DCAPICOM_GroupData {
[helpstring("removed")]
long m_lImageID;
[helpstring("removed")]
unsigned char m_ucHeadID;
[helpstring("removed")]
unsigned char m_ucPlateID;
} DCAPICOM_GroupData;
After opening a support case with Microsoft, I can now answer my own question. This is (now) a recognized bug. The issue has to do with marshalling on the server side, but before the server code is called. Our structure is 6 bytes long, but this COM implementation is interpreting it as 8, so the marshalling fails, and this is the error you get back. The workaround, until a Service Pack is released to deal with this, is to add two extra bytes to the structure to pad it up to 8 bytes. We haven't run across any more instances that fail yet, but we still have a lot of testing to do still.
We ran into the same error recently with a client/server app communicating via DCOM. It turned out that the size of a marshalled interface pointer going across the wire (i.e., not local) had changed (gotten bigger). You might like to check whether your code is doing any special marshalling via CoMarshalInterface or the like.