Getting Interface Implementation of built-in Mozilla Firefox Component - c++

I'm currently trying to develop a custom password manager in c++.
I've already developed a deployable module implementing the nsILoginManagerStorage interface, can install it on firefox and it is being called properly by firefox when a password field appears.
The problem is that when I try to instantiate the nsILoginInfo objects to be returned, the do_CreateInstance function is always returning null.
My method implementation is:
NS_IMETHODIMP FirefoxComponent::FindLogins(uint32_t *count, const nsAString & aHostname, const nsAString & aActionURL, const nsAString & aHttpRealm, nsILoginInfo * **logins)
{
nsILoginInfo ** array = static_cast<nsILoginInfo**>(nsMemory::Alloc(sizeof(nsILoginInfo*)));
nsresult result;
nsCOMPtr<nsILoginInfo> loginInfo = do_CreateInstance("#mozilla.org/login-manager/loginInfo;1" , &result);
//nsCOMPtr<nsILoginManager> loginInfo = do_CreateInstance("#mozilla.org/login-manager;1" , &result);
if (NS_FAILED(result)){
printf("shouldn't be here!!\n");
return result;
}
}
I've tried getting an nsILoginManager instance (just to check if it worked) but it had the same result. The nsILoginInfo can be instantited by java script on firefox using:
Components.classes["#mozilla.org/loginmanager/loginInfo;1"].createInstance(Components.interfaces.nsILoginInfo);
I'm using firefox 20.0 and xul-runner-sdk 20.0 (same results with 20.0.1), on Ubuntu x64, and building with QtCreator (for x64).
My code has been inspired from https://github.com/infinity0/mozilla-gnome-keyring
Since I now that nsILoginInfo is properly loaded into firefox, is there any required field/information for firefox to allow me to access these interfaces?
Thanks for the support.
edit:
Tried to load the module by accessing the component manager directly, but I cannot load the component manager.
nsIComponentManager * manager;
result = NS_GetComponentManager(&manager);
if (NS_FAILED(result)){
printf("failed getting component manager!!\n");
return result;
}

After lots of trial and error I discovered that this error was due to bad linking of the libraries. I was missing one library (libxpcom.so).
To compile and run it right i use the libraries libxpcom.so and libxpcomglue_s.a, both found at the gecko sdk/xul-runner lib folder.
More information about which libraries to compile with in each platform:
https://developer.mozilla.org/en-US/docs/XPCOM_Glue

Related

How can i attach a debugger to google v8?

In my application (Windows 10 VC2017) i enabled the possibility to write and execute scripts using google v8 and v8pp.
v8pp calls a script like this:
v8::Local<v8::Value> context::run_script(std::string const& source, std::string const& filename)
{
v8::EscapableHandleScope scope(isolate_);
v8::Local<v8::Context> context = isolate_->GetCurrentContext();
v8::ScriptOrigin origin(to_v8(isolate_, filename));
v8::Local<v8::Script> script;
bool const is_valid = v8::Script::Compile(context,
to_v8(isolate_, source), &origin).ToLocal(&script);
v8::Local<v8::Value> result;
if (!script.IsEmpty())
{
auto res1 = script->Run(context); //
if(! res1.IsEmpty())
result = res1.ToLocalChecked();
}
return scope.Escape(result);
}
How can i attach a debugger (chrome debug) to my code?
I found googles description at https://v8.dev/docs/inspector -
But this leaves some things blank and consists mostly of js code?
And i found the implementation for v8toolkit at https://github.com/xaxxon/v8toolkit/blob/master/src/debugger.cpp. But this seems to run not for windows.
What is a easy way to attach chrome debug to js code? The code is typically not a file but rather is stored in a data base and then stored in a std::string.
I finally got done a windows version of v8inspector that works well with my stand alone windows application with integrated v8.
I made a own fork including descriptions where to find/build the required 3rd party libraries (or where to find prebuilds). I also did a number of changes/additions:
https://github.com/StefanWoe/v8inspector
In the meanwhile this has also been merged into the parent project:
https://github.com/hsharsha/v8inspector
EDIT:
In the meanwhile ive been pointed to another implementation built with boost::beast and no other dependencies. Much simpler and more robust etc.:
https://github.com/ahmadov/v8_inspector_example

Enumerate Upgrade Codes of installed products?

I'd like to get list of all Upgrade codes of all installed products on Windows box. The question is: is there a dedicated MSI function to address this request?
There is MsiEnumProducts() that enumerates all installed products and MsiEnumRelatedProducts() to enumerate all products for the given Upgrade code. But I can't find a function to get all Upgrade codes in the system.
The workaround I can imagine is use MsiEnumProducts() to get list of all installed products, open each with MsiOpenProduct() function and read "UpgradeCode" property with MsiGetProductProperty(). But this should be very slow due to multiple MsiOpenProduct() calls.
I believe MsiEnumProducts loop with MsiOpenProduct and then MsiGetProductProperty is the correct official sequence. If you really need faster and are willing to bypass the API's you could read the registry directly at HKCR\Installer\UpgradeCodes. You'll have to reverse the Darwin Descriptors though. This isn't technically supported but the reality is these keys have been there for 16 years and MSFT has been doing ZERO development on The Windows Installer. Ok, maybe they updated the version number and removed ARM support in Windows 10 LOL.
FWIW, I like to use C# not C++ but the concept is the same. The following snippet ran on my developer machine in about 2 seconds.
using System;
using Microsoft.Deployment.WindowsInstaller;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
foreach (var productInstallation in ProductInstallation.AllProducts)
{
using(var database = new Database(productInstallation.LocalPackage, DatabaseOpenMode.ReadOnly))
{
Console.WriteLine(database.ExecutePropertyQuery("UpgradeCode"));
}
}
}
}
}
According to the DTF documentation, ProductInstallation.AllProducts uses MsiEnumProducts. The Database class constructor is using MsiOpenDatabase and ExecutePropertyQuery is a higher level call that basically abstracts doing a SELECT Value from Property WHERE Property = '%s'. So it'll be calling APIs to create, execute and fetch results from views. All these classes implement IDisposable to call the correct APIs to free resources also.
Ya... that's why I love managed code. :)

WinRT API WIndows::System::Launcher::LaunchFileAsync() usage from C++

I'm trying to launch an image using WinRT API WIndows::System::Launcher::LaunchFileAsync().
Code snippet is as follows:
RoInitialize(RO_INIT_MULTITHREADED);
String^ imagePath = ref new String(L"C:\\Users\\GoodMan\\Pictures\\wood.png");
auto file = Storage::StorageFile::GetFileFromPathAsync(imagePath);
Windows::System::Launcher::LaunchFileAsync(file);
I'm getting this error from the LaunchFileAsync() API:
error C2665: 'Windows::System::Launcher::LaunchFileAsync' : none of
the 2 overloads could convert all the argument types
Can I please get help how to solve this. I'm very new to WinRT C++ coding .
The method GetFileFromPathAsync does not return a StorageFile, but it returns IAsyncOperation<StorageFile>^. What you have to do is convert the latter to the former, as follows:
using namespace concurrency;
String^ imagePath = ref new String(L"C:\\Users\\GoodMan\\Pictures\\wood.png");
auto task = create_task(Windows::Storage::StorageFile::GetFileFromPathAsync(imagePath));
task.then([this](Windows::Storage::StorageFile^ file)
{
Windows::System::Launcher::LaunchFileAsync(file);
});
Generally all Windows Store app framework methods that end in Async will return either an IAsyncOperation, or a task. These methods are what are known as asynchronous methods, and require some special handling. See this article for more info: Asynchronous programming in C++ .
So now everything is great, correct? Well, not quite. There is another issue with your code. It is that when you run the code above, you will get an access-denied error. The reason is that Windows Store Apps are sandboxed, and you cannot generally access just any file on the filesystem.
You are in luck, though, because you are trying to access a file in your Pictures folder. The Pictures folder is a special folder that Windows Store apps have access to. You can get at it using the KnownFolders class:
using namespace concurrency;
Windows::Storage::StorageFolder^ pictures =
Windows::Storage::KnownFolders::PicturesLibrary;
auto task = create_task(pictures->GetFileAsync("wood.png"));
task.then([this](Windows::Storage::StorageFile^ file)
{
Windows::System::Launcher::LaunchFileAsync(file);
});
Note that in order to access the Pictures folder your application has to declare it in the project manifest. To do so, double click on the Package.appmanifest file in the project "tree" in Visual Studio, and select the Capabilities tab. Then under Capabilities, check Pictures Library.

Firefox Extension/Addon Binary Component Backward Compatibility

I have been reading up and looking at ways to compile binary components for Firefox extensions. Since Firefox 5 is being released (and 6 & 7 coming up soon) I was wondering if binary components are worth making anymore or just use a standalone executable to run the functionality I want.
I got a sample binary component to compile for Firefox 5 but when I tested it on Firefox 3.6, I get this error:
[Exception... "Could not convert Native argument arg 0 [nsISupports.QueryInterface]" nsresult: "0x8057000a (NS_ERROR_XPC_BAD_CONVERT_NATIVE)"
Running this code
var obj = Components.classes['#example.com/MyComponent;1'].QueryInterface(Components.interfaces.IMyComponent);
And errors at the QueryInterface. Apparently building for Firefox 4 (XULrunner-sdk 2.0 instead of 5.0 will work).
Here is the module code:
#include "mozilla/ModuleUtils.h"
#include "MyComponent.h"
NS_GENERIC_FACTORY_CONSTRUCTOR(MyComponent)
NS_DEFINE_NAMED_CID(MY_COMPONENT_CID);
static const mozilla::Module::CIDEntry kMyComponentCIDs[] = {
{ &kMY_COMPONENT_CID, false, NULL, MyComponentConstructor },
{ NULL }
};
static const mozilla::Module::ContractIDEntry kMyComponentContracts[] = {
{ MY_COMPONENT_CONTRACTID, &kMY_COMPONENT_CID },
{ NULL }
};
static const mozilla::Module kMyComponentModule = {
mozilla::Module::kVersion,
kMyComponentCIDs,
kMyComponentContracts,
NULL
};
NSMODULE_DEFN(NS_MyComponent_Module) = &kMyComponentModule;
NS_IMPL_MOZILLA192_NSGETMODULE(&kMyComponentModule)
I also heard that FF3.6 doesn't need to have the xpt or the dll inside the manifest file.
So basically my question is, for backward compatibility would it be better to make an executable or continue to make binary components? (Since it looks like compiling for FF5, FF3.6 broke.)
Your error message should be due to the XPT file not being recognized correctly (Components.interfaces.IMyComponent is undefined). Maybe that's because it is in the wrong directory - in Firefox 3.6 you don't declare it in the chrome.manifest file, instead it has to be located in the compoments/ directory along with your dll file.
The backwards compatibility story of XPCOM components got a lot worse starting with Firefox 4, see https://developer.mozilla.org/En/Developer_Guide/Interface_Compatibility#Binary_Interfaces. Theoretically, if you want to support multiple Firefox versions you need to put multiple versions of your XPCOM component into your XPI package, that's lots of effort for releases that come out every six weeks. If the point is really calling a few functions from a native library then you should seriously consider switching to js-ctypes. You can also ship a native library (plain, not XPCOM) with your extension and use js-ctypes to call it. Firefox supports js-ctypes starting with version 4 (Gecko 2.0), for Firefox 3.6 you would still need a different solution.

Why do I receive a SIGSEGV signal while using the Aria robotics API?

I am using the Aria C++ programming libs for mobile robots (http://robots.mobilerobots.com/wiki/ARIA). I am new to this API so I wanted to start with a simple action class derived from ArAction. Now I tried to develop a small test program (an ArAction) in order to
control a simulated p3dx robot via MobileSim. Development takes place under Ubuntu 10.10, using gcc 4.4.5. Making (compiling) my code works fine, without errors. I can also set the desired speed for example in my ArAction's fire() method, and the simulation is also working as desired.
But, unfortunately, I can't use the ArRobot object attached to the ArAction I am overriding. The problem is that none of the member functions of the ArRobot object seems to work. For example, calling getVel() or getCompass() always returns a zero value. And when I call the hasFrontBumpers() method the program even crashes with the error message "Aria: Received signal 'SIGSEGV'. Exiting.". As soon as I remove this method call and recompile the error is also gone again...
Here is the relevant code that leads to the crash:
ArActionDesired * forward::fire(ArActionDesired d)
{
desiredState.reset();
ArRobot *r = getRobot();
if(r == NULL)
{
printf("ArRobot = NULL\n");
deactivate();
return &desiredState;
}
printf("ok, ArRobot is not NULL, check for bumpers...\n");
r->hasFrontBumpers(); // <-- this leads to the SIGSEV-based "crash"
return &desiredState;
}
Any ideas what I am missing here -- is it a problem with my coding, or with the simulation environment? Thanks in advance for your help!
Kind regards, Matthias
ok, found it out now -- for the records: the Aria libs in version 2.7.2 are based on gcc-3 and libstdc++ 5, but Ubuntu 10.10 (which I am using) is shipped with gcc-4 and libstdc++ 6 per default. So I had to manually install the older versions of both packages, now my code is running fine...
cheers!
Calling hasFrontBumpers() for a p3dx from the fire() works fine for me on a similar Linux platform. If something is wrong, it is not in this method but in the initialization of the system. A reason for the non-moving robot could be that robot.enableMotors() hasn't been called.