|
|
/*++
Copyright (c) 1998-1999, Microsoft Corporation
Module Name:
Hardware.cpp
Abstract:
--*/
#include "Hardware.h"
#include <stdio.h> // only needed for testing
#if defined(WIN32) || defined(_WIN32)
static inline BOOL IsPlatformNT() {
// always do it 'The NT Way'
return TRUE;
/*/////////////////////////////////////////////////////////////////////////////
OSVERSIONINFO osvInfo; BOOL fNTPlatformFlag;
osvInfo.dwOSVersionInfoSize = sizeof( OSVERSIONINFO );
GetVersionEx( &osvInfo );
switch( osvInfo.dwPlatformId ) { case VER_PLATFORM_WIN32_NT: fNTPlatformFlag = TRUE; break;
default: fNTPlatformFlag = FALSE; break; }
return( fNTPlatformFlag ); *//////////////////////////////////////////////////////////////////////////////
}
#else
inline BOOL IsPlatformNT() { return FALSE; }
extern "C" extern WORD _C000H; extern "C" extern WORD _F000H;
#endif
CHardware::CHardware() #ifdef HWID_DETAIL ////////////////////////////////////////////////////////////
: m_dwBiosCrc32(0), m_dwVolSer(0), m_dwTotalRamMegs(0), m_dwVideoBiosCrc32(0) #endif
{ uClassID = CHARDWARE_CLASSID;
ZeroMemory( (LPVOID)m_szHardwareID, HARDWARE_ID_SIZE );
SetBIOSDigit(); SetHDSerialDigit(); SetTotalRAMDigit(); SetFDConfigDigit(); SetVideoBIOSDigit();
#ifndef NO_HWID_GUID //////////////////////////////////////////////////////////
CalculateHardwareGUID(); #endif ////////////////////////////////////////////////////////////////////////
}
CHardware::~CHardware() { }
DWORD CHardware::GetType() { return(IsPlatformNT() ? 1 : 0); }
LPSTR CHardware::GetID() { return( m_szHardwareID ); }
#ifndef NO_HWID_GUID //////////////////////////////////////////////////////////
LPSTR CHardware::GetGUID() { return( m_szHardwareGUID ); } #endif ////////////////////////////////////////////////////////////////////////
VOID CHardware::SetBIOSDigit() { DWORD dwBIOSChecksum;
#if defined(WIN32) || defined(_WIN32)
if ( IsPlatformNT() ) { dwBIOSChecksum = CalculateRegKeyChecksum( "SystemBiosDate" ); dwBIOSChecksum += CalculateRegKeyChecksum( "SystemBiosVersion" ); m_dwBiosCrc32 = dwBIOSChecksum; } else #endif
{ LPBYTE pbMemoryByte;
#if defined(WIN32) || defined(_WIN32)
pbMemoryByte = (LPBYTE)0xF0000; #else
pbMemoryByte = (LPBYTE)MAKELONG(0, &_F000H); #endif
dwBIOSChecksum = CalculateMemoryRegionChecksum(pbMemoryByte, 2048); #ifdef HWID_DETAIL ////////////////////////////////////////////////////////////
m_dwBiosCrc32 = CRC_32(pbMemoryByte, 2048); #endif
}
m_szHardwareID[ BIOS_DIGIT ] = (CHAR)( dwBIOSChecksum % 9 ) + '0'; }
#if defined(WIN32) || defined(_WIN32)
UINT CHardware::CalculateRegKeyChecksum(LPSTR lpszKey) { LONG lStatus; HKEY hkSystem; UINT uChecksum;
uChecksum = 0;
lStatus = RegOpenKeyEx( HKEY_LOCAL_MACHINE, "HARDWARE\\DESCRIPTION\\System", 0, KEY_QUERY_VALUE, &hkSystem );
_ASSERT( lStatus == ERROR_SUCCESS );
if ( lStatus == ERROR_SUCCESS ) { DWORD dwValueType; DWORD dwBufferSize; BYTE Buffer[ MAX_BIOS_KEY_LENGTH ];
dwBufferSize = MAX_BIOS_KEY_LENGTH;
lStatus = RegQueryValueEx( hkSystem, lpszKey, NULL, &dwValueType, Buffer, &dwBufferSize );
// ASSERT( lStatus == ERROR_SUCCESS ); // Not all values are guarenteed to exist
if ( lStatus == ERROR_SUCCESS ) { UINT nCurrentByte;
for ( nCurrentByte = 0; nCurrentByte < dwBufferSize; nCurrentByte++ ) { uChecksum += Buffer[ nCurrentByte ]; } }
RegCloseKey( hkSystem ); }
return( uChecksum ); } #endif
DWORD CHardware::CalculateMemoryRegionChecksum( LPBYTE pbChecksumArea, INT nNumberBytes ) { DWORD dwRegionChecksum = 0;
while (0 < nNumberBytes) { dwRegionChecksum += (UINT)( *pbChecksumArea ); ++pbChecksumArea; --nNumberBytes; }
return( dwRegionChecksum ); }
#if !defined(WIN32) && !defined(_WIN32)
#pragma pack(1)
// Media ID
typedef struct { WORD wInfoLevel; DWORD dwSerialNum; char achVolLabel[11]; BYTE abFileSysType[8]; } MID, *PMID, FAR* LPMID; #pragma pack()
#endif
VOID CHardware::SetHDSerialDigit() { m_szHardwareID[ HD_SERIAL_DIGIT ] = '?'; BOOL fInfoSuccess; DWORD dwVolumeSerialNumber;
#if defined(WIN32) || defined(_WIN32)
DWORD dwFileSystemFlags; DWORD dwMaximumComponentLength; CHAR szBootDrivePath[ MAX_PATH ];
wsprintf( szBootDrivePath, "C:\\" ); fInfoSuccess = GetVolumeInformation( szBootDrivePath, NULL, 0, &dwVolumeSerialNumber, &dwMaximumComponentLength, &dwFileSystemFlags, NULL, 0 );
_ASSERT( fInfoSuccess );
#else
LPMID pmid; union _REGS regs; struct _SREGS segregs; DWORD dwMem;
dwMem = GlobalDosAlloc(sizeof(MID));
WORD wMidSelector = LOWORD(dwMem); WORD wMidSegment = HIWORD(dwMem);
pmid = (LPMID)MAKELP(wMidSelector, 0); ZeroMemory(pmid, sizeof(MID));
ZeroMemory(®s, sizeof(regs)); ZeroMemory(&segregs, sizeof(segregs));
regs.x.ax = 0x440d; // DOS Function 440Dh - IOCTL for Block Device
regs.h.cl = 0x66; // Minor Code 66h - Get Media ID
regs.h.ch = 0x08; // Device category (must be 08h)
regs.x.bx = 3; // Drive C:
regs.x.dx = 0; // pmid offset
segregs.ds = wMidSelector; // wMidSegment;
segregs.es = wMidSelector; // wMidSegment;
_intdosx(®s, ®s, &segregs);
fInfoSuccess = !regs.x.cflag;
dwVolumeSerialNumber = pmid->dwSerialNum; GlobalDosFree(wMidSelector); #endif
if ( fInfoSuccess ) { m_szHardwareID[ HD_SERIAL_DIGIT ] = (CHAR)( dwVolumeSerialNumber % 9 ) + '0';
#ifdef HWID_DETAIL ////////////////////////////////////////////////////////////
m_dwVolSer = dwVolumeSerialNumber; #endif
} }
VOID CHardware::SetTotalRAMDigit() { DWORD dwTotalMegabytes;
m_szHardwareID[ TOTAL_RAM_DIGIT ] = '?';
#if defined(WIN32) || defined(_WIN32)
MEMORYSTATUS mStatus;
mStatus.dwLength = sizeof( MEMORYSTATUS );
GlobalMemoryStatus( &mStatus );
dwTotalMegabytes = (DWORD)( mStatus.dwTotalPhys / (1024 * 1024)); // convert to Megabytes
dwTotalMegabytes += 1; // Add 1Mb to produce accurate result due to reserved space
#else
BYTE abDpmiMemInfo[0x30];
memset(abDpmiMemInfo, -1, sizeof(abDpmiMemInfo));
__asm { push di ;save regs
push ss pop es ;make es point to stack lea di,abDpmiMemInfo ;Get offset of buffer mov ax,0500h ;DPMI -- Get Free Memory Info int 31h ;Call DPMI
pop di ;restore regs }
DWORD dwTotalPages = *(LPDWORD)&abDpmiMemInfo[0x18];
// check to see if the field is -1 (error) and just use 0
// we're adding 1 to account for the memory below 1M (I think)
dwTotalMegabytes = (dwTotalPages == -1) ? 0 : (1 + dwTotalPages/(1024/4)); #endif
m_szHardwareID[ TOTAL_RAM_DIGIT ] = (CHAR)( dwTotalMegabytes % 9 ) + '0';
#ifdef HWID_DETAIL ////////////////////////////////////////////////////////////
m_dwTotalRamMegs = dwTotalMegabytes; #endif
}
VOID CHardware::SetFDConfigDigit() { DWORD dwFDConfig;
#if defined(WIN32) || defined(_WIN32)
if ( IsPlatformNT() ) { dwFDConfig = CalculateDriveCapacityNT( 1 ) << 2; dwFDConfig += CalculateDriveCapacityNT( 2 ); } else #endif
{ #ifndef _WIN64
dwFDConfig = CalculateDriveCapacity95( 1 ) << 2; dwFDConfig += CalculateDriveCapacity95( 2 ); #endif
}
m_szHardwareID[ FD_CONFIG_DIGIT ] = (CHAR)( dwFDConfig % 9 ) + '0'; }
#ifndef _WIN64
DWORD CHardware::CalculateDriveCapacity95( INT nDrive ) { DWORD dwDriveCapacity = 0; BOOL fOk;
UINT uNumberHeads; UINT uNumberTracks; UINT uBytesPerSector; UINT uSectorsPerTrack; LPBYTE pbDiskParamTable;
#if defined(WIN32) || defined(_WIN32)
HANDLE hDevice; BOOL fResult; DIOC_REGISTERS DIOCRegs; DWORD dwBytesReturned;
// Open VWIN32 Device For Access To DOS Int 13h Functions
hDevice = CreateFile( "\\\\.\\vwin32", 0, 0, NULL, 0, FILE_FLAG_DELETE_ON_CLOSE, NULL ); fOk = (hDevice != INVALID_HANDLE_VALUE);
if (fOk) { // Invoke Int 13h Function 08h - Get Drive Parameters
DIOCRegs.reg_EAX = 0x0800; // Get Drive Parameters
DIOCRegs.reg_EDX = nDrive - 1; // 0 = A:, 1 = B:
fResult = DeviceIoControl( hDevice, VWIN32_DIOC_DOS_INT13, &DIOCRegs, sizeof( DIOC_REGISTERS ), &DIOCRegs, sizeof( DIOC_REGISTERS ), &dwBytesReturned, NULL );
// Determine if Int 13h Call Succeeded
fOk = (fResult == TRUE && 0 == (DIOCRegs.reg_Flags & FLAGS_CARRY)); }
if (fOk) { // Calculate Drive Capacity if Drive Number is Valid
if ( ( DIOCRegs.reg_EDX & 0xFF ) >= (UINT)nDrive ) {
pbDiskParamTable = (UCHAR *)DIOCRegs.reg_EDI;
uNumberHeads = ( ( DIOCRegs.reg_EDX >> 8 ) & 0xFF ) + 1; uNumberTracks = ( ( ( DIOCRegs.reg_ECX << 2 ) & 0x300 ) + ( ( DIOCRegs.reg_ECX >> 8 ) & 0xFF ) ) + 1; uSectorsPerTrack = ( DIOCRegs.reg_ECX & 0x3F ); uBytesPerSector = ( 128 << ( *( pbDiskParamTable + 3 ) ) );
dwDriveCapacity = uNumberHeads * uNumberTracks * uSectorsPerTrack * uBytesPerSector; } }
if (hDevice != INVALID_HANDLE_VALUE) { CloseHandle( hDevice ); }
#else
union _REGS regs; struct _SREGS segregs;
ZeroMemory(®s, sizeof(regs)); ZeroMemory(&segregs, sizeof(segregs));
regs.h.ah = 0x08; // BIOS Function 08h - Get drive parameters
regs.x.dx = nDrive - 1; // 0 = A:, 1 = B:
_int86x( 0x13, // BIOS Disk
®s, ®s, &segregs);
fOk = (!regs.x.cflag);
if (fOk) { uNumberHeads = regs.h.dh + 1; uNumberTracks = ((regs.h.cl & 0xC0) << 2) + regs.h.ch + 1; uSectorsPerTrack = regs.h.cl & 0x3F;
pbDiskParamTable = (LPBYTE)MAKELP(segregs.es, regs.x.di);
uBytesPerSector = (128 << pbDiskParamTable[3]);
dwDriveCapacity = (DWORD)uNumberHeads * uNumberTracks * uSectorsPerTrack * uBytesPerSector; }
#endif
dwDriveCapacity /= ( 1024L * 100L );
return( dwDriveCapacity ); } #endif
#if defined(WIN32) || defined(_WIN32)
DWORD CHardware::CalculateDriveCapacityNT(INT nDrive) { BOOL fDriveExists; DWORD dwDriveCapacity; DWORD dwBytesReturned; CHAR szDrive[ MAX_PATH ]; CHAR szDriveAssignment[ MAX_PATH ];
dwDriveCapacity = 0;
// Determine if Logical Drive Exists
fDriveExists = FALSE;
wsprintf( szDrive, "%c:", 'A' + ( nDrive - 1 ) ); // Create DOS Drive Identifier (A: or B:)
dwBytesReturned = QueryDosDevice( szDrive, szDriveAssignment, MAX_PATH );
if ( dwBytesReturned != 0 ) { LPTSTR lpszWalkString;
// DBCS-Enabled Terminate String At 2nd Backslash (1st Backslash always at Position 0)
lpszWalkString = szDriveAssignment;
do { lpszWalkString = CharNext( lpszWalkString );
switch( *lpszWalkString ) { case '\\': *lpszWalkString = 0; break; } } while( *lpszWalkString != 0 );
// Determine if Logical Drive is Physically Present
if ( lstrcmp( szDriveAssignment, "\\Device" ) == 0 ) { fDriveExists = TRUE; } }
if ( fDriveExists == TRUE ) { // Get All Supported Media Types for Drive
HANDLE hDevice; BOOL fResult;
wsprintf( szDrive, "\\\\.\\%c:", 'A' + ( nDrive - 1 ) ); // Create NT Drive Identifier (\\.\A: or \\.\B:)
hDevice = CreateFile( szDrive, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL );
_ASSERT( hDevice != INVALID_HANDLE_VALUE );
if ( hDevice != INVALID_HANDLE_VALUE ) { DISK_GEOMETRY dGeometry[ 10 ];
fResult = DeviceIoControl( hDevice, IOCTL_DISK_GET_MEDIA_TYPES, NULL, 0, (LPVOID)&dGeometry, sizeof( DISK_GEOMETRY ) * 10, &dwBytesReturned, NULL );
_ASSERT( fResult );
if ( fResult == TRUE ) { // Calculate Maximum Media Size of Drive in Bytes if No Errors
INT nMediaCount; INT nCurrentMedia; UINT uCurrentMediaCapacity;
nMediaCount = dwBytesReturned / sizeof( DISK_GEOMETRY );
for ( nCurrentMedia = 0; nCurrentMedia < nMediaCount; nCurrentMedia++ ) { uCurrentMediaCapacity = (UINT)dGeometry[ nCurrentMedia ].Cylinders.LowPart; uCurrentMediaCapacity *= (UINT)dGeometry[ nCurrentMedia ].TracksPerCylinder; uCurrentMediaCapacity *= (UINT)dGeometry[ nCurrentMedia ].SectorsPerTrack; uCurrentMediaCapacity *= (UINT)dGeometry[ nCurrentMedia ].BytesPerSector;
if ( uCurrentMediaCapacity > dwDriveCapacity ) { dwDriveCapacity = uCurrentMediaCapacity; } } }
CloseHandle( hDevice ); } }
dwDriveCapacity /= ( 1024 * 100 );
return( dwDriveCapacity ); } #endif
VOID CHardware::SetVideoBIOSDigit() { DWORD dwVideoBIOSChecksum;
#if defined(WIN32) || defined(_WIN32)
if ( IsPlatformNT() ) { dwVideoBIOSChecksum = CalculateRegKeyChecksum( "VideoBiosDate" ); dwVideoBIOSChecksum += CalculateRegKeyChecksum( "VideoBiosVersion" );
#ifdef HWID_DETAIL ////////////////////////////////////////////////////////////
m_dwVideoBiosCrc32 = dwVideoBIOSChecksum; #endif
} else #endif
{
LPBYTE pbMemoryByte;
#if defined(WIN32) || defined(_WIN32)
pbMemoryByte = (LPBYTE)0xC0000; #else
pbMemoryByte = (LPBYTE)MAKELONG(0, &_C000H); #endif
dwVideoBIOSChecksum = CalculateMemoryRegionChecksum(pbMemoryByte, 2048);
#ifdef HWID_DETAIL ////////////////////////////////////////////////////////////
m_dwVideoBiosCrc32 = CRC_32(pbMemoryByte, 2048); #endif
}
m_szHardwareID[ VIDEO_BIOS_DIGIT ] = (CHAR)( dwVideoBIOSChecksum % 9 ) + '0'; }
#ifndef NO_HWID_GUID //////////////////////////////////////////////////////////
VOID CHardware::CalculateHardwareGUID() { ULONG uCRC; INT nIndex; CCrc32 *lpCCrc32; CHAR szCRCTemp[ 20 ];
// Create Empty Template for GUID
lstrcpy( m_szHardwareGUID, "{30303030-30DA-0000-0000-0020AFC36E79}" );
// Add ASCII HWID to GUID
for ( nIndex = 0; nIndex < lstrlen( m_szHardwareID ); nIndex++ ) { switch( nIndex ) { case 0: case 1: case 2: case 3: m_szHardwareGUID[ 2 + ( nIndex * 2 ) ] = m_szHardwareID[ nIndex ]; break;
case 4: m_szHardwareGUID[ 11 ] = m_szHardwareID[ nIndex ]; break;
default: _ASSERT( FALSE ); break; } }
// Calculate GUID CRC
lpCCrc32 = new CCrc32(); _ASSERT( lpCCrc32->uClassID == CCRC32_CLASSID );
uCRC = lpCCrc32->CalculateBlockCRC( m_szHardwareGUID, lstrlen( m_szHardwareGUID ) );
delete lpCCrc32;
// Add CRC Result To GUID
wsprintf( szCRCTemp, "%08X", uCRC );
for ( nIndex = 0; nIndex < lstrlen( szCRCTemp ); nIndex++ ) { switch( nIndex ) { case 0: case 1: case 2: case 3: m_szHardwareGUID[ 15 + nIndex ] = szCRCTemp[ nIndex ]; break;
case 4: case 5: case 6: case 7: m_szHardwareGUID[ 16 + nIndex ] = szCRCTemp[ nIndex ]; break;
default: _ASSERT( FALSE ); break; } } } #endif ////////////////////////////////////////////////////////////////////////
#if 0 /////////////////////////////////////////////////////////////////////////
// Test main() function
int PASCAL WinMain( HINSTANCE, // hInstance, // handle to current instance
HINSTANCE, // hPrevInstance, // handle to previous instance
LPSTR, // lpCmdLine, // pointer to command line
int // nCmdShow // show state of window)
) {
CHardware hwid;
MessageBox( NULL, (char *)hwid.GetGUID(), (char *)hwid.GetID(), MB_OK);
return 0; }
#endif ////////////////////////////////////////////////////////////////////////
|