Recuperare informazioni da SMBIOS - pagina 5

 

Problema in mt4, funziona bene in mt5


 
Vitaly Muzichenko:

Problema in mt4, funziona bene in mt5

Capito.

Il parametro della funzione si legge

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

Ho controllato cos'è il PVOID.

Ho segnato questo tipo come lungo per qualche motivo.

L'ho cambiato inuchar e funziona

 

Il codice finale è il seguente

//+------------------------------------------------------------------+
//|                                                      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, grazie mille!

 
Vitaly Muzichenko:

Il codice finale è il seguente

---

@Edgar Akhmadeev, grazie mille!

Approfittatene.
Ho scritto un paio di esempi in c++ e la documentazione MS in poche ore, l'ho testato sui membri del forum del laboratorio.
Un tale flash mob. Non ho intenzione di usarli personalmente.
 
Edgar Akhmadeev:

Codice scritto per leggere le informazioni hardware (scheda madre e piattaforma) da SMBIOS. Si usa WinAPI, ovviamente. Può essere usato per legare i prodotti all'hardware. Secondo me, non ha senso legarsi a qualcosa di diverso dalla scheda madre. Le unità, le schede video sono variabili.

Saluti!

Ho raccolto alcune scarse statistiche su ~50 macchine.

Si scopre chel'UUID può essere lo stesso su diverse macchine, il che è molto frustrante. Perché questo è il caso?

Detto questo, il più delle volte, cioè su 6 macchine e sulla mia 7a, il numero corrisponde a "03000200-0400-0500-0006-000700080009".

Cercherò anche di raccogliere statistiche sul numero di partizione del disco C, anche se è facilmente modificato dalle utility, quindi è particolarmente inadatto come vincolo.

 
I cinesi sono maliziosi.
 

Non vedo una via d'uscita affidabile in un caso simile. Possiamo solo essere contenti che 7 su 50 corrispondano.

A parte l'UUID della scheda madre, non ci sono altre voci affidabili. Gli altri sono opzionali (per esempio il numero di serie) o facilmente sostituiti o cambiati durante la formattazione, la reinstallazione di Windows o un aggiornamento minore.

A meno che non sia collegato a una chiave hardware, ma questo è troppo. Buono solo per migliaia di dollari di software.

 
Edgar Akhmadeev:

Non vedo una via d'uscita affidabile in un caso simile. Possiamo solo essere contenti che 7 su 50 corrispondano.

A parte l'UUID della scheda madre, non ci sono altre voci affidabili. Gli altri sono opzionali (per esempio il numero di serie) o facilmente sostituiti o cambiati durante la formattazione, la reinstallazione di Windows o un aggiornamento minore.

A meno che non sia collegato ad una chiave hardware, ma questo è troppo. Questo va bene solo per migliaia di dollari di software.

La mia logica è questa: se avete preso un programma campione, esso ricorda l'hardware e non potete prenderne altri. Ora si scopre che se Kolya ha preso una copia di prova, il resto di noi è sfortunato. Quindi la mia gioia è finita.

L'unica via d'uscita che vedo ora è quella di legarsi all'unità C

 
Vitaly Muzichenko:

La mia logica è la seguente: se hai preso un campione di software, esso ricorda il ferro e non puoi prenderne altri. Ora si scopre che se Kolya ha accettato il processo, allora il resto di noi è fuori. Quindi la mia gioia è finita.

Vedo che l'unica via d'uscita ora è quella di legarsi all'unità C.

Non capisco gli altri.

 
Vitaly Muzichenko:

La mia logica è la seguente: se hai preso un campione di software, esso ricorda il ferro e non puoi prenderne altri. Ora si scopre che se Kolya ha accettato il processo, allora il resto di noi è fuori. Quindi la mia gioia è finita.

Vedo che l'unica via d'uscita ora è quella di legarsi all'unità C.

Questo se c'è un'unità C e non, per esempio, /dev/sda