📄 如何获得硬盘序列号(1).htm
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<!-- saved from url=(0051)http://www3.ccw.com.cn/club/essence/200110/6643.htm -->
<HTML><HEAD><TITLE>如何获得硬盘序列号(1)</TITLE>
<META content="text/html; charset=gb2312" http-equiv=Content-Type>
<META content="MSHTML 5.00.2614.3500" name=GENERATOR></HEAD>
<BODY>
<P style="FONT-SIZE: 26px; FONT-WEIGHT: bold">如何获得硬盘序列号(1)</P>
<P style="FONT-SIZE: 18px; FONT-WEIGHT: bold; TEXT-INDENT: 20px">cyberghost</P>
<P style="FONT-SIZE: 12px; TEXT-ALIGN: right">C、C++ (2001-10-30 12:38:11)
<HR style="COLOR: #000000; HEIGHT: 1px">
<P></P>
<DIV style="FONT-SIZE: 12px">#include <stdio.h> <BR>#include
<stdlib.h> <BR>#include <windows.h> <BR><BR><BR>// Required to
ensure correct PhysicalDrive IOCTL structure setup <BR>#pragma pack(1)
<BR><BR>#define IDENTIFY_BUFFER_SIZE 512 <BR><BR>// IOCTL
commands
<BR>#define DFP_GET_VERSION 0x00074080
<BR>#define DFP_SEND_DRIVE_COMMAND 0x0007c084
<BR>#define DFP_RECEIVE_DRIVE_DATA 0x0007c088
<BR><BR>#define FILE_DEVICE_SCSI 0x0000001b
<BR>#define IOCTL_SCSI_MINIPORT_IDENTIFY ((FILE_DEVICE_SCSI
<< 16) + 0x0501) <BR>#define IOCTL_SCSI_MINIPORT 0x0004D008
// see NTDDSCSI.H for definition <BR><BR>// GETVERSIONOUTPARAMS
contains the data returned from the <BR>// Get Driver Version function.
<BR>typedef struct _GETVERSIONOUTPARAMS <BR>{ <BR> BYTE
bVersion; // Binary driver version.
<BR> BYTE bRevision; // Binary
driver revision. <BR> BYTE
bReserved; // Not used. <BR> BYTE
bIDEDeviceMap; // Bit map of IDE devices. <BR> DWORD
fCapabilities; // Bit mask of driver capabilities. <BR> DWORD
dwReserved[4]; // For future use. <BR>}GETVERSIONOUTPARAMS,
*PGETVERSIONOUTPARAMS, *LPGETVERSIONOUTPARAMS; <BR><BR>// Bits returned in the
fCapabilities member of GETVERSIONOUTPARAMS
<BR>#define CAP_IDE_ID_FUNCTION 1 //
ATA ID command supported
<BR>#define CAP_IDE_ATAPI_ID 2 //
ATAPI ID command supported
<BR>#define CAP_IDE_EXECUTE_SMART_FUNCTION 4 //
SMART commannds supported <BR><BR>// IDE registers <BR>typedef struct _IDEREGS
<BR>{ <BR> BYTE
bFeaturesReg; // Used for specifying SMART
"commands". <BR> BYTE
bSectorCountReg; // IDE sector count register
<BR> BYTE bSectorNumberReg; // IDE sector
number register <BR> BYTE
bCylLowReg; // IDE low
order cylinder value <BR> BYTE
bCylHighReg; // IDE high order
cylinder value <BR> BYTE
bDriveHeadReg; // IDE drive/head register
<BR> BYTE
bCommandReg; // Actual IDE
command. <BR> BYTE
bReserved; //
reserved for future use. Must be zero. <BR>}IDEREGS, *PIDEREGS, *LPIDEREGS;
<BR><BR>// SENDCMDINPARAMS contains the input parameters for the <BR>// Send
Command to Drive function. <BR>typedef struct _SENDCMDINPARAMS <BR>{
<BR> DWORD cBufferSize; //
Buffer size in bytes
<BR> IDEREGS irDriveRegs; //
Structure with drive register values. <BR> BYTE
bDriveNumber; // Physical drive number
to send <BR> //
command to (0,1,2,3). <BR> BYTE
bReserved[3]; // Reserved for future
expansion. <BR> DWORD dwReserved[4]; //
For future use.
<BR> BYTE bBuffer[1]; //
Input buffer. <BR>}SENDCMDINPARAMS, *PSENDCMDINPARAMS, *LPSENDCMDINPARAMS;
<BR><BR>// Valid values for the bCommandReg member of IDEREGS.
<BR>#define IDE_ATAPI_IDENTIFY 0xA1 // Returns
ID sector for ATAPI.
<BR>#define IDE_ATA_IDENTIFY 0xEC //
Returns ID sector for ATA. <BR><BR>// Status returned from driver <BR>typedef
struct _DRIVERSTATUS <BR>{
<BR> BYTE bDriverError; // Error code
from driver, or 0 if no error.
<BR> BYTE bIDEStatus; //
Contents of IDE Error register.
<BR> // Only valid
when bDriverError is SMART_IDE_ERROR.
<BR> BYTE bReserved[2]; // Reserved for
future expansion. <BR> DWORD dwReserved[2];//
Reserved for future expansion. <BR>}DRIVERSTATUS, *PDRIVERSTATUS,
*LPDRIVERSTATUS; <BR><BR>// Structure returned by PhysicalDrive IOCTL for
several commands <BR>typedef struct _SENDCMDOUTPARAMS <BR>{
<BR> DWORD cBufferSize; //
Size of bBuffer in bytes
<BR> DRIVERSTATUS DriverStatus; // Driver
status structure.
<BR> BYTE bBuffer[1]; //
Buffer of arbitrary length <BR>// in which to store the data <BR>// read from
the drive. <BR>}SENDCMDOUTPARAMS, *PSENDCMDOUTPARAMS, *LPSENDCMDOUTPARAMS;
<BR><BR>// The following struct defines the interesting part of the IDENTIFY
<BR>// buffer: <BR>typedef struct _IDSECTOR <BR>{
<BR> USHORT wGenConfig;
<BR> USHORT wNumCyls;
<BR> USHORT wReserved;
<BR> USHORT wNumHeads;
<BR> USHORT wBytesPerTrack;
<BR> USHORT wBytesPerSector;
<BR> USHORT wSectorsPerTrack;
<BR> USHORT wVendorUnique[3];
<BR> CHAR sSerialNumber[20];
<BR> USHORT wBufferType;
<BR> USHORT wBufferSize;
<BR> USHORT wECCSize;
<BR> CHAR sFirmwareRev[8];
<BR> CHAR sModelNumber[40];
<BR> USHORT wMoreVendorUnique;
<BR> USHORT wDoubleWordIO;
<BR> USHORT wCapabilities;
<BR> USHORT wReserved1;
<BR> USHORT wPIOTiming;
<BR> USHORT wDMATiming; <BR> USHORT wBS;
<BR> USHORT wNumCurrentCyls;
<BR> USHORT wNumCurrentHeads;
<BR> USHORT wNumCurrentSectorsPerTrack;
<BR> ULONG ulCurrentSectorCapacity;
<BR> USHORT wMultSectorStuff;
<BR> ULONG ulTotalAddressableSectors;
<BR> USHORT wSingleWordDMA;
<BR> USHORT wMultiWordDMA;
<BR> BYTE bReserved[128]; <BR>}IDSECTOR,
*PIDSECTOR; <BR><BR>typedef struct _SRB_IO_CONTROL <BR>{
<BR> ULONG HeaderLength; <BR> UCHAR
Signature[8]; <BR> ULONG Timeout; <BR> ULONG
ControlCode; <BR> ULONG ReturnCode; <BR> ULONG
Length; <BR>}SRB_IO_CONTROL, *PSRB_IO_CONTROL; <BR><BR>// Define global buffers.
<BR>BYTE IdOutCmd [sizeof(SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE - 1];
<BR>char strHDSerialNumber[1024]; <BR>DWORD diskData[256]; <BR><BR>BOOL
DoIDENTIFY( HANDLE hPhysicalDriveIOCTL <BR> , PSENDCMDINPARAMS
pSCIP <BR> , PSENDCMDOUTPARAMS pSCOP <BR> , BYTE
bIDCmd <BR> , BYTE bDriveNum <BR> , PDWORD
lpcbBytesReturned <BR> ) <BR>{ <BR>// Set up data structures
for IDENTIFY command. <BR>pSCIP->cBufferSize = IDENTIFY_BUFFER_SIZE;
<BR>pSCIP->irDriveRegs.bFeaturesReg = 0;
<BR>pSCIP->irDriveRegs.bSectorCountReg = 1;
<BR>pSCIP->irDriveRegs.bSectorNumberReg = 1;
<BR>pSCIP->irDriveRegs.bCylLowReg = 0; <BR>pSCIP->irDriveRegs.bCylHighReg
= 0; <BR><BR>// Compute the drive number.
<BR>pSCIP->irDriveRegs.bDriveHeadReg = 0xA0 | ((bDriveNum & 1) <<
4); <BR><BR>// The command can either be IDE identify or ATAPI identify.
<BR>pSCIP->irDriveRegs.bCommandReg = bIDCmd; <BR>pSCIP->bDriveNumber =
bDriveNum; <BR>pSCIP->cBufferSize = IDENTIFY_BUFFER_SIZE; <BR><BR>return
(DeviceIoControl( hPhysicalDriveIOCTL <BR> ,
DFP_RECEIVE_DRIVE_DATA <BR> , (LPVOID) pSCIP
<BR> , sizeof(SENDCMDINPARAMS) - 1 <BR> ,
(LPVOID) pSCOP <BR> , sizeof(SENDCMDOUTPARAMS) +
IDENTIFY_BUFFER_SIZE - 1 <BR> , lpcbBytesReturned, NULL)
<BR> ); <BR>} <BR><BR>BOOL ReadPhysicalDriveInNT(void) <BR>{
<BR>BOOL bRet = FALSE; <BR><BR>HANDLE hPhysicalDriveIOCTL = 0; <BR>int drive =
0; <BR><BR>// Try to get a handle to PhysicalDrive IOCTL, <BR>// report failure
and exit if can't. <BR>char driveName [256]; <BR><BR>sprintf(driveName,
"\\\\.\\PhysicalDrive0"); <BR><BR>// Windows NT, Windows 2000, must have admin
rights <BR>hPhysicalDriveIOCTL = CreateFile( driveName <BR>, GENERIC_READ |
GENERIC_WRITE <BR>, FILE_SHARE_READ | FILE_SHARE_WRITE <BR>, NULL <BR>,
OPEN_EXISTING <BR>, 0 <BR>, NULL <BR>); <BR><BR>// if (hPhysicalDriveIOCTL ==
INVALID_HANDLE_VALUE) <BR>// printf ("Unable to open
physical drive %d, error code: 0x%lX\n",
<BR>// drive,
GetLastError ()); <BR><BR>if( hPhysicalDriveIOCTL != INVALID_HANDLE_VALUE )
<BR>{ <BR>GETVERSIONOUTPARAMS VersionParams;
<BR>DWORD cbBytesReturned
= 0; <BR><BR>// Get the version, etc of PhysicalDrive IOCTL
<BR>memset((void*)&VersionParams, 0, sizeof(VersionParams)); <BR><BR>if(
!DeviceIoControl( hPhysicalDriveIOCTL <BR>, DFP_GET_VERSION <BR>, NULL <BR>, 0
<BR>, &VersionParams <BR>, sizeof(VersionParams) <BR>, &cbBytesReturned
<BR>, NULL <BR>) <BR> ) <BR>{ <BR>} <BR><BR>// If there is a IDE
device at number "i" issue commands <BR>// to the device <BR>if(
VersionParams.bIDEDeviceMap > 0 ) <BR>{
<BR>BYTE bIDCmd = 0;
// IDE or ATAPI IDENTIFY cmd <BR>SENDCMDINPARAMS scip; <BR><BR>//
Now, get the ID sector for all IDE devices in the <BR>// system. If the device
is ATAPI use the <BR>// IDE_ATAPI_IDENTIFY command, otherwise use the <BR>//
IDE_ATA_IDENTIFY command <BR>bIDCmd = (VersionParams.bIDEDeviceMap >>
drive & 0x10) ? \
<BR> IDE_ATAPI_IDENTIFY
: IDE_ATA_IDENTIFY; <BR><BR>memset (&scip, 0, sizeof(scip)); <BR>memset
(IdOutCmd, 0, sizeof(IdOutCmd)); <BR><BR>if( DoIDENTIFY( hPhysicalDriveIOCTL
<BR> , &scip <BR> , (PSENDCMDOUTPARAMS)&IdOutCmd
<BR> , (BYTE)bIDCmd <BR> , (BYTE)drive <BR> ,
&cbBytesReturned <BR>) <BR> ) <BR>{ <BR>memset(diskData, 0,
1024); <BR>int i = 0; <BR><BR>USHORT *pIdSector = (USHORT *)
<BR>((PSENDCMDOUTPARAMS)IdOutCmd)->bBuffer; <BR><BR>for( i = 0; i < 256;
i++ ) <BR>diskData[i] = pIdSector[i]; <BR><BR>bRet = TRUE; <BR>} <BR>}
<BR><BR>CloseHandle(hPhysicalDriveIOCTL); <BR>} <BR><BR>return bRet; <BR>}
<BR>因为程序太大,分两篇。 <BR><BR></DIV>
<P>
<HR style="COLOR: #000000; HEIGHT: 1px">
<DIV style="FONT-SIZE: 12px; TEXT-ALIGN: right">i社区原文:<A
href="http://www3.ccw.com.cn/club/bbs/bbsView.asp?essenceID=6643"
target=_blank>如何获得硬盘序列号(1)</A></DIV>
<P></P></BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -