从SMBIOS中检索信息 - 页 5

 

在mt4中出现问题,在mt5中工作正常


 
Vitaly Muzichenko:

在mt4中出现问题,在mt5中工作正常

明白了。

该函数参数为

uint    GetSystemFirmwareTable(uint firmware_table_provider_signature,uint firmware_table_id,PVOID firmware_table_buffer,uint buffer_size);

我检查了PVOID 是什么。

由于某种原因,我把这种类型的产品标记为长

我把它改成了Uchar,它就工作了

 

最后的代码如下

//+------------------------------------------------------------------+
//|                                                      ProjectName |
//|                                      Copyright 2020, CompanyName |
//|                                       http://www.companyname.net |
//+------------------------------------------------------------------+
#property version   "1.0"
#property strict
#property copyright "(c)2021 Edgar Akhmadeev"
#property link      "https://www.mql5.com/en/users/dali"
// 2021.03.23

#import "kernel32.dll"
uint GetSystemFirmwareTable(uint firmware_table_provider_signature,uint firmware_table_id,uchar firmware_table_buffer,uint buffer_size);
uint GetSystemFirmwareTable(uint firmware_table_provider_signature,uint firmware_table_id,uchar &firmware_table_buffer[],uint buffer_size);
#import

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
union UUID16 {
   uchar b[16];
};
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
class SMBIOS
{
private:
   static UUID16     uuid;

public:
   static string     Read();
};
static UUID16  SMBIOS::uuid;

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
static string SMBIOS::Read()
{
   const uint SMBIOS_signature = ('R' << 24) + ('S' << 16) + ('M' << 8) + 'B';
// Query size of SMBIOS info.
   uint size = GetSystemFirmwareTable(SMBIOS_signature, 0, NULL, 0);
// Allocate memory for SMBIOS info
   uchar data[];
   if (ArrayResize(data, size) <= 0)
      return NULL;
// Retrieve the SMBIOS table
   uint written = GetSystemFirmwareTable(SMBIOS_signature, 0, data, size);
   if (written != size)
      return NULL;
   uint idx = 0;
   idx += 8;
// Process the SMBIOS info
   string sUUID;
   while (idx < size) {
      uchar type = data[idx];
      uchar len = data[idx + 1];
      if (len < 4)
         break;
      if (type == 1 && len >= 25) {
         idx += 8;   // offset to UUID
         // check if there is a valid UUID (not all 0x00 or all 0xff)
         bool all_zero = true, all_one = true;
         for (int i = 0; i < 16 && (all_zero || all_one); i++) {
            if (data[idx + i] != 0x00)
               all_zero = false;
            if (data[idx + i] != 0xFF)
               all_one = false;
         }
         if (!all_zero && !all_one) {
            uint idx2 = 0;
            // As off version 2.6 of the SMBIOS specification, the first 3 fields of the UUID are supposed to be encoded on little-endian. (para 7.2.1)
            sUUID  = StringFormat("%02x", uuid.b[idx2++] = data[idx + 3]);
            sUUID += StringFormat("%02x", uuid.b[idx2++] = data[idx + 2]);
            sUUID += StringFormat("%02x", uuid.b[idx2++] = data[idx + 1]);
            sUUID += StringFormat("%02x", uuid.b[idx2++] = data[idx + 0]);
            sUUID += "-";
            sUUID += StringFormat("%02x", uuid.b[idx2++] = data[idx + 5]);
            sUUID += StringFormat("%02x", uuid.b[idx2++] = data[idx + 4]);
            sUUID += "-";
            sUUID += StringFormat("%02x", uuid.b[idx2++] = data[idx + 7]);
            sUUID += StringFormat("%02x", uuid.b[idx2++] = data[idx + 6]);
            sUUID += "-";
            for (int i = 8; i < 10; i++)
               sUUID += StringFormat("%02x", uuid.b[idx2++] = data[idx + i]);
            sUUID += "-";
            for (int i = 10; i < 16; i++)
               sUUID += StringFormat("%02x", uuid.b[idx2++] = data[idx + i]);
         }
         return sUUID;
      } else
         idx += len;    // Skip formatted area
      do {
         int i = 0;
         while (idx + i < size && data[idx + i] != 0)
            ++i;
         idx += i + 1;
      } while (data[idx] != 0);
      ++idx;
   }
   return sUUID;
}

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnStart()
{
   string uuid = SMBIOS::Read();
   if (uuid == NULL) {
      Print("Error reading SMBIOS data!");
      return;
   }
   Print("UUID: ", uuid);
}
//+------------------------------------------------------------------+

---

@Edgar Akhmadeev,非常感谢你!

 
Vitaly Muzichenko:

最后的代码如下

---

@Edgar Akhmadeev,非常感谢你!

利用好它。
在几个小时内用c++和MS文档写了几个例子,在实验室的论坛成员上测试了一下。
这样的快闪族。我自己不打算使用它们。
 
Edgar Akhmadeev:

编写代码,从SMBIOS读取硬件信息(主板和平台)。当然,使用的是WinAPI。可用于将产品与硬件绑定。在我看来,与主板以外的任何东西绑定都没有意义。驱动器、显卡是可变的。

问候!

在大约50台机器上收集了一些少量的统计数据。

结果发现,UUID在几台机器上可能是一样的,这让人非常沮丧为什么会出现这种情况呢?

也就是说,更多的时候,即在6台机器和我的第7台机器上,数字与 "03000200-0400-0500-0006-000700080009 "相符。

我也会试着收集关于C盘分区号的统计数据,尽管它很容易被实用程序改变,所以特别不适合作为一个约束。

 
中国人很调皮。
 

在这种情况下,我看不出有什么可靠的出路。我们只能庆幸,50人中有7人符合。

除了主板UUID外,没有其他可靠的条目。其他的要么是可选的(如序列号),要么是在格式化、重装Windows或小规模升级时容易被换掉或改变。

除非与硬件钥匙相联系,但这也太过分了。只对价值数千美元的软件有利。

 
Edgar Akhmadeev:

在这种情况下,我看不出有什么可靠的出路。我们只能庆幸,50人中有7人符合。

除了主板UUID外,没有其他可靠的条目。其他的要么是可选的(如序列号),要么是在格式化、重装Windows或小规模升级时容易被换掉或改变。

除非与硬件钥匙相联系,但这也太过分了。这只对价值数千美元的软件有好处。

我的逻辑是这样的:如果你拿了一个样本程序,它就会记住硬件,你就不能再拿。现在事实证明,如果科里亚拿了一份校样,我们其他人就没戏了。所以我的快乐已经结束了。

我现在看到的唯一出路是与C盘进行绑定

 
Vitaly Muzichenko:

我的逻辑是这样的:如果你取了一个软件样本,它就会记住铁,你就不能再取。现在事实证明,如果科里亚接受了审判,那么我们其他人就出局了。所以我的快乐已经结束了。

我看到现在唯一的出路是与C盘绑定。

我不明白其他的人是怎么回事。

 
Vitaly Muzichenko:

我的逻辑是这样的:如果你取了一个软件样本,它就会记住铁,你就不能再取。现在事实证明,如果科里亚接受了审判,那么我们其他人就出局了。所以我的快乐已经结束了。

我看到现在唯一的出路是与C盘绑定。

这是在有一个C盘,而不是例如/dev/sda的情况下。