📄 getharddriveid.cpp
字号:
else if (diskdata [0] & 0x0040)
buf->DriveType = 0; //固定驱动器
done = TRUE;
}
}
}
CloseHandle (hScsiDriveIOCTL);
}
}
return done;
}
HANDLE hDriver;
BOOL IsWinIoInitialized = FALSE;
bool InitializeWinIo()
{
char szExePath[MAX_PATH];
PSTR pszSlash;
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;
}
#ifdef WINIO_DLL
#define PORT32API _declspec(dllexport)
#else
#define PORT32API _declspec(dllimport)
#endif
#pragma pack(1)
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;
};
struct GDTR
{
WORD wGDTLimit;
DWORD dwGDTBase;
};
#pragma pack()
// This function makes it possible to call ring 0 code from a ring 3
// application.
bool 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;
}
__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
}
}
bool 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(struct tagPort32Struct), &Port32Struct,
sizeof(struct tagPort32Struct),
&dwBytesReturned, NULL))
return false;
else
*pdwPortVal = Port32Struct.dwPortVal;
}
else
{
Result = CallRing0((PVOID)Ring0GetPortVal, wPortAddr, pdwPortVal, bSize);
if (Result == false)
return false;
}
return true;
}
__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
}
}
bool SetPortVal(WORD wPortAddr, DWORD dwPortVal, BYTE bSize)
{
DWORD dwBytesReturned;
struct tagPort32Struct Port32Struct;
if (IsNT)
{
if (!IsWinIoInitialized)
return false;
Port32Struct.wPortAddr = wPortAddr;
Port32Struct.dwPortVal = dwPortVal;
Port32Struct.bSize = bSize;
if (!DeviceIoControl(hDriver, IOCTL_WINIO_WRITEPORT, &Port32Struct,
sizeof(struct tagPort32Struct), NULL, 0, &dwBytesReturned, NULL))
return false;
}
else
return CallRing0((PVOID)Ring0SetPortVal, wPortAddr, &dwPortVal, bSize);
return true;
}
BOOL ReadDrivePortsInWin9X (int idrive, PDRIVE_INFO_OK buf)
{
int done = FALSE;
int drive = 0;
InitializeWinIo ();
// Get IDE Drive info from the hardware ports
// loop thru all possible drives
//for (drive = 0; drive < 8; drive++)
drive = idrive;
DWORD diskdata [256];
WORD baseAddress = 0; // Base address of drive controller
DWORD portValue = 0;
int waitLoop = 0;
int index = 0;
switch (drive / 2)
{
case 0: baseAddress = 0x1f0; break;
case 1: baseAddress = 0x170; break;
case 2: baseAddress = 0x1e8; break;
case 3: baseAddress = 0x168; break;
}
// Wait for controller not busy
waitLoop = 10000;
while (--waitLoop > 0)
{
GetPortVal ((WORD) (baseAddress + 7), &portValue, (BYTE) 1);
// drive is ready
if ((portValue & 0x40) == 0x40) break;
// previous drive command ended in error
if ((portValue & 0x01) == 0x01) break;
}
//if (waitLoop < 1) continue;
// Set Master or Slave drive
if ((drive % 2) == 0)
SetPortVal ((WORD) (baseAddress + 6), 0xA0, 1);
else
SetPortVal ((WORD) (baseAddress + 6), 0xB0, 1);
// Get drive info data
SetPortVal ((WORD) (baseAddress + 7), 0xEC, 1);
// Wait for data ready
waitLoop = 10000;
while (--waitLoop > 0)
{
GetPortVal ((WORD) (baseAddress + 7), &portValue, 1);
// see if the drive is ready and has it's info ready for us
if ((portValue & 0x48) == 0x48) break;
// see if there is a drive error
if ((portValue & 0x01) == 0x01) break;
}
// check for time out or other error
//if (waitLoop < 1 || portValue & 0x01) continue;
// read drive id information
for (index = 0; index < 256; index++)
{
diskdata [index] = 0; // init the space
GetPortVal (baseAddress, &(diskdata [index]), 2);
}
//将diskdata中的硬盘信息保存到buf中
buf->Heads = diskdata[3];
buf->Cylinders = diskdata[1];
buf->Sectors = diskdata[6];
strcpy(buf->ControlNum , ConvertToString(diskdata,23,26));
strcpy(buf->SerialNumber , ConvertToString(diskdata,10,19));
strcpy(buf->ModalNumber , ConvertToString(diskdata,27,46));
if (diskdata [0] & 0x0080)
buf->DriveType = 0; //可移动驱动器
else if (diskdata [0] & 0x0040)
buf->DriveType = 0; //固定驱动器
/*if (datalen < 256)
{
memcpy(drivedata,diskdata,datalen);
}
else
memcpy(drivedata,diskdata,256);*/
done = TRUE;
// ShutdownWinIo ();
return done;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -