?? diskserialnumber.cpp
字號(hào):
// DiskSerialNumber.cpp : implementation file
//
#include "stdafx.h"
#include "DiskSerialNumber.h"
#include <winioctl.h>
#include "port32.h"
#include "winio.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
// These are our ring 0 functions responsible for tinkering with the hardware ports.
// They have a similar privilege to a Windows VxD and are therefore free to access
// protected system resources (such as the page tables) and even place calls to
// exported VxD services.
__declspec(naked) void Ring0GetPortVal()
{
_asm
{
Cmp CL, 1
Je ByteVal
Cmp CL, 2
Je WordVal
Cmp CL, 4
Je DWordVal
ByteVal:
In AL, DX
Mov [EBX], AL
Retf
WordVal:
In AX, DX
Mov [EBX], AX
Retf
DWordVal:
In EAX, DX
Mov [EBX], EAX
Retf
}
}
__declspec(naked) void Ring0SetPortVal()
{
_asm
{
Cmp CL, 1
Je ByteVal
Cmp CL, 2
Je WordVal
Cmp CL, 4
Je DWordVal
ByteVal:
Mov AL, [EBX]
Out DX, AL
Retf
WordVal:
Mov AX, [EBX]
Out DX, AX
Retf
DWordVal:
Mov EAX, [EBX]
Out DX, EAX
Retf
}
}
/////////////////////////////////////////////////////////////////////////////
// CDiskSerialNumber
CDiskSerialNumber::CDiskSerialNumber()
{
IsWinIoInitialized = FALSE;
}
CDiskSerialNumber::~CDiskSerialNumber()
{
}
/////////////////////////////////////////////////////////////////////////////
// CDiskSerialNumber message handlers
BOOL CDiskSerialNumber::ReadPhysicalDriveInNT()
{
BOOL done = FALSE;
HANDLE hPhysicalDriveIOCTL = 0;
// Try to get a handle to PhysicalDrive IOCTL, report failure
// and exit if can't.
char driveName [256] = _T("\\\\.\\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)
{
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))
{
// printf (_T("DFP_GET_VERSION failed for drive %d\n"), i);
// continue;
}
// 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 >> 0 & 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)0, &cbBytesReturned))
{
DWORD diskdata [256];
int ijk = 0;
USHORT *pIdSector = (USHORT *)((PSENDCMDOUTPARAMS)IdOutCmd)->bBuffer;
for(ijk = 0; ijk < 256; ijk++)
diskdata [ijk] = pIdSector [ijk];
strcpy(HardDriveSerialNumber, ConvertToString(diskdata, 10, 19));
done = TRUE;
}
}
CloseHandle(hPhysicalDriveIOCTL);
}
return done;
}
// Send an IDENTIFY command to the drive
// bDriveNum = 0-3
// bIDCmd = IDE_ATA_IDENTIFY or IDE_ATAPI_IDENTIFY
BOOL CDiskSerialNumber::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 *CDiskSerialNumber::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;
}
long CDiskSerialNumber::GetDiskSerialNo()
{
__int64 id = GetHardDriveSerialNumber();
if(id <= 0)
id = GetSoftDriveSerialNumber();
else // make sure no bigger than 16^7
if(id > 268435455) id %= 268435456;
id ^= 0x01076032;
return (long)id;
}
long CDiskSerialNumber::GetSoftDriveSerialNumber()
{
// Get driver c: serial number
LPCTSTR lpRootPathName = _T("c:\\");
// Get volume label
LPTSTR lpVolumeNameBuffer = new char[12];
DWORD nVolumeNameSize = 12;
DWORD VolumeSerialNumber; // soft driver serial number
DWORD MaximumComponentLength;
LPTSTR lpFileSystemNameBuffer = new char[10];
DWORD nFileSystemNameSize = 10;
DWORD FileSystemFlags;
GetVolumeInformation(lpRootPathName, lpVolumeNameBuffer,
nVolumeNameSize,&VolumeSerialNumber, &MaximumComponentLength,
&FileSystemFlags, lpFileSystemNameBuffer, nFileSystemNameSize);
return VolumeSerialNumber;
}
__int64 CDiskSerialNumber::GetHardDriveSerialNumber()
{
BOOL done = FALSE;
__int64 id = 0;
strcpy (HardDriveSerialNumber, _T(""));
// this works under WinNT4 or Win2K if you have admin rights
done = ReadPhysicalDriveInNT();
// this should work in WinNT or Win2K if previous did not work
// this is kind of a backdoor via the SCSI mini port driver into
// the IDE drives
if(!done) done = ReadIdeDriveAsScsiDriveInNT();
// this works under Win9X and calls WINIO.DLL
if(!done) done = ReadDrivePortsInWin9X();
if(done)
{
char *p = HardDriveSerialNumber;
// WriteConstantString ("HardDriveSerialNumber", HardDriveSerialNumber);
// ignore first 5 characters from western digital hard drives if
// the first four characters are WD-W
if(!strncmp(HardDriveSerialNumber, _T("WD-W"), 4)) p += 5;
for( ; p && *p; p++)
{
if('-' == *p) continue;
id *= 10;
switch (*p)
{
case '0': id += 0; break;
case '1': id += 1; break;
case '2': id += 2; break;
case '3': id += 3; break;
case '4': id += 4; break;
case '5': id += 5; break;
case '6': id += 6; break;
case '7': id += 7; break;
case '8': id += 8; break;
case '9': id += 9; break;
case 'a': case 'A': id += 10; break;
case 'b': case 'B': id += 11; break;
case 'c': case 'C': id += 12; break;
case 'd': case 'D': id += 13; break;
case 'e': case 'E': id += 14; break;
case 'f': case 'F': id += 15; break;
case 'g': case 'G': id += 16; break;
case 'h': case 'H': id += 17; break;
case 'i': case 'I': id += 18; break;
case 'j': case 'J': id += 19; break;
case 'k': case 'K': id += 20; break;
case 'l': case 'L': id += 21; break;
case 'm': case 'M': id += 22; break;
case 'n': case 'N': id += 23; break;
case 'o': case 'O': id += 24; break;
case 'p': case 'P': id += 25; break;
case 'q': case 'Q': id += 26; break;
case 'r': case 'R': id += 27; break;
case 's': case 'S': id += 28; break;
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -