在新建的工程里面添加一個類
即:以下一個類
GetHDSerial.cpp
#include "stdafx.h"
#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,
0x1f7in al, dxcmp al,
0x80jb Endwaitingjmp Waiting}
Endwaiting:_asm{mov byTemp, al}
return byTemp;
}
void _declspec( naked )InterruptProcess(
void)
{
int byTemp;
int i;WORD temp;_asm{push eaxpush ebxpush ecxpush edxpush esi}WaitHardDiskIdle();_asm{mov dx,
0x1f6mov al,
0xa0out dx, al}byTemp = WaitHardDiskIdle();
if ((byTemp&
0x50)!=
0x50) {_asm {pop esipop edxpop ecxpop ebxpop eaxiretd}}_asm{mov dx,
0x1f6 mov al,
0xa0out dx, alinc dxmov al,
0xecout dx, al } byTemp = WaitHardDiskIdle();
if ((byTemp&
0x58)!=
0x58) {_asm {pop esipop edxpop ecxpop ebxpop eaxiretd}}
for (i=
0;i<
256;i++) {_asm{mov dx,
0x1f0in ax, dxmov temp, ax}m_serial[i] = temp; } _asm{pop esipop edxpop ecxpop ebxpop eaxiretd}
}
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){ WORD m_wWin9xHDSerial[
256];Win9xReadHDSerial(m_wWin9xHDSerial); strcpy (m_buffer, WORDToChar (m_wWin9xHDSerial,
10,
19));}
else{DWORD m_wWinNTHDSerial[
256];
if ( ! WinNTReadIDEHDSerial(m_wWinNTHDSerial)) WinNTReadSCSIHDSerial(m_wWinNTHDSerial); strcpy (m_buffer, DWORDToChar (m_wWinNTHDSerial,
10,
19));}
return m_buffer;
}
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+
04hclipush ecxmov ecx,dword ptr [eax]mov cx,word ptr [eax-
04h]mov dword ptr m_OldInterruptAddress,ecxpop ecxpush ebxlea ebx,InterruptProcess mov word ptr [eax-
04h],bxshr ebx,
10hmov word ptr [eax+
02h],bxpop ebx
int 3hpush ecxmov ecx,dword ptr m_OldInterruptAddressmov word ptr [eax-
04h],cxshr ecx,
10hmov word ptr [eax+
02h],cxpop ecxstipop eax}
for(i=
0;i<
256;i++) buffer[i]=m_serial[i];
}
char * CGetHDSerial::WORDToChar (WORD diskdata [
256],
int firstIndex,
int lastIndex)
{
static char string [
1024];
int index =
0;
int position =
0;
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;
}
char* CGetHDSerial::DWORDToChar (DWORD diskdata [
256],
int firstIndex,
int lastIndex)
{
static char string [
1024];
int index =
0;
int position =
0;
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;
}
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 (driveName,
"\\\\.\\PhysicalDrive%d", drive);hPhysicalDriveIOCTL = CreateFileA (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;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; SENDCMDINPARAMS scip;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;
}
BOOL CGetHDSerial::WinNTReadSCSIHDSerial (DWORD * buffer)
{ buffer[
0]=
'\n';
int controller =
0;HANDLE hScsiDriveIOCTL =
0;
char driveName [
256];sprintf (driveName,
"\\\\.\\Scsi%d:", controller);hScsiDriveIOCTL = CreateFileA (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 ((
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]){
int n =
0;USHORT *pIdSector = (USHORT *) pId;
for (n =
0; n <
256; n++)buffer[n] =pIdSector [n];
return TRUE; }}}CloseHandle (hScsiDriveIOCTL); }
return FALSE;
}
BOOL CGetHDSerial::WinNTGetIDEHDInfo (HANDLE hPhysicalDriveIOCTL, PSENDCMDINPARAMS 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) );
}
GetHDSerial.h
#include <windows.h>
#include <stdio.h>#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 _DRIVERSTATUS
{BYTE bDriverError; BYTE bIDEStatus; BYTE bReserved[
2]; DWORD dwReserved[
2];
} DRIVERSTATUS, *PDRIVERSTATUS, *LPDRIVERSTATUS;typedef
struct _SENDCMDOUTPARAMS
{DWORD cBufferSize; DRIVERSTATUS DriverStatus; BYTE bBuffer[
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
{DWORD cBufferSize; IDEREGS irDriveRegs; BYTE bDriveNumber; BYTE bReserved[
3]; DWORD dwReserved[
4]; BYTE bBuffer[
1];
} SENDCMDINPARAMS, *PSENDCMDINPARAMS, *LPSENDCMDINPARAMS;
typedef
struct _GETVERSIONOUTPARAMS
{BYTE bVersion; BYTE bRevision; BYTE bReserved; BYTE bIDEDeviceMap; DWORD fCapabilities; DWORD dwReserved[
4];
} 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);
};
源碼下載
總結
以上是生活随笔為你收集整理的MFC获取电脑硬盘序列号(附源码)的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。