VC读取硬盘序列号与CPU序列号

所需头文件

#include "stdafx.h" // VC6

#include <iostream>
#include <string>
#include <windows.h>
using namespace std;

读取硬盘序列号

硬盘序列号目前只能使用在windows平台,其他平台目前在研究。


#define   DFP_GET_VERSION   0x00074080
#define   DFP_SEND_DRIVE_COMMAND   0x0007c084
#define   DFP_RECEIVE_DRIVE_DATA   0x0007c088
 
#define  SENDIDLENGTH  sizeof (SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE
#define  IDENTIFY_BUFFER_SIZE  512
#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  IDE_ATAPI_IDENTIFY  0xA1  //  Returns ID sector for ATAPI.
#define  IDE_ATA_IDENTIFY    0xEC  //  Returns ID sector for ATA.
#define  IOCTL_GET_DRIVE_INFO   0x0007c088
#define  IOCTL_GET_VERSION          0x00074080
 /*
typedef unsigned char BYTE;
typedef unsigned long DWORD;
typedef unsigned long ULONG;
typedef unsigned short USHORT;
typedef char CHAR;
typedef unsigned char UCHAR;
typedef void* PVOID;
typedef PVOID HANDLE;
typedef char* PCHAR;
*/
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;
 
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;
 
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;
 
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;
 
typedef   struct   _SENDCMDOUTPARAMS   {
    DWORD         cBufferSize;     //   Size   of   bBuffer   in   bytes
    DRIVERSTATUS   DriverStatus;     //   Driver   status   structure.
    BYTE       bBuffer[512];       //   Buffer   of   arbitrary   length
    //   in   which   to   store   the   data   read   from   the   drive.
}   SENDCMDOUTPARAMS,   *PSENDCMDOUTPARAMS,   *LPSENDCMDOUTPARAMS;
 
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;
/*+++
Global   vars
---*/
GETVERSIONOUTPARAMS   vers;
SENDCMDINPARAMS   in;
SENDCMDOUTPARAMS   out;
HANDLE   h;
DWORD   i;
BYTE   j;
char HardDiskNO[200];
 
void  ChangeByteOrder(PCHAR   szString,   USHORT   uscStrSize)
{
    USHORT   i;
    CHAR   temp;
 
    for   (i   =   0;   i   <   uscStrSize;   i+=2)
    {
        temp   =   szString[i];
        szString[i]   =   szString[i+1];
        szString[i+1]   =   temp;
    }
}
 
PCHAR DeleteHeadSpace(PCHAR TheString) //删除获取序列号开头的空格,便于其他调用
{
    int j=0;
    for(int i=0;i<strlen(TheString);i++)
    {
        if(!isspace(TheString[i])) break;
        j++;
    }
 
    return &TheString[j];
}
 
 
bool HD_IDE_NT()
{
    bool IDEFlag=false;
    char hd[80];
    PIDSECTOR   phdinfo;
    char s[61];
 
    ZeroMemory(&vers,sizeof(vers));
 
 
    for (j = 0; j < 4; j++)
    {
        sprintf(hd,"\\\\.\\PhysicalDrive%d",j);
        h = CreateFileA(hd,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);
        //  Windows NT/2000/XP下创建文件需要管理员权限
        if (!h) continue;
        if (!DeviceIoControl(h,DFP_GET_VERSION,0,0,&vers,sizeof(vers),&i,0))
            // 得到驱动器的IO控制器版本
        {
            CloseHandle(h);
            continue;
        }
 
        if (!(vers.fCapabilities&1)){
            CloseHandle(h);
            return false;
        }
 
 
        ZeroMemory(&in,sizeof(in));
        ZeroMemory(&out,sizeof(out));
 
        if (j&1){
            in.irDriveRegs.bDriveHeadReg=0xb0;
        }
        else
        {
            in.irDriveRegs.bDriveHeadReg=0xa0;
        }
        if (vers.fCapabilities&(16>>j))    continue;
        else
        {
            in.irDriveRegs.bCommandReg=0xec;
        }
        in.bDriveNumber=j;
        in.irDriveRegs.bSectorCountReg=1;
        in.irDriveRegs.bSectorNumberReg=1;
        in.cBufferSize=512;
 
        if (!DeviceIoControl(h,DFP_RECEIVE_DRIVE_DATA,&in,sizeof(in),&out,sizeof(out),&i,0))
        {
            CloseHandle(h);
            return IDEFlag;
        }
 
        phdinfo=(PIDSECTOR)out.bBuffer;
 
        memcpy(s,phdinfo->sModelNumber,sizeof(phdinfo->sModelNumber));
        s[sizeof(phdinfo->sModelNumber)]=0;
        ChangeByteOrder(s,sizeof(phdinfo->sModelNumber));
 
 
        memcpy(s,phdinfo->sSerialNumber,sizeof(phdinfo->sSerialNumber));
        s[sizeof(phdinfo->sSerialNumber)]=0;
        ChangeByteOrder(s,sizeof(phdinfo->sSerialNumber));
 
        strcpy(HardDiskNO, DeleteHeadSpace(s));
 
 
 
        IDEFlag=true;
        CloseHandle(h);
    }
 
    return  IDEFlag;
}
 
bool HD_SCSI_NT()
{
    bool SCSIFlag=false;
 
    for (int controller=0;controller<16;controller++)
    {
        HANDLE hScsiDriveIOCTL = 0;
        char  driveName [256];
        char s[256];
 
        sprintf (driveName, "\\\\.\\Scsi%d:", controller);
 
        //  Windows NT/2000/XP下任何权限都可以进行
        hScsiDriveIOCTL = CreateFileA (driveName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,OPEN_EXISTING, 0, NULL);
 
        if (hScsiDriveIOCTL != INVALID_HANDLE_VALUE)
        {
            int drive = 0;
            DWORD dummy;
 
            for (drive = 0; drive < 2; drive++)
            {
                char buffer [sizeof (SRB_IO_CONTROL) + SENDIDLENGTH];
                SRB_IO_CONTROL *p = (SRB_IO_CONTROL *) buffer;
                SENDCMDINPARAMS *pin =(SENDCMDINPARAMS *) (buffer + sizeof (SRB_IO_CONTROL));
 
                memset (buffer, 0, sizeof (buffer));
                p -> HeaderLength = sizeof (SRB_IO_CONTROL);
                p -> Timeout = 10000;
                p -> Length = SENDIDLENGTH;
                p -> ControlCode = IOCTL_SCSI_MINIPORT_IDENTIFY;
                strncpy ((char *) p -> Signature, "SCSIDISK", 8);
                pin -> irDriveRegs.bCommandReg = IDE_ATA_IDENTIFY;
                pin -> bDriveNumber = drive;
                // 得到SCSI硬盘信息
 
                if (DeviceIoControl (hScsiDriveIOCTL,
                    IOCTL_SCSI_MINIPORT,
                    buffer,
                    sizeof (SRB_IO_CONTROL) + sizeof (SENDCMDINPARAMS) - 1,
                    buffer,
                    sizeof (SRB_IO_CONTROL) + SENDIDLENGTH,
                    &dummy, NULL))
                {
                    SENDCMDOUTPARAMS *pOut =(SENDCMDOUTPARAMS *) (buffer + sizeof (SRB_IO_CONTROL));
                    IDSECTOR *pId = (IDSECTOR *) (pOut -> bBuffer);
 
                    if(pId->sModelNumber[0])
                    {
                        memcpy(s,pId->sModelNumber,sizeof(pId->sModelNumber));
                        s[sizeof(pId->sModelNumber)]=0;
                        ChangeByteOrder(s,sizeof(pId->sModelNumber));
 
 
                        //AfxMessageBox(pId->sSerialNumber);
                        ChangeByteOrder(s,sizeof( pId->sSerialNumber));
//                        cout<<"\tSN:"<<DeleteHeadSpace( pId->sSerialNumber)<<endl;
                        strcpy(HardDiskNO, DeleteHeadSpace(s));
 
//                        AfxMessageBox(HardDiskNO);
 
                        SCSIFlag=true;  // 读取成功
                    }
                }
            }
            CloseHandle (hScsiDriveIOCTL);  // 关闭句柄
        }
    }
    return SCSIFlag;
}
 
char *  GetHardDiskNO()
{
    OSVERSIONINFO   VersionInfo;
 
    ZeroMemory(&VersionInfo,sizeof(VersionInfo));
    VersionInfo.dwOSVersionInfoSize=sizeof(VersionInfo);
    GetVersionEx(&VersionInfo);
 
    memset(HardDiskNO, 0, 200);
 
    switch (VersionInfo.dwPlatformId)
    {
    case VER_PLATFORM_WIN32_NT: // 这里没有做处理,便于测试
        HD_IDE_NT();
        HD_SCSI_NT();
 
        break;
    }
 
    return HardDiskNO;
}

读取CPU 序列号 ID

获取CPUID主要用到的是汇编语言,可以跨平台使用

string GetCPUID()
{
	std::string strCPUId;
	unsigned long s1, s2;
	char buf[32] = { 0 };
	__asm{
		mov eax, 01h   //eax=1:取CPU序列号
			xor edx, edx
			cpuid
			mov s1, edx
			mov s2, eax
	}
	if (s1) {
		memset(buf, 0, 32);
		sprintf(buf, "%08X", s1);
		strCPUId += buf;
	}
	if (s2) {
		memset(buf, 0, 32);
		sprintf(buf, "%08X", s2);
		strCPUId += buf;
	}
	__asm{
		mov eax, 03h
			xor ecx, ecx
			xor edx, edx
			cpuid
			mov s1, edx
			mov s2, ecx
	}
	if (s1) {
		memset(buf, 0, 32);
		sprintf(buf, "%08X", s1);
		strCPUId += buf;
	}
	if (s2) {
		memset(buf, 0, 32);
		sprintf(buf, "%08X", s2);
		strCPUId += buf;
	}
	return strCPUId;
}

使用

int main(int argc, char* argv[])
{
	printf("Hello World!\n%s\n",GetHardDiskNO());
	string str = GetCPUID();
	cout<<GetCPUID()<<endl;
//	printf("%s",str);
	return 0;
}

 

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: VC6.0是一个老旧的编程工具,但是它仍然可以读取硬盘序列号硬盘序列号硬盘唯一的标识符,可以帮助我们区分不同的硬盘。下面是读取硬盘序列号的步骤: 1. 在VC6.0中创建一个新的Win32控制台应用程序。 2. 在源文件中添加头文件#include <windows.h>,此头文件中定义了读取硬盘序列号的API函数。 3. 在主函数中,使用GetVolumeInformationA函数来获取硬盘的信息,如下: char szVolumeSerialNumber[256]; DWORD dwSerialNumber; DWORD dwMaxComponentLength; DWORD dwFileSystemFlags; char szFileSystemName[256]; BOOL bSuccess = GetVolumeInformationA("C:\\", NULL, 0, &dwSerialNumber, &dwMaxComponentLength, &dwFileSystemFlags, szFileSystemName, 256); 4. 上述代码中,C:\\表示要获取的硬盘的驱动器号,NULL表示不需要获取卷标,0表示卷标缓冲区的大小,而dwSerialNumber即为所获取的硬盘序列号。 5. 将硬盘序列号转换成字符串格式: sprintf(szVolumeSerialNumber, "%08X", dwSerialNumber); 6. 最终,将读取到的硬盘序列号输出到控制台: printf("Hard Disk Serial Number: %s\n", szVolumeSerialNumber); 通过以上步骤,就可以利用VC6.0读取硬盘序列号了,这对于某些需要以硬盘序列号作为标识的程序很有用。 ### 回答2: VC6.0是微软早期的编程开发工具之一,使用它可以读取硬盘序列号硬盘序列号是指硬盘唯一的标识符,每个硬盘都具有独特的序列号读取硬盘序列号可以实现硬件设备的唯一标识和数据安全性的保证。 在VC6.0中,读取硬盘序列号需要用到Windows API函数GetVolumeInformation,这个函数的作用是获取指定磁盘卷的相关信息,包括卷标、文件系统和序列号等。 具体步骤如下: 1.调用GetVolumeInformation函数,指定需要获取信息的硬盘驱动器号(例如:C盘为0、D盘为1等)。 2.将函数返回的信息存储在变量中,其中包括硬盘序列号等。 3.将硬盘序列号转换成字符串型,以便于进行后续操作。 需要注意的是,这种方法只适用于单个硬盘的情况,若系统中存在多个硬盘,则需要通过遍历硬盘列表的方式获取每个硬盘序列号。 最后,VC6.0读取硬盘序列号还需要考虑兼容性问题。由于VC6.0是一个比较老的开发工具,可以使用的Windows API函数和数据类型可能不够丰富,因此需要在开发过程中进行充分测试和调试,确保程序在各个平台上都能正常运行。 ### 回答3: VC++6.0读取硬盘序列号可以使用Windows API函数来实现。具体步骤如下: 1. 打开硬盘设备文件 可以使用CreateFile函数打开硬盘设备文件,设备名称可以通过GetLogicalDriveStrings函数获取。 2. 发送IO控制命令 使用DeviceIoControl函数发送IO控制命令获取硬盘序列号。使用的命令为IOCTL_STORAGE_QUERY_PROPERTY,具体细节可以参考Microsoft官方文档。 3. 解析获取到的数据 硬盘序列号是以十六进制形式存储在结构体中的,需要将其转换为字符串形式。具体实现可以参考以下代码示例: ```c++ HANDLE hDevice; DWORD bytesReturned; STORAGE_PROPERTY_QUERY query; query.PropertyId = StorageDeviceProperty; query.QueryType = PropertyStandardQuery; STORAGE_DEVICE_DESCRIPTOR descriptor; if (GetLogicalDriveStrings(0, NULL) == 0) { cout << "无法获取磁盘设备名称!" << endl; return 0; } TCHAR driveStrings[MAX_PATH]; if (GetLogicalDriveStrings(MAX_PATH, driveStrings) == 0) { cout << "无法获取磁盘设备名称!" << endl; return 0; } TCHAR* drive = driveStrings; while (*drive != 0) { TCHAR drivePath[MAX_PATH] = { 0 }; _sntprintf(drivePath, MAX_PATH - 1, _T("\\\\.\\%c:"), *drive); hDevice = CreateFile(drivePath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if (hDevice != INVALID_HANDLE_VALUE) { if (DeviceIoControl(hDevice, IOCTL_STORAGE_QUERY_PROPERTY, &query, sizeof(query), &descriptor, sizeof(descriptor), &bytesReturned, NULL)) { DWORD serialNumberOffset = descriptor.SerialNumberOffset; if (serialNumberOffset != 0) { char serialNumber[255]; ZeroMemory(serialNumber, sizeof(serialNumber)); memcpy(serialNumber, ((char*)&descriptor) + serialNumberOffset, (descriptor.SerialNumberLength - 1) * 2 + 1); cout << "磁盘" << *drive << "的序列号为:" << serialNumber << endl; } } CloseHandle(hDevice); } drive += _tcslen(drive) + 1; } ``` 以上代码可遍历系统中的所有磁盘,输出磁盘序列号
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值