Abrufen von Informationen aus dem SMBIOS - Seite 5

 

Problem in mt4, funktioniert gut in mt5


 
Vitaly Muzichenko:

Problem in mt4, funktioniert gut in mt5

Ich hab's.

Der Funktionsparameter lautet

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

Ich habe überprüft, was PVOID ist.

Ich habe diesen Typ aus irgendeinem Grund als lang markiert.

Ich habe es inuchar geändert und es funktioniert

 

Der endgültige Code lautet wie folgt

//+------------------------------------------------------------------+
//|                                                      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, vielen Dank!

 
Vitaly Muzichenko:

Der endgültige Code lautet wie folgt

---

@Edgar Akhmadeev, vielen Dank!

Profitieren Sie davon.
Ich habe ein paar Beispiele in C++ und MS-Dokumentation in ein paar Stunden geschrieben und sie mit den Mitgliedern des Laborforums getestet.
Ein solcher Flashmob. Ich habe nicht vor, sie selbst zu verwenden.
 
Edgar Akhmadeev:

Geschriebener Code zum Lesen von Hardware-Informationen (Motherboard und Plattform) aus SMBIOS. Natürlich wird die WinAPI verwendet. Kann verwendet werden, um Produkte an Hardware zu binden. Meiner Meinung nach macht es keinen Sinn, sich an etwas anderes als die Hauptplatine zu binden. Laufwerke und Grafikkarten sind variabel.

Grüße!

Ich habe einige spärliche Statistiken über ~50 Maschinen gesammelt.

Es stellte sich heraus, dassdie UUID auf mehreren Rechnern gleich sein kann, was sehr frustrierend ist. Warum ist dies der Fall?

Meistens jedoch, nämlich auf 6 Rechnern und meinem 7., stimmt die Nummer mit "03000200-0400-0500-0006-000700080009" überein.

Ich werde versuchen, auch Statistiken über die Nummer der C-Festplattenpartition zu sammeln, obwohl sie von Dienstprogrammen leicht geändert werden kann und daher als Bindung besonders ungeeignet ist.

 
Die Chinesen sind schadenfroh.
 

Ich sehe in einem solchen Fall keinen zuverlässigen Ausweg. Wir können nur froh sein, dass 7 von 50 übereinstimmen.

Abgesehen von der UUID der Hauptplatine gibt es keine weiteren zuverlässigen Einträge. Die anderen sind entweder optional (z. B. Seriennummer) oder können bei der Formatierung, der Neuinstallation von Windows oder einem kleineren Upgrade leicht ausgetauscht oder geändert werden.

Es sei denn, sie sind mit einem Hardwareschlüssel verbunden, aber das ist zu viel. Nur gut für Software im Wert von Tausenden von Dollar.

 
Edgar Akhmadeev:

Ich sehe in einem solchen Fall keinen zuverlässigen Ausweg. Wir können nur froh sein, dass 7 von 50 übereinstimmen.

Abgesehen von der UUID des Motherboards gibt es keine weiteren zuverlässigen Einträge. Die anderen sind entweder optional (z. B. Seriennummer) oder können bei der Formatierung, der Neuinstallation von Windows oder einem kleineren Upgrade leicht ausgetauscht oder geändert werden.

Es sei denn, sie sind mit einem Hardwareschlüssel verbunden, aber das ist zu viel. Das gilt nur für Software im Wert von Tausenden von Dollar.

Meine Logik ist folgende: Wenn man ein Beispielprogramm genommen hat, merkt es sich die Hardware und man kann keine weiteren nehmen. Nun stellt sich heraus, dass Kolya ein Korrekturexemplar mitgenommen hat, während wir anderen Pech haben. Meine Freude ist also vorbei.

Der einzige Ausweg, den ich jetzt sehe, ist die Verbindung mit dem Laufwerk C

 
Vitaly Muzichenko:

Meine Logik ist folgende: Wenn man eine Software-Probe genommen hat, merkt sie sich das Eisen und man kann keine weitere mehr nehmen. Nun stellt sich heraus, dass, wenn Kolya den Versuch unternommen hat, der Rest von uns raus ist. Meine Freude ist also vorbei.

Ich sehe, dass der einzige Ausweg darin besteht, sich mit dem Laufwerk C zu verbinden.

Das mit den anderen verstehe ich nicht.

 
Vitaly Muzichenko:

Meine Logik ist folgende: Wenn man eine Software-Probe genommen hat, merkt sie sich das Eisen und man kann keine weitere mehr nehmen. Nun stellt sich heraus, dass, wenn Kolya den Versuch unternommen hat, der Rest von uns raus ist. Meine Freude ist also vorbei.

Ich sehe, dass der einzige Ausweg darin besteht, sich mit dem Laufwerk C zu verbinden.

Dies ist der Fall, wenn es ein Laufwerk C gibt und nicht z. B. /dev/sda