//---------------------------------------------------------------------------- // EgalTech 2014-2014 //---------------------------------------------------------------------------- // File : MachineId.cpp Data : 08.09.14 Versione : 1.5i2 // Contenuto : Funzioni per gestione/calcolo Id macchina. // // // // Modifiche : 08.09.14 DS Creazione modulo. // // //---------------------------------------------------------------------------- //------------------ Include ------------------------------------------------- #include "stdafx.h" #include "MachineId.h" #include "Obfuscate.h" #include "RegForMachineId.h" #include "/EgtDev/Include/SELkMachineId.h" #include "/EgtDev/Include/EgtBase64.h" #include "/EgtDev/Include/EgtCrc32.h" #include "/EgtDev/Include/EGnStringUtils.h" #include "/EgtDev/Include/EgtStringConverter.h" #define NOMINMAX #include #include using namespace std ; // ----------------- Funzioni locali ------------------------------------------------- static bool GetSN123FromRegistry( std::string& sSN1, std::string& sSN2, std::string& sSN3) ; static bool GetSN123FromMachine( std::string& sSN1, std::string& sSN2, std::string& sSN3) ; static void AdjustSN( const std::string& sSou, const char* szFill, std::string& sDest) ; static DWORD GetPhysicalDriveSN( UINT nDriveNumber, std::string& sSerialNumber) ; static DWORD GetDiskVolumeSN( const wchar_t* wszDisk, std::string& sSerialNumber) ; static DWORD GetPseudoRandomSN( std::string& sSerialNumber) ; //------------------------------------------------------------------------------------ bool CalcMachineId( bool bForceNew) { // recupero i tre seriali dai dati di Registry string sRegSN1, sRegSN2, sRegSN3 ; GetSN123FromRegistry( sRegSN1, sRegSN2, sRegSN3) ; // recupero i tre seriali dai dati macchina string sMacSN1, sMacSN2, sMacSN3 ; GetSN123FromMachine( sMacSN1, sMacSN2, sMacSN3) ; // combino i seriali nel MachineId string sSN1, sSN2, sSN3 ; sSN1 = sMacSN1 ; sSN2 = sMacSN2 ; if ( bForceNew || sRegSN3.empty()) sSN3 = sMacSN3 ; else sSN3 = sRegSN3 ; string sMachineId = sSN1 + "-" + sSN2 + "-" + sSN3 ; // salvo il MachineId nel registry if ( ! MixLockId( sMachineId)) return false ; AddCrc32ToString( sMachineId) ; string sB64 ; if ( ! B64Encode( sMachineId, sB64)) return false ; return SaveMachineIdOnReg( sB64) ; } //------------------------------------------------------------------------------------ bool GetMachineId( string& sMachineId) { // recupero i tre seriali dai dati di Registry string sRegSN1, sRegSN2, sRegSN3 ; GetSN123FromRegistry( sRegSN1, sRegSN2, sRegSN3) ; // recupero i tre seriali dai dati macchina string sMacSN1, sMacSN2, sMacSN3 ; GetSN123FromMachine( sMacSN1, sMacSN2, sMacSN3) ; // verifico che i primi due seriali coincidano e il terzo di registro esista (quello di macchina non conta) if ( sRegSN1 != sMacSN1 || sRegSN2 != sMacSN2 || sRegSN3.empty()) return false ; // costruisco l'Id di macchina dai seriali sMachineId = sRegSN1 + "-" + sRegSN2 + "-" + sRegSN3 ; return true ; } //------------------------------------------------------------------------------------ bool GetMachineId2( string& sMachineId) { string sAux ; if ( ! GetMachineId( sAux)) return false ; // Eseguo Mix + CRC32 + Base64. // Equivale a ConvertLockIdToLockId2 ma non lo uso per evitare link a sw chiave. if ( ! MixLockId( sAux)) return false ; AddCrc32ToString( sAux) ; return B64Encode( sAux, sMachineId) ; } //------------------------------------------------------------------------------------ static bool GetSN123FromRegistry( string& sSN1, string& sSN2, string& sSN3) { // leggo MachineId da Registry string sRegOffMachId ; if ( ! LoadMachineIdFromReg( sRegOffMachId)) return false ; // converto da forma offuscata (2) in forma chiara // Equivale a ConvertLockId2ToLockId ma non lo uso per evitare link a sw chiave. string sRegMachId ; // eseguo decodifica da Base64 if ( ! B64Decode( sRegOffMachId, sRegMachId)) return false ; // eseguo test e rimozione CRC32 if ( ! TestCrc32AndRemoveFromString( sRegMachId)) return false ; // eseguo demixing if ( ! MixLockId( sRegMachId)) return false ; // divisione in seriali sSN1 = sRegMachId.substr( 0, 6) ; sSN2 = sRegMachId.substr( 7, 6) ; sSN3 = sRegMachId.substr( 14, 6) ; return true ; } //------------------------------------------------------------------------------------ static bool GetSN123FromMachine( string& sSN1, string& sSN2, string& sSN3) { // recupero SN fisico del primo disco string sDriveSN ; DWORD dwRet = GetPhysicalDriveSN( 0, sDriveSN) ; // verifico errore bool bOk = ( dwRet == NO_ERROR && ! sDriveSN.empty()) ; // calcolo stringa First Serial Number AdjustSN( sDriveSN, "WCRTBAJYOI", sSN1) ; // recupero SN di volume del primo disco string sVolSN ; dwRet = GetDiskVolumeSN( L"C:\\", sVolSN) ; ; // verifico errore bOk = bOk && ( dwRet == NO_ERROR && ! sVolSN.empty()) ; // calcolo stringa Second Serial Number AdjustSN( sVolSN, "6038149572", sSN2) ; // recupero SN pseudo random string sPRandSN ; dwRet = GetPseudoRandomSN( sPRandSN) ; ; // verifico errore bOk = bOk && ( dwRet == NO_ERROR && ! sPRandSN.empty()) ; // calcolo stringa Third Serial Number AdjustSN( sPRandSN, "7438925160", sSN3) ; return bOk ; } //------------------------------------------------------------------------------------ static void AdjustSN( const string& sSou, const char* szFill, string& sDest) { static const int LEN_REF = 6 ; int nLen = (int) sSou.length() ; if ( nLen <= LEN_REF) sDest = string( szFill).substr( 0, LEN_REF - nLen) + sSou ; else if ( nLen == LEN_REF) sDest = sSou ; else sDest = sSou.substr( sSou.length() - LEN_REF, LEN_REF) ; } //------------------------------------------------------------------------------------ static DWORD GetPhysicalDriveSN( UINT nDriveNumber, string& sSerialNumber) { DWORD dwRet = NO_ERROR ; sSerialNumber.clear() ; // Format physical drive path (may be '\\.\PhysicalDrive0', '\\.\PhysicalDrive1' and so on). const int DIM_BUFF = 15 ; char szBuff[DIM_BUFF] ; _itoa_s( nDriveNumber, szBuff, 10) ; string sDrivePath = string( "\\\\.\\PhysicalDrive") + szBuff ; // Get a handle to physical drive HANDLE hDevice = ::CreateFileW( stringtoW( sDrivePath), 0, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if ( hDevice == INVALID_HANDLE_VALUE) return ::GetLastError() ; // Set the input data structure STORAGE_PROPERTY_QUERY storagePropertyQuery ; ZeroMemory(&storagePropertyQuery, sizeof(STORAGE_PROPERTY_QUERY)) ; storagePropertyQuery.PropertyId = StorageDeviceProperty ; storagePropertyQuery.QueryType = PropertyStandardQuery ; // Get the necessary output buffer size STORAGE_DESCRIPTOR_HEADER storageDescriptorHeader = {0} ; DWORD dwBytesReturned = 0; if ( ! ::DeviceIoControl( hDevice, IOCTL_STORAGE_QUERY_PROPERTY, &storagePropertyQuery, sizeof(STORAGE_PROPERTY_QUERY), &storageDescriptorHeader, sizeof(STORAGE_DESCRIPTOR_HEADER), &dwBytesReturned, NULL)) { dwRet = ::GetLastError() ; ::CloseHandle(hDevice) ; return dwRet ; } // Alloc the output buffer const DWORD dwOutBufferSize = storageDescriptorHeader.Size; BYTE* pOutBuffer = new BYTE[dwOutBufferSize]; ZeroMemory(pOutBuffer, dwOutBufferSize); // Get the storage device descriptor if ( ! ::DeviceIoControl( hDevice, IOCTL_STORAGE_QUERY_PROPERTY, &storagePropertyQuery, sizeof(STORAGE_PROPERTY_QUERY), pOutBuffer, dwOutBufferSize, &dwBytesReturned, NULL)) { dwRet = ::GetLastError() ; delete [] pOutBuffer ; ::CloseHandle(hDevice) ; return dwRet ; } // Now, the output buffer points to a STORAGE_DEVICE_DESCRIPTOR structure // followed by additional info like vendor ID, product ID, serial number, and so on. STORAGE_DEVICE_DESCRIPTOR* pDeviceDescriptor = (STORAGE_DEVICE_DESCRIPTOR*)pOutBuffer ; const DWORD dwSerialNumberOffset = pDeviceDescriptor->SerialNumberOffset ; if ( dwSerialNumberOffset != 0) { // Finally, get the serial number sSerialNumber = (char*)( pOutBuffer + dwSerialNumberOffset) ; Trim( sSerialNumber) ; } // Do cleanup and return delete []pOutBuffer; ::CloseHandle(hDevice); return dwRet; } //----------------------------------------------------------------------------- static DWORD GetDiskVolumeSN( const wchar_t* wszDisk, string& sSerialNumber) { DWORD dwRet = NO_ERROR ; sSerialNumber.clear() ; // Verifico il numero di serie del volume indicato DWORD dwSerNum, dwMaxLen, dwFSFlag ; if ( GetVolumeInformationW( wszDisk, NULL, 0, &dwSerNum, &dwMaxLen, &dwFSFlag, NULL, 0)) { const int DIM_BUFF = 30 ; char szBuff[DIM_BUFF] ; _ui64toa_s( (unsigned int) dwSerNum, szBuff, DIM_BUFF, 10) ; sSerialNumber = szBuff ; } else { dwRet = ::GetLastError() ; } return dwRet ; } //----------------------------------------------------------------------------- static DWORD GetPseudoRandomSN( string& sSerialNumber) { sSerialNumber.clear() ; UINT nSN ; DWORD dwRet = rand_s( &nSN) ; if ( dwRet == NO_ERROR) { const int DIM_BUFF = 30 ; char szBuff[DIM_BUFF] ; _ui64toa_s( nSN, szBuff, DIM_BUFF, 10) ; sSerialNumber = szBuff ; } return dwRet ; }