getAdaptersInfo 与 firefox 附加组件
getAdaptersInfo with firefox add-on
我想使用 firefox 插件获取一些独特的 machine 信息。
用这段代码我可以得到名字:
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 运行 时 firefox 崩溃了。
忽略这个解决方案,这是非常错误的 - 请参阅我的第二个解决方案,它现在正在进行中
您的代码有效,只需访问 pbuf
的 .contents
,将下面的代码复制粘贴到暂存器并将环境设置为浏览器并点击 运行 .请参阅此处了解如何从暂存器启用浏览器环境: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:
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();
好的,现在可以了 :) 问题是我告诉函数通过将其定义为 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:
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_LIST.ptr.array() 来告诉函数接受数组,但我不得不将其更改为 IP_ADAPTER_LIST.ptr如上所示
哇,老兄,我正在看更多,看起来它需要一个 IP_ADAPTER_INFO
数组,这样做不会在 Win7
上崩溃
不过我有一个问题,因为 ret
回来说所需的大小是 2560。但是我们的 IP_ADAPTER_INFO
结构的大小是 132。所以 2560/132 = 19.333 所以我们的结构出了点问题,我们必须弄清楚。 没关系,我解决了我曾尝试做的问题 ctypes.char.array(4*4).ptr
而不仅仅是 ctypes.char.array(4*4)
所以这是我发现我们需要传递一个 IP_ADAPTER_INFO 数组的地方:https://github.com/manimaul/Matrix-Mariner-GPS/blob/8989621dfda0e291820a37096d582cc1f355e346/src/getIPwin.py#L45
这是我的作品,所以现在的问题是它在第二次获取后崩溃了。我们需要解决这个问题。
编辑:
好的,伙计,这绝对是在正确的轨道上,它现在在所有系统上的第二次获取时崩溃,win7 和 win81(我没有尝试 xp,但我相信它会),我们必须弄清楚它到底为什么会崩溃。如果你注释掉第二个 sts = getAdapters...
它不会崩溃,我们必须解决这个问题 哈哈
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:
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.array(),
ctypes.unsigned_long.ptr);
let pbuf = IP_ADAPTER_INFO.ptr.array(1)();
console.info('pbuf.length:', 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:', sts.toString(), 'ret:', ret.toString());
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 = ret_jsInt / IP_ADAPTER_INFO.size;
pbuf = IP_ADAPTER_INFO.ptr.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:');
}
} 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();
我想使用 firefox 插件获取一些独特的 machine 信息。
用这段代码我可以得到名字:
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 运行 时 firefox 崩溃了。
忽略这个解决方案,这是非常错误的 - 请参阅我的第二个解决方案,它现在正在进行中
您的代码有效,只需访问 pbuf
的 .contents
,将下面的代码复制粘贴到暂存器并将环境设置为浏览器并点击 运行 .请参阅此处了解如何从暂存器启用浏览器环境: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:
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();
好的,现在可以了 :) 问题是我告诉函数通过将其定义为 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:
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_LIST.ptr.array() 来告诉函数接受数组,但我不得不将其更改为 IP_ADAPTER_LIST.ptr如上所示
哇,老兄,我正在看更多,看起来它需要一个 IP_ADAPTER_INFO
数组,这样做不会在 Win7
不过我有一个问题,因为 没关系,我解决了我曾尝试做的问题 ret
回来说所需的大小是 2560。但是我们的 IP_ADAPTER_INFO
结构的大小是 132。所以 2560/132 = 19.333 所以我们的结构出了点问题,我们必须弄清楚。ctypes.char.array(4*4).ptr
而不仅仅是 ctypes.char.array(4*4)
所以这是我发现我们需要传递一个 IP_ADAPTER_INFO 数组的地方:https://github.com/manimaul/Matrix-Mariner-GPS/blob/8989621dfda0e291820a37096d582cc1f355e346/src/getIPwin.py#L45
这是我的作品,所以现在的问题是它在第二次获取后崩溃了。我们需要解决这个问题。
编辑:
好的,伙计,这绝对是在正确的轨道上,它现在在所有系统上的第二次获取时崩溃,win7 和 win81(我没有尝试 xp,但我相信它会),我们必须弄清楚它到底为什么会崩溃。如果你注释掉第二个 sts = getAdapters...
它不会崩溃,我们必须解决这个问题 哈哈
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:
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.array(),
ctypes.unsigned_long.ptr);
let pbuf = IP_ADAPTER_INFO.ptr.array(1)();
console.info('pbuf.length:', 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:', sts.toString(), 'ret:', ret.toString());
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 = ret_jsInt / IP_ADAPTER_INFO.size;
pbuf = IP_ADAPTER_INFO.ptr.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:');
}
} 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();