修改后的,可以直接拿来在MFC中使用。
头文件
DiskInfo.h
#define PRINTING_TO_CONSOLE_ALLOWED
#include
#include
#include
#include
#include
#include
#include
#include
#pragma comment(lib, "iphlpapi.lib")
// special include from the MS DDK
//#include "c:\win2kddk\inc\ddk\ntddk.h"
//#include "c:\win2kddk\inc\ntddstor.h"
#define TITLE "DiskId32"
//char HardDriveSerialNumber [1024];
//char HardDriveModelNumber [1024];
//int PRINT_DEBUG = false;
static void dump_buffer (const char* title,
const unsigned char* buffer,
int len);
// Required to ensure correct PhysicalDrive IOCTL structure setup
#pragma pack(1)
#define IDENTIFY_BUFFER_SIZE 512
// IOCTL commands
#define DFP_GET_VERSION 0x00074080
#define DFP_SEND_DRIVE_COMMAND 0x0007c084
#define DFP_RECEIVE_DRIVE_DATA 0x0007c088
#define FILE_DEVICE_SCSI 0x0000001b
#define IOCTL_SCSI_MINIPORT_IDENTIFY ((FILE_DEVICE_SCSI << 16) + 0x0501)
#define IOCTL_SCSI_MINIPORT 0x0004D008 // see NTDDSCSI.H for definition
#define SMART_GET_VERSION CTL_CODE(IOCTL_DISK_BASE, 0x0020, METHOD_BUFFERED, FILE_READ_ACCESS)
#define SMART_SEND_DRIVE_COMMAND CTL_CODE(IOCTL_DISK_BASE, 0x0021, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
#define SMART_RCV_DRIVE_DATA CTL_CODE(IOCTL_DISK_BASE, 0x0022, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
typedef struct _GETVERSIONINPARAMS {
UCHAR bVersion; // Binary driver version.
UCHAR bRevision; // Binary driver revision.
UCHAR bReserved; // Not used.
UCHAR bIDEDeviceMap; // Bit map of IDE devices.
ULONG fCapabilities; // Bit mask of driver capabilities.
ULONG dwReserved[4]; // For future use.
} GETVERSIONINPARAMS, *PGETVERSIONINPARAMS, *LPGETVERSIONINPARAMS;
// GETVERSIONOUTPARAMS contains the data returned from the
// Get Driver Version function.
typedef struct _GETVERSIONOUTPARAMS
{
BYTE bVersion; // Binary driver version.
BYTE bRevision; // Binary driver revision.
BYTE bReserved; // Not used.
BYTE bIDEDeviceMap; // Bit map of IDE devices.
DWORD fCapabilities; // Bit mask of driver capabilities.
DWORD dwReserved[4]; // For future use.
} GETVERSIONOUTPARAMS, *PGETVERSIONOUTPARAMS, *LPGETVERSIONOUTPARAMS;
// Bits returned in the fCapabilities member of GETVERSIONOUTPARAMS
#define CAP_IDE_ID_FUNCTION 1 // ATA ID command supported
#define CAP_IDE_ATAPI_ID 2 // ATAPI ID command supported
#define CAP_IDE_EXECUTE_SMART_FUNCTION 4 // SMART commannds supported
// IDE registers
typedef struct _IDEREGS
{
BYTE bFeaturesReg; // Used for specifying SMART "commands".
BYTE bSectorCountReg; // IDE sector count register
BYTE bSectorNumberReg; // IDE sector number register
BYTE bCylLowReg; // IDE low order cylinder value
BYTE bCylHighReg; // IDE high order cylinder value
BYTE bDriveHeadReg; // IDE drive/head register
BYTE bCommandReg; // Actual IDE command.
BYTE bReserved; // reserved for future use. Must be zero.
} IDEREGS, *PIDEREGS, *LPIDEREGS;
// SENDCMDINPARAMS contains the input parameters for the
// Send Command to Drive function.
typedef struct _SENDCMDINPARAMS
{
DWORD cBufferSize; // Buffer size in bytes
IDEREGS irDriveRegs; // Structure with drive register values.
BYTE bDriveNumber; // Physical drive number to send
// command to (0,1,2,3).
BYTE bReserved[3]; // Reserved for future expansion.
DWORD dwReserved[4]; // For future use.
BYTE bBuffer[1]; // Input buffer.
} SENDCMDINPARAMS, *PSENDCMDINPARAMS, *LPSENDCMDINPARAMS;
// Valid values for the bCommandReg member of IDEREGS.
#define IDE_ATAPI_IDENTIFY 0xA1 // Returns ID sector for ATAPI.
#define IDE_ATA_IDENTIFY 0xEC // Returns ID sector for ATA.
// Status returned from driver
typedef struct _DRIVERSTATUS
{
BYTE bDriverError; // Error code from driver, or 0 if no error.
BYTE bIDEStatus; // Contents of IDE Error register.
// Only valid when bDriverError is SMART_IDE_ERROR.
BYTE bReserved[2]; // Reserved for future expansion.
DWORD dwReserved[2]; // Reserved for future expansion.
} DRIVERSTATUS, *PDRIVERSTATUS, *LPDRIVERSTATUS;
// Structure returned by PhysicalDrive IOCTL for several commands
typedef struct _SENDCMDOUTPARAMS
{
DWORD cBufferSize; // Size of bBuffer in bytes
DRIVERSTATUS DriverStatus; // Driver status structure.
BYTE bBuffer[1]; // Buffer of arbitrary length in which to store the data read from the // drive.
} SENDCMDOUTPARAMS, *PSENDCMDOUTPARAMS, *LPSENDCMDOUTPARAMS;
// The following struct defines the interesting part of the IDENTIFY
// buffer:
typedef struct _IDSECTOR
{
USHORT wGenConfig;
USHORT wNumCyls;
USHORT wReserved;
USHORT wNumHeads;
USHORT wBytesPerTrack;
USHORT wBytesPerSector;
USHORT wSectorsPerTrack;
USHORT wVendorUnique[3];
CHAR sSerialNumber[20];
USHORT wBufferType;
USHORT wBufferSize;
USHORT wECCSize;
CHAR sFirmwareRev[8];
CHAR sModelNumber[40];
USHORT wMoreVendorUnique;
USHORT wDoubleWordIO;
USHORT wCapabilities;
USHORT wReserved1;
USHORT wPIOTiming;
USHORT wDMATiming;
USHORT wBS;
USHORT wNumCurrentCyls;
USHORT wNumCurrentHeads;
USHORT wNumCurrentSectorsPerTrack;
ULONG ulCurrentSectorCapacity;
USHORT wMultSectorStuff;
ULONG ulTotalAddressableSectors;
USHORT wSingleWordDMA;
USHORT wMultiWordDMA;
BYTE bReserved[128];
} IDSECTOR, *PIDSECTOR;
typedef struct _SRB_IO_CONTROL
{
ULONG HeaderLength;
UCHAR Signature[8];
ULONG Timeout;
ULONG ControlCode;
ULONG ReturnCode;
ULONG Length;
} SRB_IO_CONTROL, *PSRB_IO_CONTROL;
// Define global buffers.
//BYTE IdOutCmd [sizeof (SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE - 1];
BOOL DoIDENTIFY (HANDLE, PSENDCMDINPARAMS, PSENDCMDOUTPARAMS, BYTE, BYTE,
PDWORD);
// Max number of drives assuming primary/secondary, master/slave topology
#define MAX_IDE_DRIVES 16
class CDiskInfo
{
public:
CDiskInfo(void);
~CDiskInfo(void);
public:
char HardDriveSerialNumber [1024];
char HardDriveModelNumber [1024];
int m_nID;
BYTE IdOutCmd [sizeof (SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE - 1];
char m_Macstring [256];
public:
int ReadPhysicalDriveInNTWithAdminRights (void); // 以管理员权限获取硬盘信息
char *ConvertToString (DWORD diskdata [256],int firstIndex,int lastIndex,char* buf);
void PrintIdeInfo (int drive, DWORD diskdata [256]);
BOOL DoIDENTIFY (HANDLE, PSENDCMDINPARAMS, PSENDCMDOUTPARAMS, BYTE, BYTE,PDWORD);
void WriteConstantString (char *entry, char *string);
void GetDeviceInfo();
char* GetHardDriveSerialNumber(); // 序列号
char* GetHardDriveModelNumber(); // 品牌
int GetComputerID(); //
void PrintMACaddress(unsigned char MACData[]) ;//MAC地址
DWORD GetMACaddress(void);
char* GetMACAddressstring();
};
//
源文件
DiskInfo.cpp
#include "DiskInfo.h" #include#include int PRINT_DEBUG = false; using namespace std; std::string& trim(std::string &); CDiskInfo::CDiskInfo(void) { } CDiskInfo::~CDiskInfo(void) { } void CDiskInfo::WriteConstantString (char *entry, char *string) { } void CDiskInfo:: PrintMACaddress(unsigned char MACData[]) { #ifdef PRINTING_TO_CONSOLE_ALLOWED printf("\nMAC Address: %02X-%02X-%02X-%02X-%02X-%02X\n", MACData[0], MACData[1], MACData[2], MACData[3], MACData[4], MACData[5]); #endif //char string [256]; sprintf (m_Macstring, "%02X-%02X-%02X-%02X-%02X-%02X", MACData[0], MACData[1], MACData[2], MACData[3], MACData[4], MACData[5]); //WriteConstantString ("MACaddress", string); } void CDiskInfo::PrintIdeInfo (int drive, DWORD diskdata [256]) { char serialNumber [1024]; char modelNumber [1024]; char revisionNumber [1024]; char bufferSize [32]; __int64 sectors = 0; __int64 bytes = 0; // copy the hard drive serial number to the buffer ConvertToString (diskdata, 10, 19, serialNumber); ConvertToString (diskdata, 27, 46, modelNumber); ConvertToString (diskdata, 23, 26, revisionNumber); sprintf (bufferSize, "%u", diskdata [21] * 512); if (0 == HardDriveSerialNumber [0] && // serial number must be alphanumeric // (but there can be leading spaces on IBM drives) (isalnum (serialNumber [0]) || isalnum (serialNumber [19]))) { strcpy (HardDriveSerialNumber, serialNumber); strcpy (HardDriveModelNumber, modelNumber); } #ifdef PRINTING_TO_CONSOLE_ALLOWED // calculate size based on 28 bit or 48 bit addressing // 48 bit addressing is reflected by bit 10 of word 83 if (diskdata [83] & 0x400) sectors = diskdata [103] * 65536I64 * 65536I64 * 65536I64 + diskdata [102] * 65536I64 * 65536I64 + diskdata [101] * 65536I64 + diskdata [100]; else sectors = diskdata [61] * 65536 + diskdata [60]; // there are 512 bytes in a sector bytes = sectors * 512; printf ("Drive Size________________________: %I64d bytes\n", bytes); #endif // PRINTING_TO_CONSOLE_ALLOWED char string1 [1000]; sprintf (string1, "Drive%dModelNumber", drive); WriteConstantString (string1, modelNumber); sprintf (string1, "Drive%dSerialNumber", drive); WriteConstantString (string1, serialNumber); sprintf (string1, "Drive%dControllerRevisionNumber", drive); WriteConstantString (string1, revisionNumber); sprintf (string1, "Drive%dControllerBufferSize", drive); WriteConstantString (string1, bufferSize); sprintf (string1, "Drive%dType", drive); if (diskdata [0] & 0x0080) WriteConstantString (string1, "Removable"); else if (diskdata [0] & 0x0040) WriteConstantString (string1, "Fixed"); else WriteConstantString (string1, "Unknown"); } int CDiskInfo::ReadPhysicalDriveInNTWithAdminRights (void) // 已管理员权限读取物理硬盘信息 { int done = FALSE; int drive = 0; for (drive = 0; drive < MAX_IDE_DRIVES; drive++) { HANDLE hPhysicalDriveIOCTL = 0; // Try to get a handle to PhysicalDrive IOCTL, report failure // and exit if can't. char driveName [256]; sprintf (driveName, "\\\\.\\PhysicalDrive%d", drive); // Windows NT, Windows 2000, must have admin rights hPhysicalDriveIOCTL = CreateFile (driveName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE , NULL, OPEN_EXISTING, 0, NULL); // if (hPhysicalDriveIOCTL == INVALID_HANDLE_VALUE) // printf ("Unable to open physical drive %d, error code: 0x%lX\n", // drive, GetLastError ()); if (hPhysicalDriveIOCTL == INVALID_HANDLE_VALUE) { #ifdef PRINTING_TO_CONSOLE_ALLOWED if (PRINT_DEBUG) printf ("\n%d ReadPhysicalDriveInNTWithAdminRights ERROR" "\nCreateFile(%s) returned INVALID_HANDLE_VALUE\n", __LINE__, driveName); #endif } else { GETVERSIONOUTPARAMS VersionParams; DWORD cbBytesReturned = 0; // Get the version, etc of PhysicalDrive IOCTL memset ((void*) &VersionParams, 0, sizeof(VersionParams)); if ( ! DeviceIoControl (hPhysicalDriveIOCTL, DFP_GET_VERSION, NULL, 0, &VersionParams, sizeof(VersionParams), &cbBytesReturned, NULL) ) { #ifdef PRINTING_TO_CONSOLE_ALLOWED if (PRINT_DEBUG) { DWORD err = GetLastError (); printf ("\n%d ReadPhysicalDriveInNTWithAdminRights ERROR" "\nDeviceIoControl(%d, DFP_GET_VERSION) returned 0, error is %d\n", __LINE__, (int) hPhysicalDriveIOCTL, (int) err); } #endif } // If there is a IDE device at number "i" issue commands // to the device if (VersionParams.bIDEDeviceMap <= 0) { #ifdef PRINTING_TO_CONSOLE_ALLOWED if (PRINT_DEBUG) printf ("\n%d ReadPhysicalDriveInNTWithAdminRights ERROR" "\nNo device found at position %d (%d)\n", __LINE__, (int) drive, (int) VersionParams.bIDEDeviceMap); #endif } else { BYTE bIDCmd = 0; // IDE or ATAPI IDENTIFY cmd SENDCMDINPARAMS scip; //SENDCMDOUTPARAMS OutCmd; // Now, get the ID sector for all IDE devices in the system. // If the device is ATAPI use the IDE_ATAPI_IDENTIFY command, // otherwise use the IDE_ATA_IDENTIFY command bIDCmd = (VersionParams.bIDEDeviceMap >> drive & 0x10) ? \ IDE_ATAPI_IDENTIFY : IDE_ATA_IDENTIFY; memset (&scip, 0, sizeof(scip)); memset (IdOutCmd, 0, sizeof(IdOutCmd)); if ( DoIDENTIFY (hPhysicalDriveIOCTL, &scip, (PSENDCMDOUTPARAMS)&IdOutCmd, (BYTE) bIDCmd, (BYTE) drive, &cbBytesReturned)) { DWORD diskdata [256]; int ijk = 0; USHORT *pIdSector = (USHORT *) ((PSENDCMDOUTPARAMS) IdOutCmd) -> bBuffer; for (ijk = 0; ijk < 256; ijk++) diskdata [ijk] = pIdSector [ijk]; PrintIdeInfo (drive, diskdata); done = TRUE; } } CloseHandle (hPhysicalDriveIOCTL); } } return done; } BOOL CDiskInfo::DoIDENTIFY (HANDLE hPhysicalDriveIOCTL, PSENDCMDINPARAMS pSCIP, PSENDCMDOUTPARAMS pSCOP, BYTE bIDCmd, BYTE bDriveNum, PDWORD lpcbBytesReturned) { // Set up data structures for IDENTIFY command. pSCIP -> cBufferSize = IDENTIFY_BUFFER_SIZE; pSCIP -> irDriveRegs.bFeaturesReg = 0; pSCIP -> irDriveRegs.bSectorCountReg = 1; //pSCIP -> irDriveRegs.bSectorNumberReg = 1; pSCIP -> irDriveRegs.bCylLowReg = 0; pSCIP -> irDriveRegs.bCylHighReg = 0; // Compute the drive number. pSCIP -> irDriveRegs.bDriveHeadReg = 0xA0 | ((bDriveNum & 1) << 4); // The command can either be IDE identify or ATAPI identify. pSCIP -> irDriveRegs.bCommandReg = bIDCmd; pSCIP -> bDriveNumber = bDriveNum; pSCIP -> cBufferSize = IDENTIFY_BUFFER_SIZE; return ( DeviceIoControl (hPhysicalDriveIOCTL, DFP_RECEIVE_DRIVE_DATA, (LPVOID) pSCIP, sizeof(SENDCMDINPARAMS) - 1, (LPVOID) pSCOP, sizeof(SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE - 1, lpcbBytesReturned, NULL) ); } char * CDiskInfo::ConvertToString (DWORD diskdata [256], int firstIndex, int lastIndex, char* buf) { int index = 0; int position = 0; // each integer has two characters stored in it backwards for (index = firstIndex; index <= lastIndex; index++) { // get high byte for 1st character buf [position++] = (char) (diskdata [index] / 256); // get low byte for 2nd character buf [position++] = (char) (diskdata [index] % 256); } // end the string buf[position] = '\0'; // cut off the trailing blanks for (index = position - 1; index > 0 && isspace(buf [index]); index--) buf [index] = '\0'; return buf; } char* CDiskInfo::GetHardDriveSerialNumber() { GetDeviceInfo(); char szbuf[1024]={0}; std::string strtemp = HardDriveSerialNumber; //去掉首尾空格 std::string strTemp2= trim(strtemp); char* c; const int len = strTemp2.length(); c = new char[len+1]; strcpy(c,strTemp2.c_str()); return c ; } char* CDiskInfo::GetHardDriveModelNumber() { char* p=NULL; GetDeviceInfo(); p = HardDriveModelNumber; return p; } int CDiskInfo::GetComputerID() { GetDeviceInfo(); return m_nID; } void CDiskInfo::GetDeviceInfo() { int done = FALSE; // char string [1024]; __int64 id = 0; OSVERSIONINFO version; strcpy (HardDriveSerialNumber, ""); memset (&version, 0, sizeof (version)); version.dwOSVersionInfoSize = sizeof (OSVERSIONINFO); GetVersionEx (&version); if (version.dwPlatformId == VER_PLATFORM_WIN32_NT) { done = ReadPhysicalDriveInNTWithAdminRights (); } else { // this works under Win9X and calls a VXD // int attempt = 0; // // // try this up to 10 times to get a hard drive serial number // for (attempt = 0; // attempt < 10 && ! done && 0 == HardDriveSerialNumber [0]; // attempt++) // done = ReadDrivePortsInWin9X (); } if (HardDriveSerialNumber [0] > 0) { char *p = HardDriveSerialNumber; WriteConstantString ("HardDriveSerialNumber", HardDriveSerialNumber); // ignore first 5 characters from western digital hard drives if // the first four characters are WD-W if ( ! strncmp (HardDriveSerialNumber, "WD-W", 4)) p += 5; for ( ; p && *p; p++) { if ('-' == *p) continue; id *= 10; switch (*p) { case '0': id += 0; break; case '1': id += 1; break; case '2': id += 2; break; case '3': id += 3; break; case '4': id += 4; break; case '5': id += 5; break; case '6': id += 6; break; case '7': id += 7; break; case '8': id += 8; break; case '9': id += 9; break; case 'a': case 'A': id += 10; break; case 'b': case 'B': id += 11; break; case 'c': case 'C': id += 12; break; case 'd': case 'D': id += 13; break; case 'e': case 'E': id += 14; break; case 'f': case 'F': id += 15; break; case 'g': case 'G': id += 16; break; case 'h': case 'H': id += 17; break; case 'i': case 'I': id += 18; break; case 'j': case 'J': id += 19; break; case 'k': case 'K': id += 20; break; case 'l': case 'L': id += 21; break; case 'm': case 'M': id += 22; break; case 'n': case 'N': id += 23; break; case 'o': case 'O': id += 24; break; case 'p': case 'P': id += 25; break; case 'q': case 'Q': id += 26; break; case 'r': case 'R': id += 27; break; case 's': case 'S': id += 28; break; case 't': case 'T': id += 29; break; case 'u': case 'U': id += 30; break; case 'v': case 'V': id += 31; break; case 'w': case 'W': id += 32; break; case 'x': case 'X': id += 33; break; case 'y': case 'Y': id += 34; break; case 'z': case 'Z': id += 35; break; } } } id %= 100000000; if (strstr (HardDriveModelNumber, "IBM-")) id += 300000000; else if (strstr (HardDriveModelNumber, "MAXTOR") || strstr (HardDriveModelNumber, "Maxtor")) id += 400000000; else if (strstr (HardDriveModelNumber, "WDC ")) id += 500000000; else id += 600000000; m_nID = id; char *pn = HardDriveSerialNumber; } DWORD CDiskInfo::GetMACaddress(void) { DWORD MACaddress = 0; IP_ADAPTER_INFO AdapterInfo[16]; // Allocate information // for up to 16 NICs DWORD dwBufLen = sizeof(AdapterInfo); // Save memory size of buffer DWORD dwStatus = GetAdaptersInfo( // Call GetAdapterInfo AdapterInfo, // [out] buffer to receive data &dwBufLen); // [in] size of receive data buffer assert(dwStatus == ERROR_SUCCESS); // Verify return value is // valid, no buffer overflow PIP_ADAPTER_INFO pAdapterInfo = AdapterInfo; // Contains pointer to // current adapter info do { if (MACaddress == 0) MACaddress = pAdapterInfo->Address [5] + pAdapterInfo->Address [4] * 256 + pAdapterInfo->Address [3] * 256 * 256 + pAdapterInfo->Address [2] * 256 * 256 * 256; PrintMACaddress(pAdapterInfo->Address); // Print MAC address pAdapterInfo = pAdapterInfo->Next; // Progress through linked list } while(pAdapterInfo); // Terminate if last adapter return MACaddress; } char* CDiskInfo::GetMACAddressstring() { GetMACaddress(); char *p = m_Macstring; return p ; } std::string& trim(std::string &s) { if (s.empty()) { return s; } s.erase(0,s.find_first_not_of(" ")); s.erase(s.find_last_not_of(" ") + 1); return s; }
使用
#include "DiskInfo.h"
void COPQRSTDlg::OnOK()
{
// TODO: Add extra validation here
CDiskInfo obj_DiskInfo;
char szbuf[1024];
char* buf=NULL;
CString str1 = obj_DiskInfo.GetHardDriveSerialNumber();
CString str2 = obj_DiskInfo.GetHardDriveModelNumber();
int n = obj_DiskInfo.GetComputerID();
CString str3 = obj_DiskInfo.GetMACAddressstring();
CDialog::OnOK();
}