ZeroMemory(&vers,sizeof(vers));
//We start in NT/Win2000
for (j=0;j<4;j++){
wsprintf(hd,"\\\\.\\PhysicalDrive%d",j);
h=CreateFile(hd,GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE,0,OPEN_EXISTING,0,0);
if (!h){
continue;
}
if (!DeviceIoControl(h,DFP_GET_VERSION,0,0,&vers,sizeof(vers),&i,0)){
CloseHandle(h);
continue;
}
//If IDE identify command not supported, fails
if (!(vers.fCapabilities&1)){
MessageBox("Error: IDE identify command not supported.");
CloseHandle(h);
return;
}
//Identify the IDE drives
ZeroMemory(&in,sizeof(in));
ZeroMemory(&out,sizeof(out));
if (j&1){
in.irDriveRegs.bDriveHeadReg=0xb0;
}else{
in.irDriveRegs.bDriveHeadReg=0xa0;
}
if (vers.fCapabilities&(16>>j)){
//We don't detect a ATAPI device.
continue;
}else{
in.irDriveRegs.bCommandReg=0xec;
}
in.bDriveNumber=j;
in.irDriveRegs.bSectorCountReg=1;
in.irDriveRegs.bSectorNumberReg=1;
in.cBufferSize=512;
if (!DeviceIoControl(h,DFP_RECEIVE_DRIVE_DATA,&in,sizeof(in),&out,sizeof(out),&i,0)){
MessageBox("DeviceIoControl failed:DFP_RECEIVE_DRIVE_DATA");
CloseHandle(h);
return;
}
phdinfo[i]=(PIDSECTOR)out.bBuffer;
//#pragma pack(1)
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;
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;
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;
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;
typedef struct _SENDCMDOUTPARAMS {
DWORD cBufferSize; // Size of bBuffer in bytes
DRIVERSTATUS DriverStatus; // Driver status structure.
BYTE bBuffer[512]; // Buffer of arbitrary length
// in which to store the data read from the drive.
} SENDCMDOUTPARAMS, *PSENDCMDOUTPARAMS, *LPSENDCMDOUTPARAMS;
struct GDT_DESCRIPTOR
{
WORD Limit_0_15;
WORD Base_0_15;
BYTE Base_16_23;
BYTE Type : 4;
BYTE System : 1;
BYTE DPL : 2;
BYTE Present : 1;
BYTE Limit_16_19 : 4;
BYTE Available : 1;
BYTE Reserved : 1;
BYTE D_B : 1;
BYTE Granularity : 1;
BYTE Base_24_31;
};
struct CALLGATE_DESCRIPTOR
{
WORD Offset_0_15;
WORD Selector;
WORD ParamCount : 5;
WORD Unused : 3;
WORD Type : 4;
WORD System : 1;
WORD DPL : 2;
WORD Present : 1;
WORD Offset_16_31;
};
// Define the various device type values. Note that values used by Microsoft
// Corporation are in the range 0-32767, and 32768-65535 are reserved for use
// by customers.
#ifndef WINIO_H
#define WINIO_H
#define FILE_DEVICE_WINIO 0x00008010
// Macro definition for defining IOCTL and FSCTL function control codes.
// Note that function codes 0-2047 are reserved for Microsoft Corporation,
// and 2048-4095 are reserved for customers.
result = ::RegQueryValueEx (hKey, _T("VendorIdentifier"), NULL, NULL,
(LPBYTE)vendorData, &dataSize);
m_stVendorInfo.Format ("%s", vendorData);
}
// Make sure to close the reg key
RegCloseKey (hKey);
// Get the hardware information
GetSystemInfo (&sysInfo);
// Lets check the processor type first
if (sysInfo.dwProcessorType == PROCESSOR_INTEL_386) {
m_stProcessorType = _T ("Intel 386");
}
else if (sysInfo.dwProcessorType == PROCESSOR_INTEL_486) {
m_stProcessorType = _T ("Intel 486");
}
else if (sysInfo.dwProcessorType == PROCESSOR_INTEL_PENTIUM) {
m_stProcessorType = _T ("Intel Pentium");
}
else if (sysInfo.dwProcessorType == PROCESSOR_MIPS_R4000) {
// only for NT
m_stProcessorType = _T ("MIPS");
}
else if (sysInfo.dwProcessorType == PROCESSOR_ALPHA_21064) {
// only for NT
m_stProcessorType = _T ("Alpha");
}
else {
m_stProcessorType = _T ("Unknown");
}
// check number of processors
itoa (sysInfo.dwNumberOfProcessors , str, 10);
m_stNumProcessors = CString (str);
// Check the architecture type and processor level
// Windows 95 doesn't use processor level
if (sysInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL) {
m_stArchitecture = _T ("Pentium");
switch (sysInfo.wProcessorLevel) {
case 3:
m_stProcessorLevel = _T ("Intel 80386");
break;
case 4:
m_stProcessorLevel = _T ("Intel 80486");
break;
case 5:
m_stProcessorLevel = _T ("Pentium");
// Check if the MMX instruction set is availbale or not.