1. 获取机器的MAC地址真的有很多种方法。可以通过windows api,可以通过wmi服务等。MSDN上面的例子是使用IP helper函数GetAdaptersInfo。其实还有一个api,是GetAdaptersAddresses。NetBios和DDK的方法不推荐使用,低于api层次的调用不保证微软会淘汰掉。建立一个支持MFC的控制台程序:
stdafx.h
-
#include <vector>
-
#include <string>
-
typedef std::vector< std::string > MACAddresses;
- typedef MACAddresses::iterator vsIt;
GetNetBiosMacAddresses.cpp
-
#include "stdafx.h"
-
#include <windows.h>
-
#include <wincon.h>
-
#include <stdio.h>
-
#include <nb30.h>
-
// Netbios is not supported on Windows
Vista, Windows Server 2008, and subsequent
versions of the operating system]l -
// For using
NetAPI to get MAC, should
include nb30.h -
#define MACSESION 6
-
#pragma warning( disable : 4996 )
-
#pragma comment(lib,"Netapi32.lib")
-
typedef struct _ASTAT_
-
{
-
ADAPTER_STATUS adapt;
-
NAME_BUFFER NameBuff [30];
-
}ASTAT, * PASTAT;
-
-
ASTAT Adapter; // to store
MAC information -
// input parameter: lana_num
start from 0, but in windows, not continuously
allocated, so not reliable. -
std::string getmac_one( int lana_num )
-
{
-
NCB ncb;
-
UCHAR uRetCode;
-
-
memset( &ncb, 0, sizeof( ncb ) );
-
ncb.ncb_command = NCBRESET;
-
ncb.ncb_lana_num = lana_num;
-
-
uRetCode = Netbios( &ncb );
-
//printf( "The
NCBRESET return code is:0x%x \n", uRetCode ); -
-
memset( &ncb, 0, sizeof( ncb ) );
-
ncb.ncb_command = NCBASTAT;
-
ncb.ncb_lana_num = lana_num;
-
-
strcpy( (char *)ncb.ncb_callname, "*
" ); -
ncb.ncb_buffer = ( unsigned
char * ) &Adapter; -
-
ncb.ncb_length = sizeof( Adapter );
-
uRetCode = Netbios( &ncb );
-
// printf( "The
NCBASTAT return code is: 0x%x \n", uRetCode ); -
std::string s;
-
if ( uRetCode == 0 )
-
{
-
int bAddressInt [ MACSESION ];
-
char CommarSeperatedAddress[ MACSESION * 3 ]={0};
-
for( int i = 0; i < MACSESION; ++i )
-
{
-
bAddressInt[ i ] = Adapter.adapt.adapter_address[ i ];
-
bAddressInt[ i ] &= 0x000000ff; // avoid "ff" leading
bytes when "char" is lager then 0x7f -
}
-
sprintf( CommarSeperatedAddress, "%02x:%02x:%02x:%02x:%02x:%02x",
-
bAddressInt[ 0 ],
-
bAddressInt[ 1 ],
-
bAddressInt[ 2 ],
-
bAddressInt[ 3 ],
-
bAddressInt[ 4 ],
-
bAddressInt[ 5 ]); // Should
use scl::FormatString inside -
s = CommarSeperatedAddress;
-
}
-
return s;
-
}
-
-
MACAddresses GetNetBiosMacAddresses()
-
{
-
NCB ncb;
-
UCHAR uRetCode;
-
LANA_ENUM lana_enum;
-
memset( &ncb, 0, sizeof( ncb ) );
-
ncb.ncb_command = NCBENUM;
-
-
ncb.ncb_buffer = (unsigned
char *) &lana_enum; -
ncb.ncb_length = sizeof( lana_enum );
-
-
uRetCode = Netbios( &ncb );
-
//printf( "The
NCBENUM return code is:0x%x \n", uRetCode ); -
MACAddresses vAdd;
-
if ( uRetCode == 0 )
-
{
-
//printf( "Ethernet
Count is : %d\n\n", lana_enum.length); -
for ( int i=0; i < lana_enum.length; ++i )
-
{
-
std::string s = getmac_one( lana_enum.lana[i] );
-
if( ! s.empty() )
-
{
-
vAdd.push_back( s );
-
}
-
}
-
}
-
return vAdd;
- }
GetMacAddresses.cpp
-
#include "stdafx.h"
-
#include <Winsock2.h>
-
#include <Iphlpapi.h>
-
#pragma comment(lib,"Iphlpapi")
-
#pragma warning( disable : 4996 )
-
#define MACSESION 6
-
MACAddresses GetINETMacAddresses()
-
{
-
PIP_ADAPTER_ADDRESSES pAddresses = NULL;
-
ULONG family = AF_INET;
-
ULONG flags = GAA_FLAG_INCLUDE_PREFIX;
-
ULONG outBufLen = sizeof( IP_ADAPTER_ADDRESSES );
-
-
// Make an initial call to GetAdaptersAddresses to get the
-
// size needed into the outBufLen variable
-
if ( GetAdaptersAddresses( family, flags, NULL, pAddresses, &outBufLen ) == ERROR_BUFFER_OVERFLOW )
-
{
-
pAddresses = static_cast<PIP_ADAPTER_ADDRESSES>( HeapAlloc( GetProcessHeap(), 0, outBufLen ) );
-
}
-
-
_ASSERT( pAddresses );
-
// Make a second call to GetAdapters
Addresses to get the -
// actual data we want
-
DWORD dwRetVal = GetAdaptersAddresses( family, flags, NULL, pAddresses, &outBufLen );
-
-
MACAddresses vAddress;
-
if ( dwRetVal != ERROR_SUCCESS )
-
{
-
return vAddress;
-
}
-
PIP_ADAPTER_ADDRESSES pFirst = pAddresses;
-
while( pAddresses )
-
{
-
BYTE* pa = pAddresses->PhysicalAddress;
-
if ( ! pa || ! pa[ 0 ] )
-
{
-
break;
-
}
-
char bAddressBytes[ MACSESION ];
-
int bAddressInt [ MACSESION ];
-
memset( bAddressBytes, 0, MACSESION );
-
size_t nAddressSize = pAddresses->PhysicalAddressLength;
-
memcpy( bAddressBytes, pa, ( nAddressSize < MACSESION ? nAddressSize : MACSESION ));
-
char CommarSeperatedAddress[ MACSESION * 3 ]={0};
-
for( int i = 0; i < MACSESION; ++i )
-
{
-
bAddressInt[ i ] = bAddressBytes[ i ];
-
bAddressInt[ i ] &= 0x000000ff; // avoid "ff" leading
bytes when "char" is lager then 0x7f -
}
-
sprintf( CommarSeperatedAddress, "%02x:%02x:%02x:%02x:%02x:%02x",
-
bAddressInt[ 0 ],
-
bAddressInt[ 1 ],
-
bAddressInt[ 2 ],
-
bAddressInt[ 3 ],
-
bAddressInt[ 4 ],
-
bAddressInt[ 5 ]); // Should
use scl::FormatString inside -
pAddresses = pAddresses->Next ? pAddresses->Next : NULL;
-
vAddress.push_back( std::string( CommarSeperatedAddress ) );
-
}
-
HeapFree( GetProcessHeap(), 0, pFirst );
-
return vAddress;
- }
2. 获取硬盘的id, api函数得到的都是和windows安装相关的id,也就是windows硬件管理器分配的id,而不是真正的硬件生产厂商的id. 所以,为了得到真正的和硬盘序列号相关的信息,最好是使用WMI服务查询。
GetPartitionVolumeSerialNumber.cpp
-
#include "stdafx.h"
-
DWORD GetPartitionVolumeSerialNumber() // Get Disk
partition volumn id, not hard
disk id -
{
-
TCHAR lpRootPathName[]= _T( "\\\\.\\PhysicalDrive0\\" ); // Use
physical drive, not C:disk -
TCHAR lpVolumeNameBuffer[ 12 ]; //disk
volumn -
DWORD nVolumeNameSize =12;
-
DWORD VolumeSerialNumber; // Serial
number -
DWORD MaximumComponentLength;
-
TCHAR lpFileSystemNameBuffer[ 10 ];
-
DWORD nFileSystemNameSize = 10;
-
DWORD FileSystemFlags;
-
BOOL ret = GetVolumeInformation( lpRootPathName,
-
lpVolumeNameBuffer,
-
nVolumeNameSize,
-
&VolumeSerialNumber,
-
&MaximumComponentLength,
-
&FileSystemFlags,
-
lpFileSystemNameBuffer,
-
nFileSystemNameSize);
-
-
printf( "Partition serial number is %0xd\n", VolumeSerialNumber );
-
if( ret )
-
{
-
return VolumeSerialNumber;
-
}
-
else
-
{
-
return FALSE;
-
}
- }
GetPhysicalSerialNumber.cpp
-
#include "stdafx.h"
-
#include <Iphlpapi.h>
-
#pragma comment(lib,"Iphlpapi")
-
//#pragma warning( disable : 4996 )
-
// IOCTL command constants
-
#define DFP_GET_VERSION 0x00074080
-
#define DFP_RECEIVE_DRIVE_DATA 0x0007c088
-
// values for IDEREGS.bCommandReg
-
#define IDE_ATAPI_IDENTIFY 0xA1
-
#define IDE_ATA_IDENTIFY 0xEC
-
#define IDENTIFY_BUFFER_SIZE 512
-
-
//save disk information
-
typedef struct _GETVERSIONOUTPARAMS
-
{
-
BYTE bVersion;
-
BYTE bRevision;
-
BYTE bReserved;
-
BYTE bIDEDeviceMap;
-
DWORD fCapabilities;
-
DWORD dwReserved[4];
-
} GETVERSIONOUTPARAMS, *PGETVERSIONOUTPARAMS, *LPGETVERSIONOUTPARAMS;
-
// IDE register information
-
typedef struct _IDEREGS
-
{
-
BYTE bFeaturesReg;
-
BYTE bSectorCountReg;
-
BYTE bSectorNumberReg;
-
BYTE bCylLowReg;
-
BYTE bCylHighReg;
-
BYTE bDriveHeadReg;
-
BYTE bCommandReg;
-
BYTE bReserved;
-
} IDEREGS, *PIDEREGS, *LPIDEREGS;
-
// disk command input parameter
-
typedef struct _SENDCMDINPARAMS
-
{
-
DWORD cBufferSize;
-
IDEREGS irDriveRegs;
-
BYTE bDriveNumber;
-
BYTE bReserved[3];
-
DWORD dwReserved[4];
-
BYTE bBuffer[1];
-
} SENDCMDINPARAMS, *PSENDCMDINPARAMS, *LPSENDCMDINPARAMS;
-
// disk status
-
typedef struct _DRIVERSTATUS
-
{
-
BYTE bDriverError;
-
BYTE bIDEStatus;
-
BYTE bReserved[2];
-
DWORD dwReserved[2];
-
} DRIVERSTATUS, *PDRIVERSTATUS, *LPDRIVERSTATUS;
-
// sent param for disk
commands -
typedef struct _SENDCMDOUTPARAMS
-
{
-
DWORD cBufferSize;
-
DRIVERSTATUS DriverStatus;
-
BYTE bBuffer[1];
-
} SENDCMDOUTPARAMS, *PSENDCMDOUTPARAMS, *LPSENDCMDOUTPARAMS;
-
void GetDiskPhysicalSN(char pchDiskPhysicalSN[14])
-
{
-
BYTE IdOutCmd[530];
-
HANDLE drive=CreateFile(L"\\\\.\\PhysicalDrive0", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL );
-
if ( drive == INVALID_HANDLE_VALUE )
-
{
-
pchDiskPhysicalSN[ 0 ] = 0;
-
return ;
-
}
-
GETVERSIONOUTPARAMS VersionParams;
-
DWORD cbBytesReturned = 0;
-
memset( ( void* ) &VersionParams, 0, sizeof( VersionParams ) );
-
if ( ! DeviceIoControl( drive, DFP_GET_VERSION, NULL, 0, &VersionParams, sizeof( VersionParams ), &cbBytesReturned, NULL ) )
-
{
-
pchDiskPhysicalSN[ 0 ] = 0;
-
return ;
-
}
-
if (VersionParams.bIDEDeviceMap<=0)
-
{
-
pchDiskPhysicalSN[ 0 ] = 0;
-
return ;
-
}
-
BYTE bIDCmd = 0;
-
SENDCMDINPARAMS scip;
-
bIDCmd = ( VersionParams.bIDEDeviceMap >> 0 & 0x10 ) ? IDE_ATAPI_IDENTIFY : IDE_ATA_IDENTIFY;
-
memset( &scip, 0, sizeof( scip) );
-
memset( IdOutCmd, 0, sizeof( IdOutCmd ) );
-
scip.cBufferSize = IDENTIFY_BUFFER_SIZE;
-
scip.irDriveRegs.bFeaturesReg = 0;
-
scip.irDriveRegs.bSectorCountReg = 1;
-
scip.irDriveRegs.bSectorNumberReg = 1;
-
scip.irDriveRegs.bCylLowReg = 0;
-
scip.irDriveRegs.bCylHighReg = 0;
-
scip.irDriveRegs.bDriveHeadReg= 0xA0 | ( ( ( BYTE ) drive & 1 ) << 4 );
-
scip.irDriveRegs.bCommandReg = bIDCmd;
-
scip.bDriveNumber = ( BYTE ) drive;
-
scip.cBufferSize = IDENTIFY_BUFFER_SIZE;
-
if ( ! DeviceIoControl( drive, DFP_RECEIVE_DRIVE_DATA, &scip, sizeof( SENDCMDINPARAMS)- 1, ( LPVOID )&IdOutCmd, sizeof( SENDCMDOUTPARAMS ) + IDENTIFY_BUFFER_SIZE - 1, &cbBytesReturned, NULL ) )
-
{
-
pchDiskPhysicalSN[ 0 ] = 0;
-
return ;
-
}
-
USHORT *pIdSector = ( USHORT * )( ( PSENDCMDOUTPARAMS )IdOutCmd )->bBuffer;
-
int nPosition = 0;
-
for( int nIndex = 13; nIndex < 20; nIndex++ )
-
{
-
pchDiskPhysicalSN[ nPosition++ ]=( unsigned
char )( pIdSector[ nIndex ] / 256 ); -
pchDiskPhysicalSN[ nPosition++ ]=( unsigned
char )( pIdSector[ nIndex ] % 256 ); -
}
-
}
-
-
void GetDiskPhysicalSerialNumber( char* pchSerialNumber )
-
{
-
char pchDiskPhysicalSN[ 14 ];
-
GetDiskPhysicalSN( pchDiskPhysicalSN );
-
int nSerial[ 14 ];
-
for( int i = 0 ; i < 14; ++ i )
-
{
-
nSerial[ i ] = pchDiskPhysicalSN[ i ];
-
nSerial[ i ] &= 0x000000ff;
-
}
-
sprintf( pchSerialNumber, "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
-
nSerial[ 0 ],
-
nSerial[ 1 ],
-
nSerial[ 2 ],
-
nSerial[ 3 ],
-
nSerial[ 4 ],
-
nSerial[ 5 ],
-
nSerial[ 6 ],
-
nSerial[ 7 ],
-
nSerial[ 8 ],
-
nSerial[ 9 ],
-
nSerial[ 10 ],
-
nSerial[ 11 ],
-
nSerial[ 12 ],
-
nSerial[ 13 ]); // Should
use scl::FormatString inside - }
main.cpp
-
#include "stdafx.h"
-
MACAddresses GetINETMacAddresses();
-
MACAddresses GetNetBiosMacAddresses();
-
DWORD GetPartitionVolumeSerialNumber();
-
void GetDiskPhysicalSerialNumber( char* pchDiskPhysicalSN );
-
int main(int argc, char* argv[])
-
{
-
DWORD VolumeSerialNumber = 0;
-
if( ! GetPartitionVolumeSerialNumber() )
-
{
-
TRACE( "(Get Disk Partition ID met error : %d)\n", GetLastError() );
-
}
-
else
-
{
-
printf( "Disk Partition ID = %0xd\n", VolumeSerialNumber );
-
}
-
char pchSerialNumber[ 50 ];
-
GetDiskPhysicalSerialNumber( pchSerialNumber );
-
printf("PhysicalSerialNumber is %s\n", pchSerialNumber );
-
printf("--------\n");
-
-
MACAddresses& vAddresses = GetINETMacAddresses();
-
for( vsIt it = vAddresses.begin(); it != vAddresses.end(); ++ it )
-
{
-
printf( "INET MAC addresses = %s\n", it->c_str() );
-
}
-
MACAddresses& vAddresses2 = GetNetBiosMacAddresses();
-
for( vsIt it = vAddresses2.begin(); it != vAddresses2.end(); ++ it )
-
{
-
printf( "NetBios MAC addresses = %s\n", it->c_str() );
-
}
-
return 0;
- }