Recuperación de información de SMBIOS - página 5

 

Problema en mt4, funciona bien en mt5


 
Vitaly Muzichenko:

Problema en mt4, funciona bien en mt5

Lo tengo.

El parámetro de la función es

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

He comprobado lo que es el PVOID.

He marcado este tipo como largo por alguna razón.

Lo he cambiado auchar y funciona

 

El código final es el siguiente

//+------------------------------------------------------------------+
//|                                                      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, ¡muchas gracias!

 
Vitaly Muzichenko:

El código final es el siguiente

---

@Edgar Akhmadeev, ¡muchas gracias!

Aprovéchalo.
Escribí un par de ejemplos en c++ y la documentación de MS en unas pocas horas, lo probé en los miembros del foro del laboratorio.
Un flash mob así. No tengo previsto utilizarlos.
 
Edgar Akhmadeev:

Código escrito para leer la información del hardware (placa base y plataforma) de SMBIOS. Se utiliza WinAPI, por supuesto. Se puede utilizar para unir productos a los herrajes. En mi opinión, no tiene sentido enlazar con otra cosa que no sea la placa base. Las unidades, las tarjetas de vídeo son variables.

¡Saludos!

Se han reunido algunas estadísticas escasas sobre unas 50 máquinas.

Resulta queel UUID puede ser el mismo en varias máquinas, lo cual es muy frustrante. ¿Por qué es así?

Dicho esto, la mayoría de las veces, concretamente en 6 máquinas y en mi séptima, el número coincide con "03000200-0400-0500-0006-000700080009"

Intentaré recopilar estadísticas sobre el número de partición del disco C también, aunque es fácil de cambiar por las utilidades, por lo que es particularmente inadecuado como enlace.

 
Los chinos son traviesos.
 

No veo una salida fiable en tal caso. Sólo podemos alegrarnos de que 7 de 50 coincidan.

Aparte del UUID de la placa base, no hay otras entradas fiables. Los demás son opcionales (por ejemplo, el número de serie) o se pueden cambiar fácilmente cuando se formatea, se reinstala Windows o se realiza una actualización menor.

A menos que esté vinculado a una llave de hardware, pero eso es demasiado. Sólo sirve para programas que valen miles de dólares.

 
Edgar Akhmadeev:

No veo una salida fiable en tal caso. Sólo podemos alegrarnos de que 7 de 50 coincidan.

Aparte del UUID de la placa base, no hay otras entradas fiables. Los demás son opcionales (por ejemplo, el número de serie) o se pueden cambiar fácilmente cuando se formatea, se reinstala Windows o se realiza una actualización menor.

A menos que esté vinculado a una llave de hardware, pero eso es demasiado. Eso sólo sirve para miles de dólares de software.

Mi lógica es la siguiente: si tomaste un programa de muestra, éste recuerda el hardware y no puedes tomar más. Ahora resulta que si Kolya se llevó una copia de prueba, el resto no tenemos suerte. Así que mi alegría se acabó.

La única salida que veo ahora es enlazar con la unidad C

 
Vitaly Muzichenko:

Mi lógica es la siguiente: si tomaste una muestra de software, éste recuerda el hierro y no puedes tomar más. Ahora resulta que si Kolya aceptó el juicio, entonces el resto de nosotros estamos fuera. Así que mi alegría se acabó.

Veo que la única salida ahora es enlazar con la unidad C.

No entiendo lo de los otros.

 
Vitaly Muzichenko:

Mi lógica es la siguiente: si tomaste una muestra de software, éste recuerda el hierro y no puedes tomar más. Ahora resulta que si Kolya aceptó el juicio, entonces el resto de nosotros estamos fuera. Así que mi alegría se acabó.

Veo que la única salida ahora es enlazar con la unidad C.

Esto es si hay una unidad C y no, por ejemplo, /dev/sda