SMBIOS에서 정보 얻기 - 페이지 5

 

문제는 MT4에 있으며 MT5에서는 완벽하게 작동합니다.


 
Vitaly Muzichenko :

문제는 MT4에 있으며 MT5에서는 완벽하게 작동합니다.

이해했다.

함수 매개변수는 다음을 지정합니다.

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

PVOID 가 무엇인지 살펴보았습니다.

어떤 이유로 이 유형은 long 으로 지정되었습니다.

uchar 로 변경하고 작동했습니다.

 

최종 코드는 이렇습니다

 //+------------------------------------------------------------------+
//|                                                      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 , 정말 감사합니다!

 
Vitaly Muzichenko :

최종 코드는 이렇습니다

---

@Edgar Akhmadeev , 정말 감사합니다!

즐기다.
몇 시간 만에 C++ 및 MS 문서로 몇 가지 예제를 작성하고 실험실 포럼 사용자에게 테스트했습니다.
플래시몹이 그렇습니다. 직접 사용할 생각은 없습니다.
 
Edgar Akhmadeev :

SMBIOS에서 하드웨어 정보(마더보드 및 플랫폼)를 읽는 코드를 작성했습니다. 당연히 WinAPI가 사용됩니다. 제품을 철에 묶는 데 사용할 수 있습니다. 제 생각에는 마더보드 이외의 다른 것에 바인딩하는 것은 의미가 없습니다. 디스크, 비디오 카드 - 가변.

인사말!

빈약한 통계 ~50대를 수집했습니다.

여러 컴퓨터가 동일한 UUID를 가질 수 있다는 것이 밝혀졌습니다. 이는 매우 슬픈 일입니다. 왜 그런 겁니까?

동시에, 가장 자주, 즉 6대의 기계와 7대에서 숫자 "03000200-0400-0500-0006-000700080009"가 일치합니다.

C 드라이브의 파티션 번호에 대한 통계를 수집하려고 하지만 유틸리티에 의해 쉽게 변경되므로 바인딩으로 특히 적합하지 않습니다.

 
중국인들이 농담을 하고 있다.
 

이 경우 신뢰할 수 있는 방법이 보이지 않습니다. 50 7 중 일치하는 것을 기뻐하는 것만 남아 있습니다.

마더보드의 UUID 외에 다른 신뢰할 수 있는 바인딩이 없습니다. 나머지는 선택 사항(예: 일련 번호)이거나 쉽게 교체되거나 포맷, Windows 재설치 또는 가벼운 업그레이드 시 변경됩니다.

하드웨어 키에 묶이지 않는 한, 그건 너무합니다. 수천 달러의 소프트웨어에만 적합합니다.

 
Edgar Akhmadeev :

이 경우 신뢰할 수 있는 방법이 보이지 않습니다. 50 7 중 일치하는 것을 기뻐하는 것만 남아 있습니다.

마더보드의 UUID 외에 다른 신뢰할 수 있는 바인딩이 없습니다. 나머지는 선택 사항(예: 일련 번호)이거나 쉽게 교체되거나 포맷, Windows 재설치 또는 가벼운 업그레이드 시 변경됩니다.

하드웨어 키에 묶이지 않는 한, 그건 너무합니다. 수천 달러의 소프트웨어에만 적합합니다.

내 논리는 다음과 같습니다. 프로그램 샘플을 가져오면 하드웨어가 기억하고 더 이상 가져갈 수 없습니다. 이제 Kolya가 탐사를 수행하면 나머지는 비행 중입니다. 그래서 기쁨은 거기서 끝이 났습니다.

이제 한 가지 방법이 보입니다. C 드라이브에 바인딩하십시오.

 
Vitaly Muzichenko :

내 논리는 다음과 같습니다. 프로그램 샘플을 가져오면 하드웨어가 기억하고 더 이상 가져갈 수 없습니다. 이제 Kolya가 탐사를 수행하면 나머지는 비행 중입니다. 그래서 기쁨은 거기서 끝이 났습니다.

이제 한 가지 방법이 보입니다. C 드라이브에 바인딩하십시오.

다른 사람들에 대해 이해하지 못했습니다.

 
Vitaly Muzichenko :

내 논리는 다음과 같습니다. 프로그램 샘플을 가져오면 하드웨어가 기억하고 더 이상 가져갈 수 없습니다. 이제 Kolya가 탐사를 수행하면 나머지는 비행 중입니다. 그래서 기쁨은 거기서 끝이 났습니다.

이제 한 가지 방법이 보입니다. C 드라이브에 바인딩하십시오.

이것은 예를 들어 / dev / sda가 아닌 C 드라이브가 있는 경우입니다.