Skip to content

Commit

Permalink
add extension
Browse files Browse the repository at this point in the history
  • Loading branch information
gniezen committed Mar 5, 2024
1 parent 75df78e commit f1866a0
Show file tree
Hide file tree
Showing 6 changed files with 275 additions and 0 deletions.
51 changes: 51 additions & 0 deletions extension/background.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@

let reply;
let port;

function connect() {
const hostName = 'org.tidepool.uploader';
console.log('Connecting to native messaging host', hostName);
port = chrome.runtime.connectNative(hostName);
port.onMessage.addListener(onNativeMessage);
port.onDisconnect.addListener(onDisconnected);
}

function sendNativeMessage(message) {
port.postMessage(message);
//port.postMessage('\n');
console.log('Sent message:', JSON.stringify(message));
}

function onNativeMessage(message) {
if (message.msgType == 'info') {
console.log(message.details);
} else {
reply(message);
}
}

function onDisconnected() {
console.log('Disconnected: ' + chrome.runtime.lastError.message);
port = null;
reply({ msgType: 'error', details: 'Disconnected: ' + chrome.runtime.lastError.message });
}

chrome.runtime.onMessageExternal.addListener(
function(request, sender, sendResponse) {
console.log("Received message from the web page:", request);

if (request.command == "openDevice") {
connect();
}

// Process the request here
if (port) {
sendNativeMessage(request);

reply = sendResponse;
return true; // indicates you will asynchronously use sendResponse
} else {
sendResponse({ msgType: 'error', details: 'Not connected.'});
}
}
);
Binary file added extension/icon-128.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
19 changes: 19 additions & 0 deletions extension/manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"manifest_version": 3,
"key": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDcBHwzDvyBQ6bDppkIs9MP4ksKqCMyXQ/A52JivHZKh4YO/9vJsT3oaYhSpDCE9RPocOEQvwsHsFReW2nUEc6OLLyoCFFxIb7KkLGsmfakkut/fFdNJYh0xOTbSN8YvLWcqph09XAY2Y/f0AL7vfO1cuCqtkMt8hFrBGWxDdf9CQIDAQAB",
"name": "Native Messaging Example",
"version": "1.0",
"description": "Send a message to a native application.",
"icons": {
"128": "icon-128.png"
},
"permissions": [
"nativeMessaging"
],
"background": {
"service_worker": "background.js"
},
"externally_connectable": {
"matches": ["http://localhost:3005/*"]
}
}
3 changes: 3 additions & 0 deletions extension/verio-helper/helper.reg
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Windows Registry Editor Version 5.00
[HKEY_CURRENT_USER\Software\Google\Chrome\NativeMessagingHosts\org.tidepool.uploader]
@="C:\\Users\\gerri\\sandbox\\manifest.json"
193 changes: 193 additions & 0 deletions extension/verio-helper/helper.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
const std = @import("std");
const windows = @import("std").os.windows;
const W = std.unicode.utf8ToUtf16LeStringLiteral;
const Allocator = std.mem.allocator;

const OpenError = error {
InvalidHandle,
LockFailed,
ReadFailed,
};

fn openDevice() !windows.HANDLE {
const devicePath = "\\\\.\\E:"; // Change C: to your target volume
const FSCTL_LOCK_VOLUME = 0x00090018;

// Open the volume
const handle = windows.kernel32.CreateFileW(
W(devicePath),
windows.GENERIC_READ | windows.GENERIC_WRITE,
windows.FILE_SHARE_READ | windows.FILE_SHARE_WRITE,
null,
windows.OPEN_EXISTING,
windows.FILE_FLAG_NO_BUFFERING,
null);

if (handle == windows.INVALID_HANDLE_VALUE) {
try sendReply("error", "Failed to open file");
return OpenError.InvalidHandle;
}

// Lock the volume
windows.DeviceIoControl(
handle,
FSCTL_LOCK_VOLUME,
null,
null,
) catch {
try sendReply("error", "Failed to lock volume");
windows.CloseHandle(handle);
return OpenError.LockFailed;
};

try sendReply("success", "Volume locked successfully");

return handle;
}

fn checkDevice(handle: windows.HANDLE) !void {
const allocator = std.heap.page_allocator;
const alignment = 4096;
const size = 512;

const buffer = try allocator.alignedAlloc(u8, alignment, size);
defer allocator.free(buffer);

@memset(buffer, 0);

try sendReply("info", "Reading from volume..");

var bytesRead: windows.DWORD = 0;
const readSuccess = windows.kernel32.ReadFile(handle, buffer.ptr, size, &bytesRead, null);
if (readSuccess == 0) {
try sendReply("error", "Failed to read from volume");
return OpenError.ReadFailed;
}

var gpa = std.heap.GeneralPurposeAllocator(.{}){};
const printAllocator = gpa.allocator();

const slice = try std.fmt.allocPrint(printAllocator, "Read {d} bytes from volume.", .{bytesRead});
defer printAllocator.free(slice);
try sendReply("info", slice);
try sendReply("data", buffer[0x2b..0x3b]);
}

fn retrieveData(seekOffset: u64, linkLayerFrame: []const u8, handle: windows.HANDLE ) !void {
const allocator = std.heap.page_allocator;
const alignment = 4096;
const size = 512;

var gpa = std.heap.GeneralPurposeAllocator(.{}){};
const printAllocator = gpa.allocator();

const buffer = try allocator.alignedAlloc(u8, alignment, size);
defer allocator.free(buffer);

@memset(buffer, 0);
@memcpy(buffer[0..linkLayerFrame.len], linkLayerFrame);

try sendReply("info", "Sending request");

_ = try windows.WriteFile(handle, buffer, seekOffset);

@memset(buffer, 0);

const bytesRead = try windows.ReadFile(handle, buffer, seekOffset);

const slice = try std.fmt.allocPrint(printAllocator, "Read {d} bytes from volume.", .{bytesRead});
defer printAllocator.free(slice);
try sendReply("info", slice);
try sendReply("data", buffer);
}

pub fn main() !void {

const stdin = std.io.getStdIn().reader();
var buffer: [4096]u8 = undefined;
var handle: windows.HANDLE = undefined;

var gpa = std.heap.GeneralPurposeAllocator(.{}){};
const allocator = gpa.allocator();

const Message = struct {
command: []u8,
request: [512]u8 = undefined,
seekOffset: u64 = 0,
};

while (true) {

// Read the length of the incoming message
_ = try stdin.read(&buffer);

const length = std.mem.readInt(u32, buffer[0..4], .little);

// Read the message based on the length
const message = std.mem.bytesAsSlice(u8, buffer[4..(length+4)]);

const parsed = try std.json.parseFromSlice(
Message,
allocator,
message,
.{},
);

const data = parsed.value;

if (std.mem.eql(u8, data.command, "openDevice")) {
try sendReply("info", "Trying to open device");
handle = try openDevice();
}

if (std.mem.eql(u8, data.command, "checkDevice")) {
try sendReply("info", "Checking device");
try checkDevice(handle);
}

if (std.mem.eql(u8, data.command, "retrieveData")) {
try sendReply("info", "Retrieving data");
try retrieveData(data.seekOffset, &data.request, handle);
}

if (std.mem.eql(u8, data.command, "closeDevice")) {
try sendReply("info", "Closing device");
break;
}

parsed.deinit();
}

// exit gracefully
windows.CloseHandle(handle);
std.os.exit(0);
}



fn sendReply(msgtype: []const u8, result: []const u8) !void {
const stdout = std.io.getStdOut().writer();

var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit();
const allocator = gpa.allocator();
var string = std.ArrayList(u8).init(allocator);

const Reply = struct {
msgType: []const u8,
details: []const u8,
};

const x = Reply{
.msgType = msgtype,
.details = result,
};

try std.json.stringify(x, .{}, string.writer());
const response = try string.toOwnedSlice();

var response_length: [4]u8 = undefined;
std.mem.writeInt(u32, &response_length, @intCast(response.len), .little);
_ = try stdout.write(&response_length);
_ = try stdout.writeAll(response);
}
9 changes: 9 additions & 0 deletions extension/verio-helper/manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"name": "org.tidepool.uploader",
"description": "Tidepool Uploader",
"path": "C:\\Users\\gerri\\sandbox\\native-msg.exe",
"type": "stdio",
"allowed_origins": [
"chrome-extension://knldjmfmopnpolahpmmgbagdohdnhkik/"
]
}

0 comments on commit f1866a0

Please sign in to comment.