I couldn't find a solution here after searching so I have to ask! Please excuse my language, because I'm pretty new in the NPAPI business.
What I have, is an existing plugin which receives data in a cycle of about 100ms out of a local running xulrunner application comming out of a nsComponent (the dataCreator). The result looks pretty well and the xul app is stable so far. But if I increase the occurance of data (which I have to), the xul app needs too long for reaction and this ends up in xul crashes. I think a XUL->Plugin I/O is a bit expensive!?
What I have learned until now, is that the plugin is able to create a new instance of a component:
// inside myPlugin.cpp
nsresult rv;
nsCOMptr< myCompClass > _myComPtr ;
_myComPtr = do_CreateInstance( "#myDomain.org/DIR/MYCOMPONENT;1", &rv ) ;
The function
do_CreateInstance( ) ;
comes from nsComponentManagerUtlis.h which is out of the xulrunner SDK, but it has nothing like
do_giveMeTheRunningInstanceOf( "#myDomain.org/DIR/MYDATACREATOR;1", &rv ) ;
My intuition now is to use the
nsScriptablePeer::Invoke(NPIdentifier name, const NPVariant *args, uint32_t argCount, NPVariant *result )
method to pass a nsCOMptr of the running dataCreator into the plugin, make direct communication possible and reduce the xul<-->plugin I/O to a minimum.
Creating another instance of the dataCreator is definitely not an option!
To be honest: I've no idea how to "convert" the NPVariant (args[0]) into the needed nsCOMptr, did you? Or is there another possibility to receive the pointer inside the plugin?
Thanks for your help
There is no way that I am aware of to interact with the xulrunner sdk directly from a npapi plugin, as they use totally different APIs. NPVariants cannot pass a xulrunner object or other native pointer type.
This is a total brainstorm and I have no idea if it would work, but if you could somehow combine a xulrunner extension and a npapi plugin into the same module, you could probably use a global map and an id from the plugin to get shared memory, but I have no idea if that's possible or not.
You are correct that interfacing with javascript has a cost; really, though, it's the individual calls that have the most cost because they end up being cross-process. Often you can minimize this by using more efficient calls. Faster than 100ms should definitely not be an issue.
Related
I'm trying to develop C++ application for a client. So far, i have added the basic functionalities and it works as expected but i will likely to gradually grow the application in future (i.e. adding more feature to it) and the client will likely to update those feature in their app. Now my questions are the following:
For adding feature, i have decided to add features to a dll and the client will likely replace the old dll with the new one (in order to use latest features). Is there a better approach for updating C++ app?
Why some developer use ordinal values instead of function names while exporting symbols, whats the benefit of using ordinal values other than less binary file size ?
I don't want my client to recompile/link the app, i just want to keep the updating process as smooth as possible. Need advice.
P.S:
Environment = Windows + Visual Studio
#Vasilij way is the way to go. If you update only de DLL, how you application will know that there are new functions to call? You have to dynamically adapt your menus and so on.
Just create an exe stub that runs the real application (may be in a subprocess it can kill) and update the whole app (not the stub) and DLLs when necessary. That stub can check for updates also and suggest the restart after downloading.
I'm struggling to find a basic example on how to set up a minimal plugin host with VST 3.x SDK. The official documentation is absolutely criptic and brief, I can't get anywhere. I would like to:
understand the minimal setup: required headers, interfaces to implement, ...;
load a VST3 plugin (no fancy GUI, for now);
print out some data (e.g. plugin name, parameters, ...).
That would be a great start :)
Yeah, VST3 is rather mysterious and poorly documented. There are not many good examples partially because not many companies (other than Steinberg) actually care about VST3. But all cynicism aside, your best bet would be to look at the Juce source code to see their implementation of a VST3 host:
https://github.com/julianstorer/JUCE/blob/master/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp
There's a few other VST3-related files in that package which are worth checking out. Anyways, this should at least be enough information to get get you started with a VST3 host.
It's worth noting that Juce is GPL (unless you pay for a license), so it's a big no-no to borrow code directly from it unless you are also using the GPL or have a commercial license. Just a friendly reminder to be a responsible programmer when looking at GPL'd code on the net. :)
Simple VST3 hosts already exist in the VST SDK. It is not difficult to augment them, but there are some things to keep in mind.
The samples under public.skd/vst-hosting in the VST SDK contain an EditorHost and and AudioHost. The first handles the GUI, the second handles the effect (the signal processing). You can combine the two. Neither is a full implementation.
VST objects are COM objects and so you have to make sure to set up the application context correctly, so that your COM objects persist between calls. EditorHost and AudioHost both do that in a couple of lines in a global context variable (look for pluginContext).
If you use separate calls to load and unload effects, process data, and so on, you have to keep COM object pointers, so they are not unloaded. For example, you may be tempted to ignore the Steinberg::Vst::Module module, since you don't need it once the effect is loaded, but you would have to keep a pointer to it somewhere globally or in the main application thread. If not, the automatic unloading of that pointer will also unload the plugin as well and subsequent calls to the plugin will fail.
The construction of VST effects is relatively simple. They consist of a component (the effect) and a controller (the GUI). Both are instantiated when Steinberg::Vst::PlugProvider is loaded (some effects do not have a GUI). Both examples above load a plugprovider. Once you load a plugprovider, you are essentially done.
The following code is sufficient to load a plugprovider (the whole effect). Assume returning -1 means an error:
std::string error;
std::string path = "somepath/someeffect.vst3";
VST3::Hosting::Module::Ptr module =
VST3::Hosting::Module::create(path, error);
if (! module)
return -1;
IPtr<PlugProvider> plugProvider;
VST3::Optional<VST3::UID> effectID = std::move(uid);
for (auto& classInfo : module->
getFactory().classInfos())
{
if (classInfo.category() == kVstAudioEffectClass)
{
if (effectID)
{
if (*effectID != classInfo.ID())
continue;
}
plugProvider = owned(new
PlugProvider(module->getFactory(),
classInfo, true));
break;
}
}
if (! plugProvider)
return -1;
After this, plugProvider->getComponent() and plugProvider->getController() give you the effect and GUI. The controller has to be displayed in a window, of course, which is done in EditorHost. These are the implementations of IComponent,IAudioProcessor and IEditController in the VST SDK.
The source/vst/testsuite part of the VST SDK will show you the full functionality of both of these parts (it will essentially give you the functional calls that you can use to do everything you want to do).
Note the module and plugprovider loaded in the code above. As mentioned above, if you don't keep the module pointer, there is no guarantee the plugprovider pointer will survive. It is difficult to keep track of what gets released when in the VST SDK.
I've been asked by a client to solve the following pesky issue. They have a custom software that has a tendency of displaying message boxes "left and right" without any apparent reason. For instance, the software itself is an accounting program, and when they take a customer's payment, the message box may be displayed about 3 or 4 times in a row. Each message box plays Windows default sound. Unfortunately the way this software was programmed, the type of sounds it plays is completely wrong. For instance, it may display a warning message box and play the warning system sound when the message itself is just an information. All this is quite annoying for the staff who uses the software.
I tried to contact the vendor who distributes the software, but I hit a deadend with them. So now I am looking for ways to mitigate this issue.
My easiest solution was to suggest to mute the speakers, but unfortunately, they require sound to be present to be able to hear incoming emails, and most importantly, be able to play voice mail from them later. So my solution was to somehow mute message box sounds just for a single process.
From my experience, I know that there're two APIs that may be producing these sounds: MessageBeep and an older Beep.
I also found this article that explains how to use AppInit_DLLs to hook to system APIs. It works great, except that both of the APIs that I need to hook to come from User32.dll and not from kernel32.dll like the author suggests.
There's also this post in the questions section that kinda gives approximate steps to hooking to an API from User32.dll, but when I tried to implement them, there's not enough information (for my knowledge to do it.)
So my questions is, does anyone know how to hook to an API in the User32.dll module?
EDIT: PS. Forgot to mention. This software is installed on Windows 7 Professional, with UAC disabled -- because it is not compatible with UAC :)
As an alternative you can patch you application. Find calls to MessageBeep and overwrite them with nop.
This is the hard way of doing it: if your app is supposed to be running as Administrator on a pre-Vista Windows, you could get the address of the API via ::GetProcAddress(), give yourself privileges to write to its memory page, and overwrite the beginning of the API's code with a "jmp" assembly instruction jumping into the address of your override function. Make sure your overwrite function takes the same arguments and is declared as __cdecl.
Expanded answer follows.
The "standard" technique for API hooking involves the following steps:
1: Inject your DLL into the target process
This is usually accomplished by first allocating memory in the target process for a string containing the name/path of your DLL (e.g. "MyHook.dll"), and then creating a remote thread in the target process whose entry point is kernel32::LoadLibraryA() passing the name of your DLL as argument. This page has an implementation of this technique. You'll have to wrestle a bit with privileges, but it's guaranteed to work 100% on Windows XP and earlier OSes. I'm not sure about Vista and post-Vista, Address Space Layout Randomization might make this tricky.
2. Hook the API
Once your DLL is loaded into the target process, its DllMain() will be executed automatically, giving you a chance to run anything you want in the target process. From within your DllMain, use ::LoadLibraryA() to get the HMODULE of the library containing the API you want to hook (e.g. "user32.dll") and pass it to ::GetProcAddress() together with the name of the API you want to hook (e.g. "MessageBeep") to get the address of the API itself. Eventaully give yourself privileges to write to that address' page, and overwrite the beginning of the API with a jmp instruction jumping into your detour (i.e. into your "version" of the API to hook). Note that your detour needs to have the same signature and calling convention (usually _cdecl) as the API you want to hook, or else monsters will be awakened.
As described here, this technique is somewhat destructive: you can't call back into the original API from the detour, as the original API has been modified to jump into yours and you'll end up with a very tight and nice infinite loop. There are many different techniques that would allow you to preserve and/or call back into the original API, one of which is hooking the ...A() versions of the API and then calling into the ...W() versions (most if not all of the ...A() Windows API's convert ASCII strings into UNICODE strings and end up calling into their ...W() counterparts).
No need to spend time on a custom program to do this.
You can mute a particular application when it's running, and that setting will be remembered the next time you open the application. See https://superuser.com/questions/37281/how-to-disable-sound-of-certain-applications.
There's also the Windows Sound Sentry that will turn off most system sounds, although I'm not aware of any per-application settings for Sound Sentry.
You can use Deviare API hook and solve the hook in a couple of C# lines. Or you can use EasyHook that is a bit more difficult and less stable.
So at work I have been working for a few months on a OPOS driver for a few different things. I didn't create the project, but I have taken it over and am the only one developing it. So today I got curious about the way that it was done and I think that it may have started off on the wrong foot. I had to do a little bit of digging to find out that it uses the OPOS drivers from a company called MCS (Monroe Consulting Services) I downloaded 1.13 and installed the MSI version. I fired up VS created a new mfc dll. I then went to add a class. This is where I am confused.
It doesn't matter if i choose Typelib or ActiveX it usually gives me the same list of interfaces that I can add/extend from(with one exception that comes to mind with MSR it has an events interface that I can extend) And they both make the same header file (in the case with msr it is COPOSMSR.h) but one extends CCmdTarget, and the other extends CWnd. This is my first question. Which should I choose? what is a typelib/ what is a ActiveX component and how do they differ from one another.
The one i've been working on extends CCmdTarget. For the life of me I can not figure out how the driver knows to use one of the files (USNMSRRFID) but that is where all the development went into. (I broke it up a bit so it wasn't just one huge file) But that file doesn't extend COPOSMSR..it extends CCmdTarget as well. The only time i see anything mention the USN file is in MSRRFID.idl (which confuses me even more) Any one have clarity for this?
Part of me thinks this could make a very big impact when it comes time to deploy. A few of the test apps that have been written that make use of this driver require a somewhat confusing setup process that involves registering different drivers, copying files into a specific folder, setting up the registry and so forth. I think that if i can get a grip on what this all means and how to make a nice application that extends one of these OPOS devices properly that I could save my self further grief in the future.
Any tips or pointers??? Sorry if it is a newb question..but i am new to C++. I started with Java then moved to C# so some of this stuff is WAY over my head....
Well so I've done TONS of digging, and it is like searching for dinosaurs. Not easy, and hard to find. I will end up writing a nice little how to on this, but for now I will put up my findings. Although I still don't have this 100% i know I am close.
Turns out the typelib and activeX things are not a big concern but come into play after you've gotten started. ActiveX is for Control objects, and Typelib is for the Service Object. The most important thing is to get started correctly. I found a article on some Chinese website that offers some OK tips after figuring out the translation errors. To start with you will want to make a C++ project with Automation. It can be ATL or MFC. My preference is MFC. In the UPOS 1.13 pdf (or newer) in Appendix A section 8 it describes the responsibilities of the Service object. It has the main methods you need to implement. There are 16 methods you have to add, and at least 4 methods that get/set the properties for your OPOS device.
So to get started you will need to open up the add class wizard (for MFC classes) and click Add MFC class. You wil want your base class to be CCmdTarget. Come up with a classy Class name (I chose PinpadSOCPP) Then in the automation radio buttons select Creatable by type ID. It should fill in your type id as [Project Name].[Class name] so mine was PinpadSO.PinpadSOCPP. hit finish. This makes a nice interface file that you can use Class view to add methods and so forth to it.
As for adding the methods there are 2 things to note about this, and one of them I haven't figured out 100% yet. The first is that you have to implement all the methods in that section with the correct parameters and return values. Most of them return LONG (32bit signed number). and the 2 most common parameters are LONG and BSTR. (there is the occasional pointers for when you have "out" parameters) This is the part that I think that I am currently failing as I don't know if I have them all implemented correctly and that is why I am getting error 104/305 (which from the Chinese article says that I am missing something from my methods) I'm not sure if it is case sensitive, and I'm not sure of the 7 properties that look to need to have get/set which ones need to be implemented because the MSR SO that i am working on from work doesn't use them all and that SO is working. The other is that after you implement the base OPOS methods you have to also implement the extra methods from your specific OPOS device. Since I am doing PINPad there are 6 additional methods I have to implement.
Now this is a lot of time consuming work because you have to open up class view, navigate to the name of your project class. Expand it and go to the Interface portion. My Project name is PinpadSO, and the file that I am implementing this in is PinpadSOCPP (which means the interface name is IPinpadSOCPP) right click on IPinpadSOCPP and click add > add method. This brings you to a 2 step process. You fill in your return value, name of your function, add in all your parameters. Hit next and fill out some help string info (if you want) and hit finish. Now after you do that 20+ times it gets old and slow...and if you are like me you type Computer instead of Compute and flip flop letters, or forget to hit add on all your parameters. A person could make a nice little program to edit the 3 files that get changed each time you add a method and that would speed it up considerably. If you make a mistake you will need to open up [project name].idl, [class name].h, and [class name].cpp those are the 3 files that get the methods added to it directly. I recommend not making a mistake.
so now that all that hard work is out of the way. Compile your program. If you want to save your self an extra step you could turn on Auto Register in the linker project settings (NOTE: if you do that you'll need to run Visual Studio as admin if you program in vista or higher) this would save you of having to open a command window (admin) navigate to your DLL and use the command regsvr32 on that DLL. Nice thing is that you don't have to do that over and over again, just the once will do. I have no hard facts that it works like that every time but the MSR SO that I am working on, I'll make changes to it, compile it, then open up my OPOS tester program and the changes have taken affect.
After that you need to make your registry additions. navigate to HKLM\software\OLEforRetail\ServiceOPOS
(NOTE if you have a x64 machine you'll do this twice. One there, and again at HKLM\software\Wow6432Node\OLEforRetail\ServiceOPOS )
You'll need to add a Key for whatever OPOS device you are working with. I am making a pinpad SO so I made a Key called PINPad (check your UPOS document to see what name you should give it) Lastly choose a name for your device. I chose the model type of the from the vendor as my device name (C100) and made a sub key in PINPad. The default REG_SZ value needs to be your registered SO Device TypeID. in my case it is PinpadSO.PinpadSOCPP
if you don't have a OPOS test program (which I just made my own as a console program) then you can use the Microsoft OPOS test app (I couldn't get it to work on my x64 machine...but maybe you'll have better luck with it) If you do decide to make your own OPOS test app make sure you compile it for x86 machines (even if you have x64) OPOS does not like x64 for some reason (probably the pointers length I'd assume)..at any rate. Once you got it all setup run your test app (for my case I am just running OPOSPinpadClass pin = new OPOSPinpadClass(); Console.WriteLine(pin.Open("C100")); and hope for 0 :)
I am currently getting 104 (E_NOSERVICE)..and like i said before i think it is because I don't have all my methods correct. If that turns out to be the case I'll edit this response, or I'll report back and say what it really was.
Anywho, i hope this helps anyone else who decides they want to make their own SO. Good luck
UPDATE
OPOS checks a couple of properties when you call the Open command. One of the properties that is a must to implement is the in the GetPropertyNumber, and it is PIDX_ServiceObjectVersion. You will need to set this number to return (1000000 * majorVersion) + (1000 * minorVersion) + revision since I am making a OPOS 1.13 compatible SO my returned ServiceObjectVersion is 1013000. You will also want to implement 3 properties in GetPropertyString:
PIDX_DeviceDescription
PIDX_DeviceName
PIDX_ServiceObjectDescription
For all other values you can return a empty string or 0 until you start hooking all those things up.
As a side note if you don't want to make it in C++ you don't have to. You can make it in any language that you can write a ActiveX object in (such as a COM visible .NET class library)
I'm starting up a new embedded system design using FreeRTOS. My last one used eCos, which has a built-in HTTP server that's really lightweight, especially since I didn't have a filesystem. The way it worked, in short, was that every page was a CGI-like C function that got called when needed by the HTTP daemon. Specifically, you would write a function of the form:
int MyWebPage(FILE* resp, const char* page, const char* params, void* uData);
where page was the page part of the url, params were any form parameters (only GET was supported, not POST, which prevented file uploads and thus made burning the flash a pain), uData is a token passed in that was set when you registered the function, so you could have the same function serve multiple URLs or ranges with different data, and resp is a file handle that you write the HTTP response (headers and all) out to.
Then you registered the function with:
CYG_HTTPD_TABLE_ENTRY(www_myPage, "/", MyWebPage, 0);
where CYG_HTTPD_TABLE_ENTRY is a macro where the first parameter was a variable name, the second was a page URL (the * wildcard is allowed; hence page getting passed to MyWebPage()), third is the function pointer, and last is the uData value.
So a simple example:
int HelloWorldPage(FILE* resp, const char*, const char* params, void*)
{
fprintf("Content-Type: text/html;\n\n");
fprintf("<html><head><title>Hello World!</title></head>\n");
fprintf("<body>\n");
fprintf("<h1>Hello, World!</h1>\n");
fprintf("<p>You passed in: %s</p>\n", params);
fprintf("</body></html>\n");
}
CYG_HTTPD_TABLE_ENTRY(www_hello, "/", HelloWorldPage, 0);
(Actually, params would be passed through a function to escape the HTML magic characters, and I'd use another couple functions to split the params and make a <ul> out of it, but I left that out for clarity.)
The server itself just ran as a task (i.e. thread) and didn't get in the way as long as it had a lower priority than the critical tasks.
Needless to say, having this proved invaluable for testing and debugging. (One problem with embedded work is that you generally can't toss up an XTerm to use as a log.) So when Supreme Programmer reflexively blamed me for something not working (path of least resistance, I guess), I could pull up the web page and show that he had sent me bad parameters. Saved a lot of debug time in integration.
So anyway... I'm wondering, is there something like this available as an independent library? Something that I can link in, register my callbacks, spawn a thread, and let it do the magic? Or do I need to crank out my own? I'd prefer C++, but can probably use a C library as well.
EDIT: Since I'm putting a bounty on it, I need to clarify that the library would need to be under an open-source license.
I suggest you have a look at libmicrohttpd, the embedded web server:
http://www.gnu.org/software/libmicrohttpd/
It is small and fast, has a simple C API, supports multithreading, is suitable for embedded systems, supports POST, optionally supports SSL/TLS, and is available under either the LGPL or eCos license (depending). I believe this fulfils all your requirements. It would be trivial to wrapper in C++ if you preferred.
Mongoose is licensed under GPLv2 and is lightweight (just one C file so easy to include into a new project). It will run in a separate thread and support callbacks.
http://www.ibm.com/developerworks/systems/library/es-nweb/index.html
Seems exactly what you are after. You my need to do a small amount of re-writing to get it to run under FreeRTOS but its a very small, very lightweight web server.
I'm not familiar with FreeRTOS and how it supports TCP/IP and sockets, so I can't say for sure but you might want to take a look at the GoAhead web server. http://embedthis.com/goahead/