C++获取硬盘序列号

C++获取硬盘序列号
C++获取硬盘序列号

作者自己已经在vs2008下编译通过,此代码获取的是机器的硬盘物理序列号(唯一的,即使格式化硬盘也不变)

main.cpp

#include "GetHDSerial.h"

#include

#include

#include

using namespace std;

int main(int argc,char** argv){

CGetHDSerial* disk = new CGetHDSerial;

char *diskNumber=disk->GetHDSerial();//获取硬盘序列号

std::cout<

return 0;

}

GetHDSerial.h

// GetHDSerial.h: interface for the CGetHDSerial class.

// Download by https://www.360docs.net/doc/7a2467440.html,/

//////////////////////////////////////////////////////////////////////

#include

#include

#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 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;

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; // 获取硬盘序列号的类

class CGetHDSerial

{

public:

CGetHDSerial();

virtual ~CGetHDSerial();

void _stdcall Win9xReadHDSerial(WORD * buffer);

char* GetHDSerial();

char* WORDToChar (WORD diskdata [256], int firstIndex, int lastIndex);

char* DWORDToChar (DWORD diskdata [256], int firstIndex, int lastIndex);

BOOL WinNTReadSCSIHDSerial(DWORD * buffer);

BOOL WinNTReadIDEHDSerial (DWORD * buffer);

BOOL WinNTGetIDEHDInfo (HANDLE hPhysicalDriveIOCTL, PSENDCMDINPARAMS pSCIP, PSENDCMDOUTPARAMS pSCOP, BYTE bIDCmd, BYTE bDriveNum,

PDWORD lpcbBytesReturned);

};

GetHDSerial.cpp

#include "GetHDSerial.h"

char m_buffer[256];

WORD m_serial[256];

DWORD m_OldInterruptAddress;

DWORDLONG m_IDTR;

// 等待硬盘空闲

static unsigned int WaitHardDiskIdle()

{

BYTE byTemp;

Waiting:

_asm

{

mov dx, 0x1f7

in al, dx

cmp al, 0x80

jb Endwaiting

jmp Waiting

}

Endwaiting:

_asm

{

mov byTemp, al

}

return byTemp;

}

//中断服务程序

void _declspec( naked )InterruptProcess(void)

{

int byTemp;

int i;

WORD temp;

//保存寄存器值

_asm

{

push eax

push ebx

push ecx

push edx

push esi

}

WaitHardDiskIdle();//等待硬盘空闲状态

_asm

{

mov dx, 0x1f6

mov al, 0xa0

out dx, al

}

byTemp = WaitHardDiskIdle(); //若直接在Ring3级执行等待命令,会进入死循环

if ((byTemp&0x50)!=0x50)

{

_asm // 恢复中断现场并退出中断服务程序

{

pop esi

pop edx

pop ecx

pop ebx

pop eax

iretd

}

_asm

{

mov dx, 0x1f6 //命令端口1f6,选择驱动器0 mov al, 0xa0

out dx, al

inc dx

mov al, 0xec

out dx, al //发送读驱动器参数命令

}

byTemp = WaitHardDiskIdle();

if ((byTemp&0x58)!=0x58)

{

_asm // 恢复中断现场并退出中断服务程序{

pop esi

pop edx

pop ecx

pop ebx

pop eax

iretd

}

}

//读取硬盘控制器的全部信息

for (i=0;i<256;i++)

{

_asm

{

mov dx, 0x1f0

in ax, dx

mov temp, ax

}

m_serial[i] = temp;

}

_asm

{

pop esi

pop edx

pop ecx

pop ebx

pop eax

iretd

}

///////////////////////////////////////////////////////////////////// /

// Construction/Destruction

///////////////////////////////////////////////////////////////////// /

CGetHDSerial::CGetHDSerial()

{

}

CGetHDSerial::~CGetHDSerial()

{

}

// 读取硬盘序列号函数

char* CGetHDSerial::GetHDSerial()

{

m_buffer[0]='\n';

// 得到当前操作系统版本

OSVERSIONINFO OSVersionInfo;

OSVersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); GetVersionEx( &OSVersionInfo);

if (OSVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT)

{

// Windows 9x/ME下读取硬盘序列号

WORD m_wWin9xHDSerial[256];

Win9xReadHDSerial(m_wWin9xHDSerial);

strcpy_s (m_buffer, WORDToChar (m_wWin9xHDSerial, 10, 19));

}

else

{

// Windows NT/2000/XP下读取硬盘序列号

DWORD m_wWinNTHDSerial[256];

// 判断是否有SCSI硬盘

if ( ! WinNTReadIDEHDSerial(m_wWinNTHDSerial)) WinNTReadSCSIHDSerial(m_wWinNTHDSerial);

strcpy_s (m_buffer, DWORDToChar (m_wWinNTHDSerial, 10, 19));

}

return m_buffer;

}

// Windows9X/ME系统下读取硬盘序列号

void _stdcall CGetHDSerial::Win9xReadHDSerial(WORD * buffer)

int i;

for(i=0;i<256;i++)

buffer[i]=0;

_asm

{

push eax

//获取修改的中断的中断描述符(中断门)地址

sidt m_IDTR

mov eax,dword ptr [m_IDTR+02h]

add eax,3*08h+04h

cli

//保存原先的中断入口地址

push ecx

mov ecx,dword ptr [eax]

mov cx,word ptr [eax-04h]

mov dword ptr m_OldInterruptAddress,ecx

pop ecx

//设置修改的中断入口地址为新的中断处理程序入口地址

push ebx

lea ebx,InterruptProcess

mov word ptr [eax-04h],bx

shr ebx,10h

mov word ptr [eax+02h],bx

pop ebx

//执行中断,转到Ring 0(类似CIH病毒原理)

int 3h

//恢复原先的中断入口地址

push ecx

mov ecx,dword ptr m_OldInterruptAddress

mov word ptr [eax-04h],cx

shr ecx,10h

mov word ptr [eax+02h],cx

pop ecx

sti

pop eax

}

for(i=0;i<256;i++)

buffer[i]=m_serial[i];

}

// Windows 9x/ME系统下,将字类型(WORD)的硬盘信息转换为字符类型(char)char * CGetHDSerial::WORDToChar (WORD diskdata [256], int firstIndex, int lastIndex)

static char string [1024];

int index = 0;

int position = 0;

// 按照高字节在前,低字节在后的顺序将字数组diskdata 中内容存入到字符串string中

for (index = firstIndex; index <= lastIndex; index++)

{

// 存入字中的高字节

string [position] = (char) (diskdata [index] / 256);

position++;

// 存入字中的低字节

string [position] = (char) (diskdata [index] % 256);

position++;

}

// 添加字符串结束标志

string [position] = '\0';

// 删除字符串中空格

for (index = position - 1; index > 0 && ' ' == string [index]; index--)

string [index] = '\0';

return string;

}

// Windows NT/2000/XP系统下,将双字类型(DWORD)的硬盘信息转换为字符类型(char)

char* CGetHDSerial::DWORDToChar (DWORD diskdata [256], int firstIndex , int lastIndex)

{

static char string [1024];

int index = 0;

int position = 0;

// 按照高字节在前,低字节在后的顺序将双字中的低字存入到字符串string 中

for (index = firstIndex; index <= lastIndex; index++)

{

// 存入低字中的高字节

string [position] = (char) (diskdata [index] / 256);

position++;

// 存入低字中的低字节

string [position] = (char) (diskdata [index] % 256);

position++;

}

// 添加字符串结束标志

string [position] = '\0';

// 删除字符串中空格

for (index = position - 1; index > 0 && ' ' == string [index]; index--)

string [index] = '\0';

return string;

}

// Windows NT/2000/XP下读取IDE硬盘序列号

BOOL CGetHDSerial::WinNTReadIDEHDSerial(DWORD * buffer)

{

BYTE IdOutCmd [sizeof (SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE - 1]; BOOL bFlag = FALSE;

int drive = 0;

char driveName [256];

HANDLE hPhysicalDriveIOCTL = 0;

sprintf_s (driveName, "\\\\.\\PhysicalDrive%d", drive);

// Windows NT/2000/XP下创建文件需要管理员权限

hPhysicalDriveIOCTL = CreateFile (driveName,

GENERIC_READ | GENERIC_WRITE,

FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,

OPEN_EXISTING, 0, NULL);

if (hPhysicalDriveIOCTL != INVALID_HANDLE_VALUE)

{

GETVERSIONOUTPARAMS VersionParams;

DWORD cbBytesReturned = 0;

// 得到驱动器的IO控制器版本

memset ((void*) &VersionParams, 0, sizeof(VersionParams));

if(DeviceIoControl (hPhysicalDriveIOCTL, IOCTL_GET_VERSION,

NULL, 0, &VersionParams,

sizeof(VersionParams),

&cbBytesReturned, NULL) )

{

if (VersionParams.bIDEDeviceMap > 0)

{

BYTE bIDCmd = 0; // IDE或者ATAPI识别命令SENDCMDINPARAMS scip;

// 如果驱动器是光驱,采用命令IDE_ATAPI_IDENTIFY, command, // 否则采用命令IDE_ATA_IDENTIFY读取驱动器信息

bIDCmd = (VersionParams.bIDEDeviceMap >> drive & 0x10)? IDE_ATAPI_IDENTIFY : IDE_ATA_IDENTIFY;

memset (&scip, 0, sizeof(scip));

memset (IdOutCmd, 0, sizeof(IdOutCmd));

// 获取驱动器信息

if (WinNTGetIDEHDInfo (hPhysicalDriveIOCTL,

&scip,

(PSENDCMDOUTPARAMS)&IdOutCmd,

(BYTE) bIDCmd,

(BYTE) drive,

&cbBytesReturned))

{

int m = 0;

USHORT *pIdSector = (USHORT *) ((PSENDCMDOUTPARAMS) IdOutCmd) -> bBuffer;

for (m = 0; m < 256; m++)

buffer[m] = pIdSector [m];

bFlag = TRUE; // 读取硬盘信息成功

}

}

}

CloseHandle (hPhysicalDriveIOCTL); // 关闭句柄

}

return bFlag;

}

// WindowsNT/2000/XP系统下读取SCSI硬盘序列号

BOOL CGetHDSerial::WinNTReadSCSIHDSerial (DWORD * buffer) {

buffer[0]='\n';

int controller = 0;

HANDLE hScsiDriveIOCTL = 0;

char driveName [256];

sprintf_s (driveName, "\\\\.\\Scsi%d:", controller);

// Windows NT/2000/XP下任何权限都可以进行

hScsiDriveIOCTL = CreateFile (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_s ((char *) p -> Signature, 0,"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])

{

int n = 0;

USHORT *pIdSector = (USHORT *) pId;

for (n = 0; n < 256; n++)

buffer[n] =(char)pIdSector [n];

return TRUE; // 读取成功

}

}

}

CloseHandle (hScsiDriveIOCTL); // 关闭句柄

}

return FALSE; // 读取失败

}

// Windows NT/2000/XP下读取IDE设备信息

BOOL CGetHDSerial::WinNTGetIDEHDInfo (HANDLE hPhysicalDriveIOCTL, PSE NDCMDINPARAMS pSCIP,

PSENDCMDOUTPARAMS pSCOP, BYTE bIDCmd, BYTE bDriveNum,

PDWORD lpcbBytesReturned)

{

// 为读取设备信息准备参数

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;

// 计算驱动器位置

pSCIP -> irDriveRegs.bDriveHeadReg = 0xA0 | ((bDriveNum & 1) << 4);

// 设置读取命令

pSCIP -> irDriveRegs.bCommandReg = bIDCmd;

pSCIP -> bDriveNumber = bDriveNum;

pSCIP -> cBufferSize = IDENTIFY_BUFFER_SIZE;

// 读取驱动器信息

return ( DeviceIoControl (hPhysicalDriveIOCTL, IOCTL_GET_DRIVE_INFO, (LPVOID) pSCIP,

sizeof(SENDCMDINPARAMS) - 1,

(LPVOID) pSCOP,

sizeof(SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE - 1, lpcbBytesReturned, NULL) );

}

机器码获取生成注册码

机器码获取生成注册码 通过获取硬盘的物理序列号和网卡MAC地址,为您的程序提供了获取唯一的机器码,你可以根据此码,生成自己产品注册码,有效防止软件的盗版可以自己根据获取到的硬盘序列号和网卡MAC地址进行一定的加密算法生成,唯一的机器码. 给自己的软件制作注册码.从今天起,您开发的的任何软件如果您愿意都可以为之加密 --为您的软件制作一款注册机!当您看完这篇文章时, 您就可以理直气壮的告诉您的用户 : "喂, 想用我的软件是吧 ? 掏钱!". 呵呵, 这当然只是给自己壮胆的话, 现在连万能注册机都有了, 人家还怕啥 ? 不过只要您想想微软, 人家再牛B的加密技术都会被国人"鄙视"? 但人家不也在中国大把大把的捞钱吗?OK, 不扯了, 我们进入正题.同一般的软件注册一样, 我们这里的注册是这样进行的: 1. 首先根据用户的硬件信息生成24位的机器码 -- 相当于种子,用于生成随机数 2. 采用注册机根据特征数字生成一个24位注册码 -- 相当于伪随机数生成器, 输出长度自己定, 最后用一个格式化函数,将随机数映射到ASCII字符集合 3. 用户输入注册码注册成功 假设客户很喜欢您的软件, 也假设他没有破解, 他需要通过以下方式向您取得注册码: (1).如果他能上网, 他需要把机器码用Email发给您; (2).如果他不能上网, 他可以把机器码用手机短信的方式发给您. (3).如果他没有手机, 他可以带着机器码然后坐火车到您的办公室想您要一个注册码. --第3条只是为了让您看帖子的时候别太枯燥了, 抱歉. 现在, 您拿到了客户的机器码后, 如果您同时也收到了他汇的钱, 呵呵, 好像给软件加密就是为了要钱吧? 那么您就可以用客户的机器码生成一个唯一的注册码再用同样的方式给用户, 最后, 用户输入注册码即可! 需要强调的是客户机器的硬件信息获取方式是有很多种选择的. 这里我们选择最放心的两个硬件: CUP的序列号和硬盘的卷标号. 好了,下面您就可以一步一步制作一款软件注册机了. 步骤一: 获得CUP序列号和硬盘序列号的实现代码如下:Java代码 #region 获取cpu的序列号 public string getCpu() { string strCpu = null; ManagementClass myCpu = new ManagementClass("win32_Processor");

VC++获取网卡MAC、硬盘序列号、CPU+ID、BIOS编号

VC++获取网卡MAC、硬盘序列号、CPU ID、BIOS编号 以下代码可以取得系统特征码(网卡MAC、硬盘序列号、CPU ID、BIOS编号) BYTE szSystemInfo[4096]; // 在程序执行完毕后,此处存储取得的系统特征码 UINT uSystemInfoLen = 0; // 在程序执行完毕后,此处存储取得的系统特征码的长度 // 网卡MAC 地址,注意: MAC 地址是可以在注册表中修改的 { UINT uErrorCode=0; IP_ADAPTER_INFO iai; ULONG uSize = 0; DWORD dwResult = GetAdaptersInfo( &iai, &uSize ); if( dwResult == ERROR_BUFFER_OVERFLOW ) { IP_ADAPTER_INFO* piai=( IP_ADAPTER_INFO* )HeapAlloc( GetProcessHeap( ), 0, uSize ); if( piai != NULL ) { dwResult = GetAdaptersInfo( piai, &uSize ); if( ERROR_SUCCESS == dwResult ) { IP_ADAPTER_INFO* piai2 = piai; while(piai2!=NULL &&(uSystemInfoLen+piai2->AddressLength )< 4096U) { CopyMemory(szSystemInfo+uSystemInfoLen,piai2->Address, piai2->AddressLength ); uSystemInfoLen += piai2->AddressLength; piai2 = piai2->Next; } } else { uErrorCode = 0xF0000000U + dwResult; } VERIFY( HeapFree( GetProcessHeap( ), 0, piai ) ); } else { return FALSE; } } else { uErrorCode = 0xE0000000U + dwResult; } if( uErrorCode != 0U ) { return FALSE; } }

NET获取硬盘序列号的几个方法

最近作软件注册,收集了很多.NET相关的获取硬盘物理序列号的方法,主要分为使用WMI方式和API方式。但这些方法均可能有问题。 1,使用WMI方式,有的机器根本取不到硬盘序列号,有的方式在Vista下面会报错。 常用的使用WMI的方式主要有下面一些方式: class HardDrive { private string model = null; private string type = null; private string serialNo = null; public string Model { get {return model;} set {model = value;} } public string Type { get {return type;} set {type = value;} } public string SerialNo { get {return serialNo;} set {serialNo = value;} } } class TestProgram { ///

/// The main entry point for the application. /// [STAThread] static void Main(string[] args) { //在Vista下面失败 ArrayList hdCollection = new ArrayList(); ManagementObjectSearcher searcher = new

ManagementObjectSearcher("SELECT * FROM Win32_DiskDrive"); foreach(ManagementObject wmi_HD in searcher.Get()) { HardDrive hd = new HardDrive(); hd.Model = wmi_HD["Model"].ToString(); hd.Type = wmi_HD["InterfaceType"].ToString(); hdCollection.Add(hd); } searcher = new ManagementObjectSearcher("SELECT * FROM Win32_PhysicalMedia"); int i = 0; foreach(ManagementObject wmi_HD in searcher.Get()) { // get the hard drive from collection // using index HardDrive hd = (HardDrive)hdCollection[i]; // get the hardware serial no. if (wmi_HD["SerialNumber"] == null) hd.SerialNo = "None"; else hd.SerialNo = wmi_HD["SerialNumber"].ToString(); ++i; } // Display available hard drives foreach(HardDrive hd in hdCollection) { Console.WriteLine("Model\t\t: " + hd.Model); Console.WriteLine("Type\t\t: " + hd.Type); Console.WriteLine("Serial No.\t: " + hd.SerialNo); Console.WriteLine(); } // Pause application Console.WriteLine("Press [Enter] to exit..."); Console.ReadLine(); } }

VC获得硬盘序列号

VC 之获取硬盘序列号 上一回,一帆风给大家讲了讲如何读取计算机的MAC地址,这次聊聊怎么获取硬盘序列号。硬盘物理序列号是硬盘的出厂序列号,它是全球都是唯一的,不会随着系统的安装、硬盘的格式化等操作而改变,跟mac地址一样都具有唯一性。1,第一步:创建设备对象,得到设备句柄,设备为硬盘。 { CString sFilePath; sFilePath.Format("\\\\.\\PHYSICALDRIVE%d", driver); HANDLE hFile=::CreateFile(sFilePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); DWORD dwBytesReturned; GETVERSIONINPARAMS gvopVersionParams; DeviceIoControl(hFile, //向设备对象发送SMART_GET_VERSION设备请求,获取硬盘属性 SMART_GET_VERSION, NULL, 0, &gvopVersionParams, sizeof(gvopVersionParams), &dwBytesReturned, NULL); if(gvopVersionParams.bIDEDeviceMap <= 0) return -2; 2。第二步,发送SMART_RCV_DRIVE_DATA设备请求,获取硬盘详细信息。 // IDE or ATAPI IDENTIFY cmd int btIDCmd = 0; SENDCMDINPARAMS InParams; int nDrive =0; btIDCmd = (gvopVersionParams.bIDEDeviceMap >> nDrive & 0x10) ? IDE_ATAPI_IDENTIFY : IDE_ATA_IDENTIFY; // 输出参数 BYTE btIDOutCmd[sizeof(SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE - 1]; if(DoIdentify(hFile, &InParams,

C++获取硬盘序列号

作者自己已经在vs2008下编译通过,此代码获取的是机器的硬盘物理序列号(唯一的,即使格式化硬盘也不变) main.cpp #include "GetHDSerial.h" #include #include #include using namespace std; int main(int argc,char** argv){ CGetHDSerial* disk = new CGetHDSerial; char *diskNumber=disk->GetHDSerial();//获取硬盘序列号 std::cout< #include #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 struct _IDSECTOR { USHORT wGenConfig; USHORT wNumCyls; USHORT wReserved; USHORT wNumHeads; USHORT wBytesPerTrack; USHORT wBytesPerSector; USHORT wSectorsPerTrack; USHORT wVendorUnique[3]; CHAR sSerialNumber[20]; USHORT wBufferType;

vb获取硬盘序列号利用硬盘序列号计算软件注册码-vb

vb获取硬盘序列号:利用硬盘序列号计算软件注册码-vb教程 疯狂代码 https://www.360docs.net/doc/7a2467440.html,/ ?:http:/https://www.360docs.net/doc/7a2467440.html,/VisualBasic/Article15611.html 盘序列号计算软件注册码。在模块中加入下列声明: Public Declare Function GetVolumeInformation Lib \"kernel32\" _ Alias \"GetVolumeInformationA\" (ByVal lpRootPathName As String, _ ByVal lpVolumeNameBuffer As String, ByVal nVolumeNameSize As Long, _ lpVolumeSerialNumber As Long, lpMaximumComponentLength As Long, _ lpFileSystemFlags As Long, ByVal lpFileSystemNameBuffer As String, _ ByVal nFileSystemNameSize As Long) As Long ′得到某一磁盘分区的信息,如C:窗体代码如下: Option Explicit Private Regid, Localid As LongPrivate Sub CmdLocalID_Click() ′根据C盘序列号得到原ID Dim Driver, VolName, Fsys As String Dim volNumber, MCM, FSF As Long Driver = \"c:\\\" Dim res As Long res = GetVolumeInformation(Driver, VolName, 127, volNumber, MCM, FSF, Fsys, 127) ′volNumber是C盘序列号 Localid = volNumber / 2 + 123456789 Text1.Text = Localid End SubPrivate Sub CmdRegID_Click() ′根据原ID算出注册ID If IsNumeric(Text1.Text) Then Regid = CLng(Text1.Text) / 4 * 3 + 987654321 Else ′error End If Text2.Text = Regid End SubPrivate Sub CmndCheckID_Click() ′验证注册ID Dim Driver, VolName, Fsys As String Dim volNumber, MCM, FSF As Long Driver = \"c:\\\" Dim res As Long

Linux下获取CPUID、硬盘序列号与 MAC地址

Linux下获取CPUID、硬盘序列号与 MAC地址 在很多系统软件的开发中,需要使用一些系统的唯一性信息。所以,得到主机的CPUID、硬盘序列号及网卡的MAC地址,就成个一件很重要的应用。 本人经过一番google即自己的钻研,基本上实现了这几个功能。需要的准备知识有: 1.GCC的嵌入汇编,具体的GCC嵌入汇编知识,请参考相关手册 2.ioctl系统调用,具体的调用方法,请查看手册页 获取CPUID 按照网上提供的说明,CPUID并不是所有的Intel CPU都支持的。如果支持,汇编调用为:eax置0000_0003,调用cpuid。 以下为实现代码(在我的CPU上,并没有得到): #define cpuid(in,a,b,c,d) asm("cpuid": "=a" (a), "=b" (b), "=c" (c), "=d" (d) : "a" (in)); static int getcpuid (char *id, size_t max) { int i; unsigned long li, maxi, maxei, ebx, ecx, edx, unused; cpuid (0, maxi, unused, unused, unused); maxi &= 0xffff; if (maxi < 3) { return -1; } cpuid (3, eax, ebx, ecx, edx); snprintf (id, max, "%08lx %08lx %08lx %08lx", eax, ebx, ecx, edx); fprintf (stdout, "get cpu id: %s\n", id); return 0; } 获取硬盘序列号 这个的实现,采用的是读取/etc/mtab文件,找到/(即根目录)挂载的设备文件,然后打开它,再用系统调用 ioctl来实现的。 ioctl第二个参数为HDIO_GET_IDENTITY, 获得指定文件描述符的标志号 ioctl的第三个参数为struct hd_driveid *,在linux/hdreg.h中,struct hd_driveid 的声明有 struct hd_driveid { unsigned short config; /* lots of obsolete bit flags */ unsigned short cyls; /* Obsolete, "physical" cyls */ unsigned short reserved2; /* reserved (word 2) */ unsigned short heads; /* Obsolete, "physical" heads */ unsigned short track_bytes; /* unformatted bytes per track */ unsigned short sector_bytes; /* unformatted bytes per sector */ unsigned short sectors; /* Obsolete, "physical" sectors per track */ unsigned short vendor0; /* vendor unique */ unsigned short vendor1; /* vendor unique */

如何得到硬盘序列号[C#]

如何得到硬盘序列号[C#] 部门: xxx 时间: xxx 整理范文,仅供参考,可下载自行编辑

硬盘序列号来获取硬盘信息,而不需要写VXD或者DRIVER。这样这个问题就解决了,我对它进行了封装,大量使用了P/Invoke技术,一个完整的Library。支持Windows 98-2003。b5E2RGbCAP 使用上很简单: HardDiskInfo hdd = AtapiDevice.GetHddInfo(0>。 // 第一个硬盘p1EanqFDPw Console.WriteLine("Module Number: {0}", hdd.ModuleNumber>。DXDiTa9E3d Console.WriteLine("Serial Number: {0}", hdd.SerialNumber>。RTCrpUDGiT Console.WriteLine("Firmware: {0}", hdd.Firmware>。Console.WriteLine("Capacity: {0} M", hdd.Capacity>。5PCzVD7HxA 下面是全部代码:

硬盘序列号识别

硬盘序列号识别 一、希捷(Seagate) ST“X,XXXX,XX,XXX”,也就是说其硬盘编号可以分为四部分。 首先,“ST”代表的是“Seagate”,也就是说是希捷公司的产品。 然后第一部分的“X”是表示其硬盘外形和尺寸。“1”表示3.5英寸,厚度为41mm的全高硬盘;“3”表示3.5英寸,厚度为25mm的半高硬盘;“4”表示5.25英寸,厚度为82mm的硬盘;“5”表示尺寸为3.5英寸,厚度为19mm 的硬盘;“9”表示为尺寸2.5英寸的硬盘。 第二部分的四个“X”是表示硬盘的容量,通常由3到4位数字组成,单位是GB。如:“1600”就是表示这硬盘的容量为160GB,而“400”或者“800”就表示其容量为40GB或者80GB了。 第三部分的两个“X”为硬盘标志,由主标志和副标志所组成。前一个数字是主标志,在Seagate的IDE硬盘中都是指硬盘的碟片数,如数字“2”则表示该硬盘采用了2张盘片。而在Seagate的SCSI硬盘中,其主标识则是指硬盘的转速了。有了主标识当然就会有副标识了,而后一个数字就是副标识。它是只有当主标识相同或者无效时,副标识才有意义。它一般代表硬盘的性能和代数,当数字越大,表示的代数越高,性能越好,此款硬盘也就越新。 第三部分的三个“X”主要由1到3个字母所组成,表示硬盘接口类型等。一般的桌面IDE硬盘较为简单,但如果包括了现在和早期的SCSI硬盘的话,其含义就变得较为复杂了。 “A”表示为ATA UDMA/33或UDMA/66 IDE的接口 “AS”表示为Serial ATA150的接口 “AG”表示为笔记本电脑专用的ATA的接口 “N”表示为50针Ultra SCSI的接口,其数据传输率为20MB/s “W”表示为68针Ultra SCSI接口,其数据传输率为40MB/s “WC”表示为80针Ultra SCSI的接口 “FC”表示为光纤,可提供高达100MB/s的数据传输率,并且支持热拔插 “WD”表示为68针Ultra Wide SCSI的接口 “LW”表示为68针Ultra-2 SCSI(LVD)的接口 “LC”表示为80针Ultra-2 SCSI(LVD)的接口 我们以Seagate酷鱼硬盘“ST3160023AS”为例子,通过例子的编号我们可以知道该硬盘是希捷公司生产的3.5英寸厚度为25mm的半高硬盘,其采用2张硬盘盘片,总容量是160GB的Serial ATA150。另外,如果你看到硬盘上印刷着“7200.7”等字符的,就说明这是希捷新推出的单碟容量80GB的硬盘系列;看到“Barracuda 7200.7 Plus”等字符,我们就了解到了这个系列的产品是采用8MB缓存,Serial ATA 150接口或者Ultra ATA 100接口的高端产品 二、三星(SAMSUNG) 目前三星硬盘均属SpinPoint系列,此系列又分为P和V两大类。编号标注形式为“系列型号+转速+容量+缓存+磁头数目+接口类型”。 我们亦可以简单的表示为“X,X,XXX,X,X”五部分。 第一部分的“X”表示硬盘产品系列。这里的“S”就表示为“SpinPoint”系列。 第二部分的“X”表示三星硬盘各系列不同转速的产品。 “V”表示V系列硬盘,转速为5400 RPM/分 “P”表示P系列硬盘,转速为7200 RPM/分

C语言获得硬盘序列号

C++获取硬盘序列号 #include #include #include #pragma argsused #define DFP_GET_VERSION 0x00074080 #define DFP_SEND_DRIVE_COMMAND 0x0007c084 #define DFP_RECEIVE_DRIVE_DA TA 0x0007c088 //#pragma pack(1) 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, *LPGETVERSIONOU TPARAMS; 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 _DRIVERSTA TUS { BYTE bDriverError; // Error code from driver, // or 0 if no error. BYTE bIDEStatus; // Contents of IDE Error register. // Only valid when bDriverError

C#程序获得cpu,硬盘的序列号

使用c#获得cpu,硬盘的序列号(源码) 出处:https://www.360docs.net/doc/7a2467440.html, //首先在项目中选中右键“引用”→“添加引用”→打开一个界面,切换到.NET选项卡,添//加System.Management“确定”即可。如下图: using System; using System.Runtime.InteropServices; using System.Management; namespace Hardware { ///

/// Hardware_Mac 的摘要说明。 /// public class HardwareInfo { //取机器名 public string GetHostName() {

return https://www.360docs.net/doc/7a2467440.html,.Dns.GetHostName(); } //取CPU编号 public String GetCpuID() { try { ManagementClass mc = new ManagementClass("Win32_Processor"); ManagementObjectCollection moc = mc.GetInstances(); String strCpuID = null ; foreach( ManagementObject mo in moc ) { strCpuID = mo.Properties["ProcessorId"].Value.ToString(); break; } return strCpuID; } catch { return ""; } }//end method //取第一块硬盘编号 public String GetHardDiskID() { try

获取硬盘序列号

用api函数读取硬盘的序列号 关于盘序列号有两种: 硬盘序列号: 英文名Hard Disk Serial Number, 该号是出厂时生产厂家 为 区别产品而设置的, 是唯一的, 是只读的, 利用硬盘序列号的 加密往往是利用其唯一和只读的特性, 大多是针对有序列号的 IDE HDD而言, 对于没有序列号或SCSI HDD硬盘则无能为力, 这也是利用它进行加密的局限性. 卷的序列号: 英文名Volume Serial Number, 该号既可指软磁盘要 得, 如: A:盘和B:盘的, 又可以指硬盘的逻辑盘, 如: C:, D:...的, 是高级格式化时随机产生的, 是可以修改的, 所以利用其进行 加密, 在写程序时我们想对每一台计算机都生成一个唯一的标识,而且在一此共享软件中我们也看到,软件在不同的机器上生成了不同的标识,这是如何实现的呢,其实是软件有一部分程序读取了,本地计算机的一部分硬件参数(如硬盘序列号,网卡序列号等等),再通过一系列算法而得到了一个唯一标识,其实我们也可以通过一个api函数生成我们的唯一标识,由于硬盘人人都有,而网卡不一定每个人都有,所以以读硬盘序列号为例, 下面就先介绍一下我们要用到的api函数 BOOL GetVolumeInformation( LPCTSTR lpRootPathName, // 硬盘的路径 LPTSTR lpVolumeNameBuffer, // 硬盘的卷标 DWORD nVolumeNameSize, // 卷标的字符串长度 LPDWORD lpVolumeSerialNumber, // 硬盘的序列号 LPDWORD lpMaximumComponentLength, // 最大的文件长度 LPDWORD lpFileSystemFlags, // 文件系统的一此标志 LPTSTR lpFileSystemNameBuffer, // 存储所在盘符的分区类型的长指针变量DWORD nFileSystemNameSize // 分区类型的长指针变量所指向的字符串长度 ); 如果上述函数成功就返回一个非0值。 光说不做,是不行了,我们还得实践一下:// 最大的文件长度 首选用MFC AppWizard建立一个基于Dialog base的对话框工程,名为GetHardID,点击finish。 加一个按钮,双击它,点击ok,并在对应的函数中加入如下代码: LPCTSTR lpRootPathName="c:\\"; //取C盘 LPTSTR lpVolumeNameBuffer=new char[12];//磁盘卷标 DWORD nVolumeNameSize=12;// 卷标的字符串长度 DWORD VolumeSerialNumber;//硬盘序列号 DWORD MaximumComponentLength;// 最大的文件长度 LPTSTR lpFileSystemNameBuffer=new char[10];// 存储所在盘符的分区类型的长

硬盘参数读取程序 - 硬盘型号、容量、序列号、固件版本等for Windows 98MENT2000XP

文件示意图: //--------------------------------------------------------------------------- #include #pragma hdrstop //--------------------------------------------------------------------------- USEFORM("UnitHdDisk.cpp", FormHdParams); //--------------------------------------------------------------------------- WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)

{ try { Application->Initialize(); Application->CreateForm(__classid(TFormHdParams), &FormHdParams); Application->Run(); } catch (Exception &exception) { Application->ShowException(&exception); } catch (...) { try { throw Exception(""); } catch (Exception &exception) { Application->ShowException(&exception); }

} return 0; } //--------------------------------------------------------------------------- /*-------------------------------------------------------------------------*\ | | | IDE 硬盘参数读取程序| | ~~~~~~~~~~~~~~~~~~~~ | | Copyright (C) 1997-2003, Victor Chen | | Email: victor@https://www.360docs.net/doc/7a2467440.html, | | Homepage: https://www.360docs.net/doc/7a2467440.html, | |

关于VC获取硬盘序列号

【注意】本文代码可以在XP系统下成功,但在WIN7 系统中不行,因为WIN7 对直接打开磁盘驱动器做了限制,必须要管理员授权。否则以普通用户身份运行会在CreateFile 时返回INV ALID_HANDLE_V ALUE(5:没有权限),从而无法获取硬盘序列号。如何在WIN7 下面不需要以管理员身份运行就可以得到硬盘序列号呢,因为涉及一些软件保护的敏感信息,故暂不在此处发表。 网上有不少相关的问题回答和博客,帖子,讲到这件事。不过我比较不满的是很多人他们都不会说自己的代码是否参考,引用,也不说原创。而且我发现他们有照搬别人的代码的嫌疑。比如说检出序列号字符串的那个辅助函数(好像叫做 ConvertToString),其实这个实现主要是用于颠倒字节顺序,但是它的实现方式就是合理的吗,效率上是可以的吗,代码是优美的吗?在我看来老外这里用的方法不合理。而且它把WORD 数组先灌入一个DWORD 数组,然后再调用ConvertToString 这样的函数去做字节转化,在我看来完全是脱裤子放屁,闲的蛋疼。而且里面用了一个1KB 的static 数组去存储结果,在返回这个地址,让调用方去把结果拷走,你不拷走会发生什么后果呢,你下次再调用,这个地址里的内容又变了。所以这样一个函数如果不看实现,光给你这么一个原型声明(char* ConvertToString...),是一定会让用户发生困惑的。你返给我的是个什么地址,该地址是持久的吗?需要我去释放吗?而我们中国人可倒是好,直接Copy 过来,也不看。好一点的中国人还会大概看一下这个步骤,罗列出具体步骤,不好的就直接把代码贴上去了,他根本也不问也不管里面的代码是什么啊!而那代码我看起来不爽,所以我调试通过以后就想改成比较正确的适合别人使用的方式。 为此,我参考了一些资料。当然,里面有的细节我还没有完全弄明白,比如SENDCMDINPARAMS 里有一些寄存器变量,这个是输入的参数,可是要我怎么设呢,MSDN 网站也语焉不详,为此我只能照搬原来的代码,因为不明细节,所以也只能如此了。 最早我看那个辅助函数就觉得很奇怪,为什么要调用这个辅助函数呢,后来我看了另一个中国人的博客,他指出是对返回的数据的WORD 里面的字节序做调整。所以我才明白这个函数原来主要是把字节进行两两颠倒,好比一串连续的字节:01 23 45 67 89,必须转接成10 32 54 76 98 这个样子。因为识别设备返回值是一个WORD [256] 数组(512 Bytes),应用程序调用DeviceIoControl 像设备驱动程序发送命令(识别设备),然后DeviceIoControl 把结果填充到这个WORD 数组。这个WORD 数组就是驱动程序给出的识别设备的结果,具体是哪个设备,主要是由提供给DeviceIoControl 的第一个参数(设备句柄)来甄别的,设备句柄通过CreateFile 获得。哪么识别设备的结果是256 个WORD(相当于uint16),哪么他们的含义是如何规定的呢,这个属于ATA / ATAPI 的技术标准,是一个统一规定,内容可以搜索网络,有三份文档(PDF文档)详细给出了A TA/ATAPI 的技术规范,当然不同的资料上你会看到里面给出的定义还略微不同,应该是历史发展的原因。也就是这个标准规定了比如WORD 数组里哪些是硬盘的序列号等,所以你会看到代码里有通过对硬编码的WORD 数组索引范围,获取相关信息。现在你就知道了,这些索引值,都是这些文档里的规定。ATA、ATAPI 是什么呢,英文大概是AT Attachment with Packet Interface ,我们不去管它了。 下面是我对网络上那些代码进行修改后得到的代码,是一个win32 console 程序。没有那么多废话,可读性,可用性比网络上的代码更好(你可以看到我整理后的代码非常简短)。当然,如果我们把硬盘序列号作为分发软件时绑定物理硬件使用,实际上就没必要再去做调

改变硬盘序列号码的方法

改变硬盘序列号码的方法 硬盘的号码有时候是需要改变的,这是因为有些软件的许可证号码是和硬盘号码有关系的。 更改硬盘号的步骤: (1)一般需要使用windows启动盘启动计算机。 (2)使用VOL命令,查看欲修改的硬盘序列号码,并用笔记录。 例如: 该硬盘号码为0B3214E7 (2)启动Debug (3)使用L命令将硬盘中存放硬盘序列号放入开始地址为100的内存中。 命令格式L 内存开始地址驱动器代码开始扇区扇区数 其中:内存开始地址一般为100 驱动器代码A盘------0 B盘------1 C盘------2 D盘------3 开始扇区磁盘序列号放在0扇区 扇区数取一个扇区就可以 例:L 100 2 0 1 表示将C盘的第0扇区放入开始地址为100的内存中 (4)使用D命令观察内存内容 命令格式:D[地址] 例: D 100表示将内存地址为100的内容显示到屏幕上

(5)在屏幕上找硬盘序列号,將记录的硬盘号码与显示的内容相比较,找硬盘号的地址 例如,硬盘号码是0B3214E7, 经过比较,可知硬盘序列号的地址是143,144,145和146 注意:各个计算机的硬盘号码所在地址不同,都需要通过比较的方法寻找 找到后,可以输入命令:D 143 以确定号码地址的正确性。 (5) 修改硬盘号码,将修改的硬盘号码写入内存。 命令格式:E 地址内容 其中:地址为欲修改内存的地址 内容为修改后的内容,在这里是硬盘号码,如果要将硬盘号码修改为22e75628 则输入: E 143 28 E 144 56 E 145 e7

E 146 22 (6)使用写入命令将内存中内容写入硬盘 命令格式:W 内存开始地址驱动器代码开始扇区扇区数 其中,内存开始地址、驱动器代码、开始扇区、扇区数,应该和L命令的参数一致,这一点非常重要,否则硬盘就不能使用了。 下图表示了全过程: (7)使用Q命令退出DEBUG,启动计算机后,再用VOL命令检查硬盘序列号,可以观察到硬盘号已经变了。

获取硬盘物理序列号

获取硬盘物理序列号 最近才做完了这个获取IDE 硬盘物理序列号的程序。声明一下,这个程序是我根据Lynn McGuire 的那个DiskID32 的源代码做了些自以为是的改动得到的,只能在NT 平台下获得第一块IDE 硬盘的物理序列号。同时,这个程序用到了不少未公开的Windows 的结构和常量...... 下面就是相应的C++ 代码,在XP SP2 + VC 2005 Express 下调试通过。 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 == INV ALID_HANDLE_V ALUE) { // 错误处理 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)) { // 错误处理 return ; } if (VersionParams.bIDEDeviceMap<=0) { // 错误处理 return ; } BYTE bIDCmd = 0; SENDCMDINPARAMS scip; bIDCmd = (VersionParams.bIDEDeviceMap >> 0 & 0x10) ? IDE_ATAPI_IDENTIFY : IDE_A TA_IDENTIFY; memset (&scip, 0, sizeof(scip)); memset (IdOutCmd, 0, sizeof(IdOutCmd)); scip.cBufferSize=IDENTIFY_BUFFER_SIZE;

相关主题
相关文档
最新文档