⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jun.txt

📁 用C++编的一个硬盘ID获得程序
💻 TXT
字号:
#include <stdio.h> 
#include <stdlib.h> 
#include <windows.h> 


// 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 

// 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]; 
char strHDSerialNumber[1024]; 
DWORD diskData[256]; 

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) 
   ); 
} 

BOOL ReadPhysicalDriveInNT(void) 
{ 
BOOL bRet = FALSE; 

HANDLE hPhysicalDriveIOCTL = 0; 
int drive = 0; 

// Try to get a handle to PhysicalDrive IOCTL, 
// report failure and exit if can't. 
char driveName [256]; 

sprintf(driveName, "\\\\.\\PhysicalDrive0"); 

// 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 ) 
{ 
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 
) 
  ) 
{ 
} 

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

// 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 
) 
  ) 
{ 
memset(diskData, 0, 1024); 
int i = 0; 

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

for( i = 0; i < 256; i++ ) 
diskData[i] = pIdSector[i]; 

bRet = TRUE; 
} 
} 

CloseHandle(hPhysicalDriveIOCTL); 
} 

return bRet; 
} 





//============================================================= 
// DoIDENTIFY 
// FUNCTION: Send an IDENTIFY command to the drive 
// bDriveNum = 0-3 
// bIDCmd = IDE_ATA_IDENTIFY or IDE_ATAPI_IDENTIFY 
//============================================================== 
#define  SENDIDLENGTH  sizeof (SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE 

BOOL ReadIdeDriveAsScsiDriveInNT(void) 
{ 
BOOL bRet = FALSE; 
int controller = 0; 

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; 

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] ) 
{ 
memset(diskData, 0, 1024); 
int i = 0; 
USHORT *pIdSector = (USHORT *)pId; 

for( i = 0; i < 256; i++ ) 
diskData[i] = pIdSector[i]; 

bRet = TRUE; 
} 
} 
CloseHandle (hScsiDriveIOCTL); 
} 

return bRet; 
} 

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; index--){ 
if(string[index]!=' ') break; 
else  string[index]=0; 
} 
for(index = 0; index < position; index++) 
if(string[index]!=' ') break; 
if(index!=0){ 
strncpy(string,string+index,position-index); 
string[position-index]=0; 
} 

return string; 
} 

BOOL GetHDSerialCode(char* lpSerialID) 
{ 
if( lpSerialID == NULL ) 
return FALSE; 

memset(strHDSerialNumber, 0, 1024); 

BOOL bRet; 

bRet = ReadPhysicalDriveInNT(); 

if( !bRet ) 
bRet = ReadIdeDriveAsScsiDriveInNT(); 

if( bRet ) 
{ 
strcpy( strHDSerialNumber 
  , ConvertToString(diskData, 10, 19) 
  ); 

try 
{ 
strcpy(lpSerialID, strHDSerialNumber); 
} 
catch(...) 
{ 
return FALSE; 
} 
} 

return bRet; 
} 

void main(void) 
{ 
char strSerialNumber[16]; 
memset(strSerialNumber, 0, 16); 

BOOL bRet = GetHDSerialCode(strSerialNumber); 

if( bRet ) 
printf("SerialNumber=%s\n",strSerialNumber); 
} 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -