我是靠谱客的博主 优秀胡萝卜,最近开发中收集的这篇文章主要介绍hd获取硬盘序列号_<转>另一个获取硬盘序列号的方法,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

#defineDFP_GET_VERSION0x00074080

#defineFILE_DEVICE_SCSI0x0000001b

#defineIOCTL_SCSI_MINIPORT_IDENTIFY((FILE_DEVICE_SCSI << 16 ) + 0x0501)

#defineIOCTL_SCSI_MINIPORT0x0004D008

#defineIDENTIFY_BUFFER_SIZE512

#defineSENDIDLENGTH(sizeof (SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE)

#defineIDE_ATAPI_IDENTIFY0xA1

#defineIDE_ATA_IDENTIFY0xEC

#defineDFP_RECEIVE_DRIVE_DATA0x0007c088

typedef struct _IDSECTOR

{

USHORTwGenConfig;

USHORTwNumCyls;

USHORTwReserved;

USHORTwNumHeads;

USHORTwBytesPerTrack;

USHORTwBytesPerSector;

USHORTwSectorsPerTrack;

USHORTwVendorUnique[3];

CHARsSerialNumber[20];

USHORTwBufferType;

USHORTwBufferSize;

USHORTwECCSize;

CHARsFirmwareRev[8];

CHARsModelNumber[40];

USHORTwMoreVendorUnique;

USHORTwDoubleWordIO;

USHORTwCapabilities;

USHORTwReserved1;

USHORTwPIOTiming;

USHORTwDMATiming;

USHORTwBS;

USHORTwNumCurrentCyls;

USHORTwNumCurrentHeads;

USHORTwNumCurrentSectorsPerTrack;

ULONGulCurrentSectorCapacity;

USHORTwMultSectorStuff;

ULONGulTotalAddressableSectors;

USHORTwSingleWordDMA;

USHORTwMultiWordDMA;

BYTEbReserved[128];

}IDSECTOR, *PIDSECTOR;

//typedef struct _DRIVERSTATUS

//{

//BYTEbDriverError;

//BYTEbIDEStatus;

//BYTEbReserved[2];

//DWORDdwReserved[2];

//

//}DRIVERSTATUS, *PDRIVERSTATUS, *LPDRIVERSTATUS;

//typedef struct _SENDCMDOUTPARAMS

//{

//DWORDcBufferSize;

//DRIVERSTATUSDriverStatus;

//BYTEbBuffer[1];

//}SENDCMDOUTPARAMS, *PSENDCMDOUTPARAMS, *LPSENDCMDOUTPARAMS;

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 _IDEREGS

//{//

//BYTE bFeaturesReg;

//BYTE bSectorCountReg;

//BYTE bSectorNumberReg;

//BYTE bCylLowReg;

//BYTE bCylHighReg;

//BYTE bDriveHeadReg;

//BYTE bCommandReg;

//BYTE bReserved;

//

//}IDEREGS, *PIDEREGS, *LPIDEREGS;

//typedef struct _SENDCMDINPARAMS

//{

//DWORDcBufferSize;

//IDEREGSirDriveRegs;

//BYTE bDriveNumber;

//BYTE bReserved[3];

//DWORDdwReserved[4];

//BYTEbBuffer[1];

//}SENDCMDINPARAMS, *PSENDCMDINPARAMS, *LPSENDCMDINPARAMS;

typedef struct _GETVERSIONOUTPARAMS

{

BYTE bVersion;

BYTE bRevision;

BYTE bReserved;

BYTE bIDEDeviceMap;

DWORD fCapabilities;

DWORD dwReserved[4];

}GETVERSIONOUTPARAMS, *PGETVERSIONOUTPARAMS, *LPGETVERSIONOUTPARAMS;

typedef struct _UNICODE_STRING

{

USHORTLength;

USHORTMaximumLength;

PWSTRBuffer;

}UNICODE_STRING,*PUNICODE_STRING;

typedef struct _OBJECT_ATTRIBUTES

{

ULONG Length;

HANDLE RootDirectory;

PUNICODE_STRING ObjectName;

ULONG Attributes;

PVOID SecurityDescriptor;

PVOID SecurityQualityOfService;

}OBJECT_ATTRIBUTES;

typedef OBJECT_ATTRIBUTES *POBJECT_ATTRIBUTES;

// 函数指针

typedef DWORD(__stdcall *ZWOS )( PHANDLE,ACCESS_MASK,POBJECT_ATTRIBUTES);

typedef DWORD(__stdcall *ZWMV )( HANDLE,HANDLE,PVOID,ULONG,ULONG,PLARGE_INTEGER,PSIZE_T,DWORD,ULONG,ULONG);

typedef DWORD(__stdcall *ZWUMV )( HANDLE,PVOID);

BOOL WinNTHDSerialNumAsScsiRead(BYTE* dwSerial, UINT* puSerialLen, UINT uMaxSerialLen)

{

BOOL bInfoLoaded = FALSE;

for (int iController = 0; iController < 2; ++iController)

{

HANDLE hScsiDriveIOCTL = 0;

char szDriveName[256];

sprintf( szDriveName, "\\.\Scsi%d:", iController );

//Windows NT, Windows 2000, any rights should do

hScsiDriveIOCTL = CreateFile(szDriveName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);

// if (hScsiDriveIOCTL == INVALID_HANDLE_VALUE)

//printf ("Unable to open SCSI controller %d, error code: 0x%lXn",

//controller, GetLastError ());

if( hScsiDriveIOCTL != INVALID_HANDLE_VALUE )

{

int iDrive = 0;

for (iDrive = 0; iDrive < 2; ++ iDrive)

{

char szBuffer[sizeof (SRB_IO_CONTROL) + SENDIDLENGTH] = { 0 };

SRB_IO_CONTROL* p = ( SRB_IO_CONTROL* )szBuffer;

SENDCMDINPARAMS* pin = ( SENDCMDINPARAMS* )( szBuffer + sizeof (SRB_IO_CONTROL));

DWORD dwResult;

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 = iDrive;

if (DeviceIoControl(hScsiDriveIOCTL, IOCTL_SCSI_MINIPORT, szBuffer, sizeof (SRB_IO_CONTROL) + sizeof (SENDCMDINPARAMS) - 1, szBuffer, sizeof (SRB_IO_CONTROL) + SENDIDLENGTH, &dwResult, NULL))

{

SENDCMDOUTPARAMS* pOut = (SENDCMDOUTPARAMS*) (szBuffer + sizeof( SRB_IO_CONTROL));

IDSECTOR* pId = (IDSECTOR*) (pOut->bBuffer);

if (pId->sModelNumber[0])

{

if (* puSerialLen + 20U <= uMaxSerialLen)

{

CopyMemory(dwSerial + * puSerialLen, ((USHORT*) pId) + 10, 20);

// Cut off the trailing blanks

for (UINT i = 20; i != 0U && ' ' == dwSerial[* puSerialLen + i - 1]; --i);

* puSerialLen += i;

CopyMemory( dwSerial + * puSerialLen, ( ( USHORT* )pId ) + 27, 40 );

// Cut off the trailing blanks

for( i = 40; i != 0U && ' ' == dwSerial[* puSerialLen + i - 1]; -- i );

* puSerialLen += i;

bInfoLoaded = TRUE;

}

else

{

::CloseHandle( hScsiDriveIOCTL );

return bInfoLoaded;

}

}

}

}

::CloseHandle( hScsiDriveIOCTL );

}

}

return bInfoLoaded;

}

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

// calc 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);

}

BOOL WinNTHDSerialNumAsPhysicalRead( BYTE* dwSerial, UINT* puSerialLen, UINT uMaxSerialLen )

{

BOOL bInfoLoaded = FALSE;

for (UINT uDrive = 0; uDrive < 4; ++ uDrive)

{

HANDLE hPhysicalDriveIOCTL = 0;

//Try to get a handle to PhysicalDrive IOCTL, report failure

//and exit if can't.

char szDriveName [256];

sprintf( szDriveName, "\\.\PhysicalDrive%d", uDrive );

//Windows NT, Windows 2000, must have admin rights

hPhysicalDriveIOCTL = CreateFile(szDriveName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);

if (hPhysicalDriveIOCTL != INVALID_HANDLE_VALUE)

{

GETVERSIONOUTPARAMS VersionParams = { 0 };

DWORDcbBytesReturned = 0;

// Get the version, etc of PhysicalDrive IOCTL

if( DeviceIoControl( hPhysicalDriveIOCTL, DFP_GET_VERSION, NULL, 0, &VersionParams, sizeof (GETVERSIONOUTPARAMS), &cbBytesReturned, NULL))

{

// If there is a IDE device at number "i" issue commands

// to the device

if (VersionParams.bIDEDeviceMap != 0)

{

BYTEbIDCmd = 0;// IDE or ATAPI IDENTIFY cmd

SENDCMDINPARAMSscip = { 0 };

// 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 >> uDrive & 0x10) ? IDE_ATAPI_IDENTIFY : IDE_ATA_IDENTIFY;

BYTE IdOutCmd[sizeof( SENDCMDOUTPARAMS ) + IDENTIFY_BUFFER_SIZE - 1] = { 0 };

if (DoIdentify( hPhysicalDriveIOCTL, &scip, (PSENDCMDOUTPARAMS)&IdOutCmd, (BYTE)bIDCmd, (BYTE)uDrive, &cbBytesReturned))

{

if (* puSerialLen + 20U <= uMaxSerialLen)

{

CopyMemory(dwSerial + * puSerialLen, ((USHORT*)(((PSENDCMDOUTPARAMS )IdOutCmd )->bBuffer)) + 10, 20);// 序列号

// Cut off the trailing blanks

for (UINT i = 20; i != 0U && ' ' == dwSerial[* puSerialLen + i - 1]; --i);

* puSerialLen += i;

CopyMemory(dwSerial + * puSerialLen, ((USHORT*)(((PSENDCMDOUTPARAMS)IdOutCmd )->bBuffer)) + 27, 40); // 型号

// Cut off the trailing blanks

for (i = 40; i != 0U && ' ' == dwSerial[* puSerialLen + i - 1]; -- i);

* puSerialLen += i;

bInfoLoaded = TRUE;

}

else

{

::CloseHandle( hPhysicalDriveIOCTL );

return bInfoLoaded;

}

}

}

}

CloseHandle( hPhysicalDriveIOCTL );

}

}

return bInfoLoaded;

}

// 如何获取硬盘序列好

// 结果存放在 disk_info.txt 文件中

void GetDiskSuquenceID()

{

UINT uSystemInfoLen;

BYTE szSystemInfo[1024] = { 0 };

OSVERSIONINFO ovi = { 0 };

ovi.dwOSVersionInfoSize = sizeof( OSVERSIONINFO );

GetVersionEx( &ovi );

if( ovi.dwPlatformId != VER_PLATFORM_WIN32_NT )

// 获取不到硬盘序列号信息,返回

return;

if( !WinNTHDSerialNumAsPhysicalRead(szSystemInfo, &uSystemInfoLen, 1024))

WinNTHDSerialNumAsScsiRead(szSystemInfo, &uSystemInfoLen, 1024);

// 以写追加的方式打开保存结果的文件

FILE *pf = fopen("./disk_info.txt", "a+");

// 检测文件指针的有效性

assert(NULL != pf);

if (NULL == pf)

return;

// 把硬盘序列号写入文件

fprintf(pf, "ndisk sequence info is %sn",szSystemInfo );

// 关闭文件

fclose(pf);

}

最后

以上就是优秀胡萝卜为你收集整理的hd获取硬盘序列号_<转>另一个获取硬盘序列号的方法的全部内容,希望文章能够帮你解决hd获取硬盘序列号_<转>另一个获取硬盘序列号的方法所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(74)

评论列表共有 0 条评论

立即
投稿
返回
顶部