我想使用firefox附件获取一些独特的机器信息。
使用此代码我可以得到名称:
var dns = Cu.components.classes["@mozilla.org/network/dns-service;1"]
.getService(Cu.components.interfaces.nsIDNSService);
var myName = dns.myHostName;
现在我需要NIC信息(如mac地址,适配器名称)。我尝试使用getAdaptersInfo
函数,但这只适用于Windows,我需要一些解决方案跨平台。
有人有想法吗?
这是我的getAdaptersInfo代码:
function getMacAddress(){
const MAX_ADAPTER_NAME_LENGTH = 256;
const MAX_ADAPTER_DESCRIPTION_LENGTH = 128;
const ERROR_BUFFER_OVERFLOW = 111;
const NO_ERROR = 0;
var IP_ADDRESS_STRING = ctypes.StructType('IP_ADDRESS_STRING',[
{'String': ctypes.char}
]);
var IP_ADDR_STRING = ctypes.StructType('IP_ADDR_STRING');
IP_ADDR_STRING.define([
{'Next': IP_ADDR_STRING.ptr},
{'IpAddress': IP_ADDRESS_STRING},
{'IpMask': IP_ADDRESS_STRING},
{'Context': ctypes.long}
]);
var IP_ADAPTER_INFO = ctypes.StructType('IP_ADAPTER_INFO');
const DWORD = ctypes.uint32_t;
IP_ADAPTER_INFO.define([
{'Next': IP_ADAPTER_INFO.ptr},
{'ComboIndex': DWORD},
{'AdapterName': ctypes.char},
{'Description': ctypes.char},
{'AddressLength': ctypes.int32_t},
{'Address': ctypes.uint8_t.array(10).ptr},
{'Index': DWORD},
{'Type': ctypes.uintptr_t},
{'DhcpEnabled': ctypes.uintptr_t},
{'CurrentIpAddress': IP_ADDR_STRING.ptr},
{'IpAddressList': IP_ADDR_STRING},
{'GatewayList' : IP_ADDR_STRING},
{'DhcpServer': IP_ADDR_STRING},
{'HaveWins': ctypes.int32_t},
{'PrimaryWinsServer': IP_ADDR_STRING},
{'SecondaryWinsServer':IP_ADDR_STRING},
{'LeaseObtained': ctypes.uintptr_t},
{'LeaseExpires': ctypes.uintptr_t}
]);
const nomes = [ctypes.libraryName('IPHLPAPI')];
const lib = loadLibrary(nomes);
try{
if(!lib)
return null
console.log("Biblioteca aberta!");
/*DWORD GetAdaptersInfo(
_Out_ PIP_ADAPTER_INFO pAdapterInfo,
_Inout_ PULONG pOutBufLen
);*/
var getAdaptersInfo = lib.declare(
"GetAdaptersInfo",
ctypes.default_abi,
DWORD,
IP_ADAPTER_INFO.ptr,
ctypes.long.ptr);
let buf = (IP_ADAPTER_INFO)();
let pbuf = buf.address();
let ret = ctypes.long(2000);
let pret = ret.address();
let sts = getAdaptersInfo(pbuf,pret);
if(sts == ERROR_BUFFER_OVERFLOW){ //o tamanho do buffer enviado não foi o suficiente.
buf = null;
//agora mando novamente usando o que a lib me retornou.
sts = getAdaptersInfo(pbuf,pret);
}
if(sts != NO_ERROR){ //aqui ocorreu um erro que não conseguiremos resolver ainda.
throw Error("Erro buscando configuracoes do adaptador.");
}
}catch(ex){
console.log("Erro na biblioteca", ex, ex.message);
}finally{
lib.close();
}
}
但是当我运行cfx run时,firefox会崩溃。
答案 0 :(得分:2)
您的代码有效,只需访问 .contents
pbuf
,将下面的代码粘贴到暂存器并将环境设置为浏览器并点击运行。请参阅此处了解如何从暂存器启用浏览器环境:Youtube :: How to Enable Scratchpad Environment - Browser
Cu.import('resource://gre/modules/ctypes.jsm');
function getMacAddress(){
const MAX_ADAPTER_NAME_LENGTH = 256;
const MAX_ADAPTER_DESCRIPTION_LENGTH = 128;
const ERROR_BUFFER_OVERFLOW = 111;
const NO_ERROR = 0;
const MAX_ADAPTER_ADDRESS_LENGTH = 8;
var IP_ADDRESS_STRING = ctypes.StructType('IP_ADDRESS_STRING',[
{'String': ctypes.char.array(4 * 4)}
]);
const DWORD = ctypes.uint32_t;
var IP_ADDR_STRING = ctypes.StructType('IP_ADDR_STRING');
IP_ADDR_STRING.define([
{'Next': IP_ADDR_STRING.ptr},
{'IpAddress': IP_ADDRESS_STRING},
{'IpMask': IP_ADDRESS_STRING},
{'Context': DWORD}
]);
var PIP_ADDR_STRING = IP_ADDR_STRING.ptr;
var time_t = ctypes.long; // based on this github search https://github.com/search?utf8=%E2%9C%93&q=time_t+ctypes&type=Code&ref=searchresults AND based on this answer here: http://stackoverflow.com/a/471287/1828637
var IP_ADAPTER_INFO = ctypes.StructType('IP_ADAPTER_INFO');
IP_ADAPTER_INFO.define([ // have to use .define because one of the fields "Next" is a ptr to itself
{'Next': IP_ADAPTER_INFO.ptr},
{'ComboIndex': DWORD},
{'AdapterName': ctypes.char.array(MAX_ADAPTER_NAME_LENGTH + 4)},
{'Description': ctypes.char.array(MAX_ADAPTER_DESCRIPTION_LENGTH + 4)},
{'AddressLength': ctypes.unsigned_int},
{'Address': ctypes.unsigned_char.array(MAX_ADAPTER_ADDRESS_LENGTH)}, // BYTE is ctypes.unsigned_char
{'Index': DWORD},
{'Type': ctypes.unsigned_int},
{'DhcpEnabled': ctypes.unsigned_int},
{'CurrentIpAddress': PIP_ADDR_STRING},
{'IpAddressList': IP_ADDR_STRING},
{'GatewayList' : IP_ADDR_STRING},
{'DhcpServer': IP_ADDR_STRING},
{'HaveWins': ctypes.bool},
{'PrimaryWinsServer': IP_ADDR_STRING},
{'SecondaryWinsServer':IP_ADDR_STRING},
{'LeaseObtained': time_t},
{'LeaseExpires': time_t}
])
const lib = ctypes.open(ctypes.libraryName('IPHLPAPI'));
try{
if(!lib)
return null
console.log("Biblioteca aberta!");
/*DWORD GetAdaptersInfo(
_Out_ PIP_ADAPTER_INFO pAdapterInfo,
_Inout_ PULONG pOutBufLen
);*/
var getAdaptersInfo = lib.declare(
"GetAdaptersInfo",
ctypes.default_abi,
DWORD,
IP_ADAPTER_INFO.ptr,
ctypes.long.ptr);
let buf = (IP_ADAPTER_INFO)();
let pbuf = buf.address();
let ret = ctypes.long(2000);
let pret = ret.address();
let sts = getAdaptersInfo(pbuf,pret);
if(sts == ERROR_BUFFER_OVERFLOW){ //o tamanho do buffer enviado não foi o suficiente.
buf = null;
//agora mando novamente usando o que a lib me retornou.
sts = getAdaptersInfo(pbuf,pret);
} else {
console.log('got it', pbuf.contents.toString());
}
if(sts != NO_ERROR){ //aqui ocorreu um erro que não conseguiremos resolver ainda.
throw Error("Erro buscando configuracoes do adaptador.");
}
}catch(ex){
console.log("Erro na biblioteca", ex, ex.message);
}finally{
lib.close();
}
}
getMacAddress();
击> <击> 撞击>
答案 1 :(得分:1)
好的,现在这可行:)问题是我告诉函数接受结构列表,将其定义为IP_ADAPTER_INFO.ptr.array()
然后我创建了一个像let pbuf = IP_ADAPTER_INFO.ptr.array(1)()
这样的结构数组但是这样做崩溃,当我们增加到2或更多的大小时,它崩溃得更快。所以我更改为在函数IP_ADAPTER_INFO.ptr
中声明它,然后我创建了一个像let pbuv = IP_ADAPTER_INFO.array(?)
这样的结构数组,其中?
可以是任何数字,它可以正常工作:)
Cu.import('resource://gre/modules/ctypes.jsm');
function getMacAddress(){
var MAX_ADAPTER_NAME_LENGTH = 256;
var MAX_ADAPTER_DESCRIPTION_LENGTH = 128;
var ERROR_BUFFER_OVERFLOW = 111;
var NO_ERROR = 0;
var MAX_ADAPTER_ADDRESS_LENGTH = 8;
var IP_ADDRESS_STRING = ctypes.StructType('IP_ADDRESS_STRING',[
{'String': ctypes.char.array(4 * 4)}
]);
var IP_MASK_STRING = ctypes.StructType('IP_MASK_STRING',[
{'String': ctypes.char.array(4 * 4)}
]);
var DWORD = ctypes.unsigned_long;
var IP_ADDR_STRING = ctypes.StructType('IP_ADDR_STRING');
IP_ADDR_STRING.define([
{'Next': IP_ADDR_STRING.ptr},
{'IpAddress': IP_ADDRESS_STRING},
{'IpMask': IP_MASK_STRING},
{'Context': DWORD}
]);
var PIP_ADDR_STRING = IP_ADDR_STRING.ptr;
var time_t = ctypes.long; // based on this github search https://github.com/search?utf8=%E2%9C%93&q=time_t+ctypes&type=Code&ref=searchresults AND based on this answer here: http://stackoverflow.com/a/471287/1828637
var IP_ADAPTER_INFO = ctypes.StructType('IP_ADAPTER_INFO');
IP_ADAPTER_INFO.define([ // have to use .define because one of the fields "Next" is a ptr to itself
{'Next': IP_ADAPTER_INFO.ptr},
{'ComboIndex': DWORD},
{'AdapterName': ctypes.char.array(MAX_ADAPTER_NAME_LENGTH + 4)},
{'Description': ctypes.char.array(MAX_ADAPTER_DESCRIPTION_LENGTH + 4)},
{'AddressLength': ctypes.unsigned_int},
{'Address': ctypes.unsigned_char.array(MAX_ADAPTER_ADDRESS_LENGTH)}, // BYTE is ctypes.unsigned_char
{'Index': DWORD},
{'Type': ctypes.unsigned_int},
{'DhcpEnabled': ctypes.unsigned_int},
{'CurrentIpAddress': PIP_ADDR_STRING},
{'IpAddressList': IP_ADDR_STRING},
{'GatewayList' : IP_ADDR_STRING},
{'DhcpServer': IP_ADDR_STRING},
{'HaveWins': ctypes.bool},
{'PrimaryWinsServer': IP_ADDR_STRING},
{'SecondaryWinsServer':IP_ADDR_STRING},
{'LeaseObtained': time_t},
{'LeaseExpires': time_t}
]);
var lib = ctypes.open(ctypes.libraryName('IPHLPAPI'));
try{
if(!lib)
return null
console.log("Biblioteca aberta!");
/*DWORD GetAdaptersInfo(
_Out_ PIP_ADAPTER_INFO pAdapterInfo,
_Inout_ PULONG pOutBufLen
);*/
var getAdaptersInfo = lib.declare("GetAdaptersInfo", ctypes.winapi_abi,
DWORD,
IP_ADAPTER_INFO.array(),
ctypes.unsigned_long.ptr
);
let pbuf = IP_ADAPTER_INFO.array(0)();
console.info('pbuf.length:', pbuf, pbuf.length, 'IP_ADAPTER_INFO.size:', IP_ADAPTER_INFO.size, 'pbuf size:', pbuf.length * IP_ADAPTER_INFO.size);
let ret = ctypes.unsigned_long(pbuf.length * IP_ADAPTER_INFO.size);
let sts = getAdaptersInfo(pbuf, ret.address()); // initial fetch to get size needed
console.info('sts:', ctypes.UInt64.lo(sts));
console.info('sts:', sts, sts.toString(), uneval(sts));
console.info('ret:', ret, ret.toString(), uneval(ret));
if(sts == ERROR_BUFFER_OVERFLOW){ //o tamanho do buffer enviado não foi o suficiente.
// ret is defined as unsigned_long which is always a UInt64 in jsctypes `CData { value: UInt64 } `
var ret_jsInt = parseInt(ret.value.toString());
console.info('ret_jsInt:', ret_jsInt);
var neededLength = Math.round(ret_jsInt / IP_ADAPTER_INFO.size);
pbuf = IP_ADAPTER_INFO.array(neededLength)();
console.info('pbuf RE-size:', pbuf.length * IP_ADAPTER_INFO.size);
if (pbuf.length * IP_ADAPTER_INFO.size != ret_jsInt) {
throw new Error('winapi says the size needed is ' + ret_jsInt + ' and i calculated the length by dividing the ID_ADAPTER_INFO.size which is ' + ID_ADAPTER_INFO.size + ' so the needed length was ' + neededLength + ' but the size of this list of neededLength DOES NOT match what winapi says it needs, the size of the neededLength resized list is ' + (pbuf.length * IP_ADAPTER_INFO.size));
}
//agora mando novamente usando o que a lib me retornou.
console.error('going for 2nd time');
sts = getAdaptersInfo(pbuf, ret.address()); // we just pass same ret, as it was updated to the right size // crashing here!!!
if (sts != NO_ERROR) {
throw new Error('after 2nd fetch it still failed, now i need to add more error handling here, error was: ' + sts.toString());
} else {
console.info('succesfully obtained after 2nd time:', pbuf.toString());
for (var i=0; i<pbuf.length; i++) {
console.log(i, pbuf[i].addressOfField('AdapterName').contents.readString(), pbuf[i].addressOfField('IpAddressList').contents.IpAddress.String.readString(), pbuf[i].addressOfField('Description').contents.readString());
}
}
} else {
console.error('this should never happen! i passed 0 size into it it should always overflow!! unless there is no adapater info but there has to be!!');
}
/*
if(sts != NO_ERROR){ //aqui ocorreu um erro que não conseguiremos resolver ainda.
throw Error("Erro buscando configuracoes do adaptador.");
}
*/
}catch(ex){
console.log("Erro na biblioteca", ex, ex.message);
}finally{
lib.close();
}
}
getMacAddress();
哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇
我有一个问题,因为 从不介意我修复了我所做的问题IP_ADAPTER_INFO
回来说需要的大小是2560.但我们的ret
结构的大小是132.所以2560/132 = 19.333所以我们的结构是错误的,我们必须弄明白。IP_ADAPTER_INFO
而非ctypes.char.array(4*4).ptr
所以我知道我们需要传递一个IP_ADAPTER_INFO数组:https://github.com/manimaul/Matrix-Mariner-GPS/blob/8989621dfda0e291820a37096d582cc1f355e346/src/getIPwin.py#L45
这是我的工作,所以现在的问题是它在第二次获取后崩溃。我们需要解决这个问题。
编辑:
好吧,老兄,这肯定是在正确的轨道上,它现在崩溃在所有系统上的第二次获取,win7和win81(我没有尝试xp,但我确定它会),我们必须弄清楚为什么它在地球上崩溃。如果你注释掉第二个ctypes.char.array(4*4)
它不会崩溃,我们必须弄明白它困扰我哈哈
sts = getAdapters...