hardinfo.cpp
来自「“取CPU和硬盘ID值” 在Windows 98平台下编译成功」· C++ 代码 · 共 733 行 · 第 1/2 页
CPP
733 行
// HardInfo.cpp: implementation of the CHardInfo class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "GatAll.h"
#include "HardInfo.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
__declspec(naked) void /*CHardInfo::*/ 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
}
}
__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
}
}
CHardInfo::CHardInfo()
{
memset(&Hard_Info,0,sizeof(Hard_Info));
IsWinIoInitialized = false;
getHardDriveComputerID();
}
CHardInfo::~CHardInfo()
{
}
int CHardInfo::ReadPhysicalDriveInNT (void)
{
int done = FALSE;
int drive = 0;
for (drive = 0; drive < MAX_IDE_DRIVES; drive++)
{
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)
// 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) )
{
// printf ("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;
//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];
PrintIdeInfo (drive, diskdata);
done = TRUE;
}
}
CloseHandle (hPhysicalDriveIOCTL);
}
}
return done;
}
// DoIDENTIFY
// FUNCTION: Send an IDENTIFY command to the drive
// bDriveNum = 0-3
// bIDCmd = IDE_ATA_IDENTIFY or IDE_ATAPI_IDENTIFY
BOOL CHardInfo::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 CHardInfo::IsWinNT()
{
OSVERSIONINFO OSVersionInfo;
OSVersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
GetVersionEx(&OSVersionInfo);
return OSVersionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT;
}
bool CHardInfo::InitializeWinIo()
{
char szExePath[MAX_PATH];
PSTR pszSlash;
IsNT = IsWinNT();
if (IsNT)
{
if (!GetModuleFileName(GetModuleHandle(NULL), szExePath, sizeof(szExePath)))
return false;
pszSlash = strrchr(szExePath, '\\');
if (pszSlash)
pszSlash[1] = 0;
else
return false;
strcat(szExePath, "winio.sys");
// UnloadDeviceDriver("WINIO");
// if (!LoadDeviceDriver("WINIO", szExePath, &hDriver))
// return false;
}
IsWinIoInitialized = true;
return true;
}
void CHardInfo::ShutdownWinIo()
{
// if (IsNT)
// UnloadDeviceDriver("WINIO");
}
// This function makes it possible to call ring 0 code from a ring 3
// application.
bool CHardInfo::CallRing0(PVOID pvRing0FuncAddr, WORD wPortAddr, PDWORD pdwPortVal, BYTE bSize)
{
struct GDT_DESCRIPTOR *pGDTDescriptor;
struct GDTR gdtr;
WORD CallgateAddr[3];
WORD wGDTIndex = 1;
_asm Sgdt [gdtr]
// Skip the null descriptor
pGDTDescriptor = (struct GDT_DESCRIPTOR *)(gdtr.dwGDTBase + 8);
// Search for a free GDT descriptor
for (wGDTIndex = 1; wGDTIndex < (gdtr.wGDTLimit / 8); wGDTIndex++)
{
if (pGDTDescriptor->Type == 0 &&
pGDTDescriptor->System == 0 &&
pGDTDescriptor->DPL == 0 &&
pGDTDescriptor->Present == 0)
{
// Found one !
// Now we need to transform this descriptor into a callgate.
// Note that we're using selector 0x28 since it corresponds
// to a ring 0 segment which spans the entire linear address
// space of the processor (0-4GB).
struct CALLGATE_DESCRIPTOR *pCallgate;
pCallgate = (struct CALLGATE_DESCRIPTOR *) pGDTDescriptor;
pCallgate->Offset_0_15 = LOWORD(pvRing0FuncAddr);
pCallgate->Selector = 0x28;
pCallgate->ParamCount = 0;
pCallgate->Unused = 0;
pCallgate->Type = 0xc;
pCallgate->System = 0;
pCallgate->DPL = 3;
pCallgate->Present = 1;
pCallgate->Offset_16_31 = HIWORD(pvRing0FuncAddr);
// Prepare the far call parameters
CallgateAddr[0] = 0x0;
CallgateAddr[1] = 0x0;
CallgateAddr[2] = (wGDTIndex << 3) | 3;
// Please fasten your seat belts!
// We're about to make a hyperspace jump into RING 0.
_asm Mov DX, [wPortAddr]
_asm Mov EBX, [pdwPortVal]
_asm Mov CL, [bSize]
_asm Call FWORD PTR [CallgateAddr]
// We have made it !
// Now free the GDT descriptor
memset(pGDTDescriptor, 0, 8);
// Our journey was successful. Seeya.
return true;
}
// Advance to the next GDT descriptor
pGDTDescriptor++;
}
// Whoops, the GDT is full
return false;
}
bool CHardInfo::GetPortVal(WORD wPortAddr, PDWORD pdwPortVal, BYTE bSize)
{
bool Result;
DWORD dwBytesReturned;
struct tagPort32Struct Port32Struct;
if (IsNT)
{
if (!IsWinIoInitialized)
return false;
Port32Struct.wPortAddr = wPortAddr;
Port32Struct.bSize = bSize;
if (!DeviceIoControl(hDriver, IOCTL_WINIO_READPORT, &Port32Struct,
sizeof( tagPort32Struct), &Port32Struct,
sizeof(struct tagPort32Struct),
&dwBytesReturned, NULL))
return false;
else
*pdwPortVal = Port32Struct.dwPortVal;
}
else
{
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?