Recuperando informações do SMBIOS - página 5

 

Problema no mt4, funciona bem no mt5


 
Vitaly Muzichenko:

Problema no mt4, funciona bem no mt5

Entendi.

O parâmetro da função diz

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

Eu verifiquei o que é PVOID.

Eu tenho marcado este tipo há tanto tempo por alguma razão.

Eu o mudei parauchar e funciona

 

O código final é o seguinte

//+------------------------------------------------------------------+
//|                                                      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, muito obrigado!

 
Vitaly Muzichenko:

O código final é o seguinte

---

@Edgar Akhmadeev, muito obrigado!

Tire proveito disso.
Escreveu alguns exemplos na documentação do c++ e MS em poucas horas, testou-a nos membros do fórum do laboratório.
Uma tal multidão relâmpago. Não pretendo usá-los eu mesmo.
 
Edgar Akhmadeev:

Código escrito para ler informações de hardware (placa-mãe e plataforma) do SMBIOS. O WinAPI é utilizado, é claro. Pode ser usado para amarrar produtos a ferragens. Na minha opinião, não faz sentido se prender a nada além da placa-mãe. Acionamentos, placas de vídeo são variáveis.

Saudações!

Reuniu algumas estatísticas escassas sobre ~50 máquinas.

Acontece quea UUID pode ser a mesma em várias máquinas, o que é muito frustrante. Por que este é o caso?

Dito isto, na maioria das vezes, em 6 máquinas e na minha 7ª, o número corresponde a "03000200-0400-0400-0500-0006-000700080009".

Vou tentar reunir estatísticas sobre o número da partição do disco C também, embora ele seja facilmente alterado por utilitários, por isso é particularmente inadequado como uma ligação.

 
Os chineses são maliciosos.
 

Não vejo uma saída confiável em um caso desses. Só podemos nos alegrar que 7 de 50 correspondam.

Além da UUID da placa-mãe, não há outras entradas confiáveis. As outras são opcionais (por exemplo, número de série) ou facilmente trocadas ou alteradas ao formatar, reinstalar o Windows ou uma atualização menor.

A menos que ligado a uma chave de hardware, mas isso é demais. Apenas bom para milhares de dólares de software.

 
Edgar Akhmadeev:

Não vejo uma saída confiável em um caso desses. Só podemos nos alegrar que 7 de 50 correspondam.

Além da UUID da placa-mãe, não há outras entradas confiáveis. As outras são opcionais (por exemplo, número de série) ou facilmente trocadas ou alteradas ao formatar, reinstalar o Windows ou uma atualização menor.

A menos que ligado a uma chave de hardware, mas isso é demais. Isso só é bom para milhares de dólares de software.

Minha lógica é a seguinte: se você pegou um programa de amostra, ele se lembra do hardware e você não pode mais pegar. Agora acontece que se Kolya pegou uma cópia de prova, o resto de nós está sem sorte. Portanto, minha alegria acabou.

A única saída que posso ver agora é ligar-se à unidade C

 
Vitaly Muzichenko:

Minha lógica é a seguinte: se você pegou uma amostra de software, ele se lembra do ferro e você não pode mais pegar. Agora acontece que se Kolya fez o julgamento, então o resto de nós está fora. Portanto, minha alegria acabou.

Vejo agora que a única saída é ligar-se à unidade C.

Eu não entendo sobre os outros.

 
Vitaly Muzichenko:

Minha lógica é a seguinte: se você pegou uma amostra de software, ele se lembra do ferro e você não pode mais pegar. Agora acontece que se Kolya fez o julgamento, então o resto de nós está fora. Portanto, minha alegria acabou.

Vejo agora que a única saída é ligar-se à unidade C.

Isto se houver uma unidade C e não, por exemplo, /dev/sda