Récupération des informations de SMBIOS - page 5

 

Problème dans mt4, fonctionne bien dans mt5


 
Vitaly Muzichenko:

Problème dans mt4, fonctionne bien dans mt5

Je l'ai.

Le paramètre de fonction est le suivant

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

J'ai vérifié ce qu'est PVOID.

J'ai marqué ce type comme long pour une raison quelconque.

Je l'ai changé enuchar et ça marche

 

Le code final est le suivant

//+------------------------------------------------------------------+
//|                                                      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, merci beaucoup !

 
Vitaly Muzichenko:

Le code final est le suivant

---

@Edgar Akhmadeev, merci beaucoup !

Profitez-en.
J'ai écrit quelques exemples en c++ et la documentation MS en quelques heures, je l'ai testé sur les membres du forum du laboratoire.
Un tel flash mob. Je n'ai pas l'intention de les utiliser moi-même.
 
Edgar Akhmadeev:

Code écrit pour lire les informations matérielles (carte mère et plateforme) à partir du SMBIOS. WinAPI est utilisé, bien sûr. Peut être utilisé pour lier les produits au matériel. À mon avis, il est inutile de se lier à autre chose qu'à la carte mère. Les lecteurs, les cartes vidéo sont variables.

Salutations !

J'ai recueilli quelques maigres statistiques sur ~50 machines.

Il s'avère que l'UUID peut être le même sur plusieurs machines, ce qui est très frustrant. Pourquoi en est-il ainsi ?

Cela dit, le plus souvent, notamment sur 6 machines et ma 7ème, le numéro correspond à "03000200-0400-0500-0006-000700080009".

J'essaierai également de rassembler des statistiques sur le numéro de la partition du disque C, bien qu'il soit facilement modifié par les utilitaires, ce qui le rend particulièrement impropre à servir de référence.

 
Les Chinois sont malicieux.
 

Je ne vois pas d'issue fiable dans un tel cas. Nous ne pouvons qu'être heureux que 7 sur 50 correspondent.

En dehors de l'UUID de la carte mère, il n'y a pas d'autres entrées fiables. Les autres sont soit facultatifs (par exemple, le numéro de série), soit facilement remplaçables ou modifiables lors du formatage, de la réinstallation de Windows ou d'une mise à niveau mineure.

Sauf si elle est liée à une clé matérielle, mais c'est trop. Seulement bon pour des milliers de dollars de logiciels.

 
Edgar Akhmadeev:

Je ne vois pas d'issue fiable dans un tel cas. Nous ne pouvons qu'être heureux que 7 sur 50 correspondent.

En dehors de l'UUID de la carte mère, il n'y a pas d'autres entrées fiables. Les autres sont soit facultatifs (par exemple, le numéro de série), soit facilement remplaçables ou modifiables lors d'un formatage, d'une réinstallation de Windows ou d'une mise à niveau mineure.

Sauf si elle est liée à une clé matérielle, mais c'est trop. C'est seulement bon pour des milliers de dollars de logiciels.

Ma logique est la suivante : si vous avez pris un programme échantillon, il se souvient du matériel et vous ne pouvez pas en prendre d'autres. Il s'avère maintenant que si Kolya a pris une copie d'essai, le reste d'entre nous n'a pas de chance. Ma joie est donc terminée.

Le seul moyen de s'en sortir est de se connecter au disque C.

 
Vitaly Muzichenko:

Ma logique est la suivante : si vous avez pris un échantillon de logiciel, il se souvient du fer et vous ne pouvez pas en prendre d'autres. Il s'avère que si Kolya a accepté le procès, nous sommes tous éliminés. Ma joie est donc terminée.

Je vois que le seul moyen de s'en sortir est de se lier au lecteur C.

Je ne comprends pas pour les autres.

 
Vitaly Muzichenko:

Ma logique est la suivante : si vous avez pris un échantillon de logiciel, il se souvient du fer et vous ne pouvez pas en prendre d'autres. Il s'avère que si Kolya a accepté le procès, nous sommes tous éliminés. Ma joie est donc terminée.

Je vois que le seul moyen de s'en sortir est de se lier au lecteur C.

C'est s'il y a un lecteur C et non, par exemple, /dev/sda