📄 getharddriveid.cpp
字号:
// GetScsiHardDriveID.cpp: implementation of the CGetScsiHardDriveID class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "GetHardDriveID.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CGetScsiHardDriveID::CGetScsiHardDriveID()
{
}
CGetScsiHardDriveID::~CGetScsiHardDriveID()
{
}
////////////////////////////////////////////////////////////////////////////////
//
// 自加的
//
////////////////////////////////////////////////////////////////////////////////
// HWID.cpp: implementation of the HWID class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
//#include "PCInfo.h"
#include "GetHardDriveID.h"
#include <winioctl.h>
#include <stdio.h>
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
// Define global buffers.
BYTE IdOutCmd [sizeof (SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE - 1];
BOOL IsWinNT()//判断是否NT
{
OSVERSIONINFO OSVersionInfo;
OSVersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
GetVersionEx(&OSVersionInfo);
return OSVersionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT;
}
BOOL IsNT = IsWinNT();
void TrimRight(char * psString)
{
int len = strlen(psString);
for (int i = len - 1; i >= 0; --i)
{
if (psString[i] != ' ')
break;
// continue;
psString[i] = '\0';
}
}
char _szInfo[1024];
BOOL GetHardDiskID(char szBuff[128])
{
DRIVER_INFO_OK io = {0};
if (IsNT)
strcat(_szInfo, "NT[yes]\r\n");
else
strcat(_szInfo, "NT[no]\r\n");
if (IsNT)
ReadPhysicalDriveInNT(0, &io);
else
ReadDrivePortsInWin9X(0, &io);
TrimRight(io.ModalNumber);
TrimRight(io.SerialNumber);
TrimRight(io.ControlNum);
if ( (!io.ModalNumber[0])
&& (!io.SerialNumber[0])
&& (!io.ControlNum[0]))
{
if (IsNT)
{
ReadIdeDriveAsScsiDriveInNT(0, &io);//拿SCSI硬盘ID
strcat(_szInfo, "[ReadIdeDriveAsScsiDriveInNT]\r\n");
TrimRight(io.ModalNumber);
TrimRight(io.SerialNumber);
TrimRight(io.ControlNum);
if ( (!io.ModalNumber[0])
&& (!io.SerialNumber[0])
&& (!io.ControlNum[0]))
return FALSE;
}
}
sprintf(szBuff, "%s", io.SerialNumber); //,io.ControlNum );
// strcat(_szInfo, "HDSN[");
// strcat(_szInfo, szBuff);
// strcat(_szInfo, "]\r\n");
return TRUE;
}
#include "nb30.h"
// Define the various device type values. Note that values used by Microsoft
// Corporation are in the range 0-32767, and 32768-65535 are reserved for use
// by customers.
#define FILE_DEVICE_WINIO 0x00008010
// Macro definition for defining IOCTL and FSCTL function control codes.
// Note that function codes 0-2047 are reserved for Microsoft Corporation,
// and 2048-4095 are reserved for customers.
#define WINIO_IOCTL_INDEX 0x810
// Define our own private IOCTL
#define IOCTL_WINIO_WRITEPORT CTL_CODE(FILE_DEVICE_WINIO, \
WINIO_IOCTL_INDEX + 2, \
METHOD_BUFFERED, \
FILE_ANY_ACCESS)
#define IOCTL_WINIO_READPORT CTL_CODE(FILE_DEVICE_WINIO, \
WINIO_IOCTL_INDEX + 3, \
METHOD_BUFFERED, \
FILE_ANY_ACCESS)
struct tagPort32Struct
{
USHORT wPortAddr;
ULONG dwPortVal;
UCHAR bSize;
};
struct tagPort32Struct Port32Struct;
// DoIDENTIFY
// FUNCTION: Send an IDENTIFY command to the drive
// bDriveNum = 0-3
// bIDCmd = IDE_ATA_IDENTIFY or IDE_ATAPI_IDENTIFY
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;
// 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 * ConvertToString (DWORD diskdata [256], int firstIndex, int lastIndex)
{
static char string [1024];
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
string [position] = (char) (diskdata [index] / 256);
position++;
// get low byte for 2nd character
string [position] = (char) (diskdata [index] % 256);
position++;
}
// end the string
string [position] = '\0';
// cut off the trailing blanks
for (index = position - 1; index > 0 && ' ' == string [index]; index--)
string [index] = '\0';
return string;
}
BOOL ReadPhysicalDriveInNT(const int idrive,PDRIVE_INFO_OK buf)
{
BOOL done = 0;
int drive = 0;
drive = idrive;
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)
{
//MessageBox(0,"OK","OK",MB_YESNOCANCEL);
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) )
{
done = FALSE; //设备打开错误
}
// If there is a IDE device at number "i" issue commands
// to the device
if (VersionParams.bIDEDeviceMap > 0)
{
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];
//将diskdata中的硬盘信息保存到buf中
buf->Heads = diskdata[3];
buf->Cylinders = diskdata[1];
buf->Sectors = diskdata[6];
strcpy(buf->ControlNum , ConvertToString(diskdata,23,26));
strcpy(buf->SerialNumber , ConvertToString(diskdata,10,19));
strcpy(buf->ModalNumber , ConvertToString(diskdata,27,46));
if (diskdata [0] & 0x0080)
buf->DriveType = 0; //可移动驱动器
else if (diskdata [0] & 0x0040)
buf->DriveType = 0; //固定驱动器
done = TRUE;
}
}
CloseHandle (hPhysicalDriveIOCTL);
}
return done;
}
#define SENDIDLENGTH sizeof (SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE
BOOL ReadIdeDriveAsScsiDriveInNT(const int idrive,PDRIVE_INFO_OK buf)
{
// AfxMessageBox("ReadIdeDriveAsScsiDriveInNT");
BOOL done = FALSE;
int controller = 0;
for (controller = 0; controller < 4; controller++)
{
HANDLE hScsiDriveIOCTL = 0;
char driveName [256];
// Try to get a handle to PhysicalDrive IOCTL, report failure
// and exit if can't.
//sprintf (driveName, "\\\\.\\Scsi%d:", controller);
// Windows NT, Windows 2000, any rights should do
hScsiDriveIOCTL = CreateFile (driveName,
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%lX\n",
controller, GetLastError ());
if (hScsiDriveIOCTL != INVALID_HANDLE_VALUE)
{
int drive = 0;
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));
DWORD dummy;
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;
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])
{
DWORD diskdata [256];
int ijk = 0;
USHORT *pIdSector = (USHORT *) pId;
for (ijk = 0; ijk < 256; ijk++)
diskdata [ijk] = pIdSector [ijk];
buf->Heads = diskdata[3];
buf->Cylinders = diskdata[1];
buf->Sectors = diskdata[6];
strcpy(buf->ControlNum , ConvertToString(diskdata,23,26));
strcpy(buf->SerialNumber , ConvertToString(diskdata,10,19));
strcpy(buf->ModalNumber , ConvertToString(diskdata,27,46));
if (diskdata [0] & 0x0080)
buf->DriveType = 0; //可移动驱动器
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -