4

I want to access smart card through winscard.dll by a chrome extension.

I am new in Chrome extension developing, however as I know a chrome extension in the unpacked mode is a folder consist of some html pages (background, ordinary, optinal, override, tabs.create/window.open and so on) and javaScript files (content script and other files) which communicating with each other. These various files make me confused and need step by step guiding.

In the firs step, how can I call a C++ dll from chrome browser extension?

Already I did this in Firefox add-on using js-ctypes. Is it similar to Firefox approach?

One approach which explain in How to call exported function in a DLL(written using C), from chrome extensions provide calling dll through adding the following code to manifest.json:

"plugins": [{ "path": "FRViewPortExtn.dll", "public": true },], ...

However I think due to deprecating plugin NPAPI in chrome, it is not applicable anymore.

Another approach is using Native Messaging which introduce in https://developer.chrome.com/extensions/nativeMessaging . I study the example of this tutorial page and found that it does forced clients to use a bat file (or executable file).

Also as mentioned in comments a similar question asked in Loading dll from Chrome extension However the answer only recommend using native messaging without any sample code which indicate calling a dll and using a function of this dll

Community
  • 1
  • 1
Hosein Aqajani
  • 1,553
  • 4
  • 26
  • 46
  • I guess the only choice is [nativeMessaging](https://developer.chrome.com/extensions/nativeMessaging). – wOxxOm Nov 08 '15 at 12:43
  • also look at the official extensions docs to clear confusion about all that. question is too broad. try something in the docs then let us know what's not working. theres a whole section dedicated to messaging. – Zig Mandel Nov 08 '15 at 13:41
  • As @wOxxOm said, it seems one and only solution is to use native client. in [here](https://developer.chrome.com/native-client) they have mentioned that extensions can invoke these without prompting. I haven't tried it but looks like achievable, have a shot. – Ruwanka De Silva Nov 08 '15 at 13:57
  • This is an exact duplicate of http://stackoverflow.com/questions/21163880/loading-dll-from-chrome-extension – smorgan Nov 09 '15 at 02:13
  • Dear @smorgan you right, however your answer in that question is too general and only you mentioned to the name of `Native Messaging` approach. Providing a sample code would be so useful for chrome beginner like me. Thanks – Hosein Aqajani Nov 09 '15 at 05:38
  • 1
    You shouldn't ask duplicate questions hoping for different/better answers. If you are stuck on the details, rather than the general technique you need to use, then submit a new question that shows what you tried with native messaging, where you got stuck, and asks a specific question about how to proceed. – smorgan Nov 11 '15 at 00:43

2 Answers2

4

We must create two folders called app and host. The extension is the app folder while connection with a executable file is provided in the host folder.

main.html in the app folder :

<html>
  <head>
    <script src='./main.js'></script>
  </head>
  <body>
    <button id='connect-button'>Connect</button>
    <input id='input-text' type='text' />
    <button id='send-message-button'>Send</button>
    <div id='response'></div>
  </body>
</html>

main.js in the app folder :

var port = null;

var getKeys = function(obj){
   var keys = [];
   for(var key in obj){
      keys.push(key);
   }
   return keys;
}


function appendMessage(text) {
  document.getElementById('response').innerHTML += "<p>" + text + "</p>";
}

function updateUiState() {
  if (port) {
    document.getElementById('connect-button').style.display = 'none';
    document.getElementById('input-text').style.display = 'block';
    document.getElementById('send-message-button').style.display = 'block';
  } else {
    document.getElementById('connect-button').style.display = 'block';
    document.getElementById('input-text').style.display = 'none';
    document.getElementById('send-message-button').style.display = 'none';
  }
}

function sendNativeMessage() {
  message = {"text": document.getElementById('input-text').value};
  port.postMessage(message);
  appendMessage("Sent message: <b>" + JSON.stringify(message) + "</b>");
}

function onNativeMessage(message) {
  appendMessage("Received message: <b>" + JSON.stringify(message) + "</b>");
}

function  onDisconnected() {
  appendMessage("Failed to connect: " + chrome.runtime.lastError.message);
  port = null;
  updateUiState();
}

function connect() {
  var hostName = "com.google.chrome.example.echo";
  appendMessage("Connecting to native messaging host <b>" + hostName + "</b>")
  port = chrome.runtime.connectNative(hostName);
  port.onMessage.addListener(onNativeMessage);
  port.onDisconnect.addListener(onDisconnected);
  updateUiState();
}

document.addEventListener('DOMContentLoaded', function () {
  document.getElementById('connect-button').addEventListener(
      'click', connect);
  document.getElementById('send-message-button').addEventListener(
      'click', sendNativeMessage);
  updateUiState();
});

window.onbeforeunload= function (e)
{
 message = {"text": "terminate"};
  port.postMessage(message);
   appendMessage("Sent message: <b>" + JSON.stringify(message) + "</b>");
};

manifest.json in the app folder :

{
  // Extension ID: knldjmfmopnpolahpmmgbagdohdnhkik
  "key": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzcp66xi1ctUL0HvndH7IyjNw2CM9TdOMx8XPv0GbQXFmzm3xnqwQkbRYyfNoYN+pIIY0/TRu7qYOAnb0sogEqQRU73sbSAJajPbCxxBTVFueTypQtBpN5uuV/Z/Ox4myMiRVqcfLxDaVLFkVa3f9OGMhWJclDa74eIrwqc81GJQM8TG0JvZMSwE3u8FzH+d8U+x2p/f7a4546BNpP9Ssv2Jc/kE2KV5DIQS++8rg04aHnW3TZX2aUd1Bz+c416hmqxEb4iARGXhg7iURh6KIe9+490imIcXaedhUwWRiqnuJ3Kbkzl/iOSUI2XzIOHxGnkAGmLf9tfsrhKLcwtvvqQIDAQAB",
  "name": "Native Messaging Example",
  "version": "1.0",
  "manifest_version": 2,
  "description": "Send a message to a native application.",
  "app": {
    "launch": {
      "local_path": "main.html"
    }
  },
  "icons": {
    "128": "icon-128.png"
  },
  "permissions": [
    "nativeMessaging"
  ],
  "background":{
     "scripts":["main.js"],
     "persistent": true
     }
}

com.google.chrome.example.echo-win.json file in the host folder :

{
  "name": "com.google.chrome.example.echo",
  "description": "Chrome Native Messaging API Example Host",
  "path": "nativeMessaging.exe",
  "type": "stdio",
  "allowed_origins": [
    "chrome-extension://bcffeaabpankpgikpifpailfcihmheno/"
  ]
}

install_host.bat in the host folder :

REG ADD "HKCU\Software\Google\Chrome\NativeMessagingHosts\com.google.chrome.example.echo" /ve /t REG_SZ /d "%~dp0com.google.chrome.example.echo-win.json" /f

Also, nativeMessaging.exe and its required dlls could be exist in the host folder

After providing these two folders you should run the batch file in the host folder to register the json file in the registry. Finally, you should upload the extension folder (app folder) through chrome browser (Settings -> Extensions -> Load unpacked extension).

Hosein Aqajani
  • 1,553
  • 4
  • 26
  • 46
2

You could use Native Messaging, as for sample code, you could check this answer for more details, it uses C# as server side, which you could easily convert to C/C++ or just import a dll to C# project.

Community
  • 1
  • 1
Haibara Ai
  • 10,703
  • 2
  • 31
  • 47