📄 hdisksn.cpp
字号:
// Detect for Scsi device all, Odd for slave, any rights should do
for(BYTE j=(BYTE)FROM_HDNO; j<=(BYTE)TO_HDNO; j++)
{
sprintf(chDevFile, "\\\\.\\Scsi%d:", j / 2);
hScsiDrv = CreateFile(chDevFile, GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
if(hScsiDrv == INVALID_HANDLE_VALUE) continue; // Open failed
for(i=0; i<2; i++) // ATA / ATAPI Selected
{
// 填充SCSI输入/输出数据
memset(bySRBIO, 0, sizeof(bySRBIO));
pSRBIO->HeaderLength = sizeof(SRB_IO_CONTROL);
memcpy(pSRBIO->Signature, "SCSIDISK", 8);
pSRBIO->Timeout = 10000;
pSRBIO->ControlCode = IOCTL_SCSI_MINIPORT_IDENTIFY;
pSRBIO->Length = sizeof(SENDCMDOUTPARAMS);
pSCIP->bDriveNumber = j % 2;
pSCIP->irDriveRegs.bDriveHeadReg = IDE_MASL_PARA[j % 2];
pSCIP->irDriveRegs.bCommandReg = IDE_DEV_TYPE[i];
if(!DeviceIoControl(hScsiDrv, IOCTL_SCSI_MINIPORT,
bySRBIO, sizeof(SRB_IO_CONTROL) +sizeof(SENDCMDINPARAMS),
bySRBIO, SRB_IOBUFF_SIZE, &dwReturn, NULL)) continue;
if(pHdInfo->sModelNumber[0]) break; // Extract data success
}
CloseHandle(hScsiDrv); // Close Device driver
if(i >= 2) continue; // Read HDisk Infor failed
memcpy(SCK_HD_INFO, pSCOP->bBuffer, sizeof(SCK_HD_INFO));
END_HDNO = j; return TRUE; // Success read hard disk info
}
return FALSE; // No find valid hard disk
}
//-------------------------------------------------------------------------//
// 采用WinIo驱动:等待硬盘空闲(小于0x80时为空闲状态)...
static UINT WaitHardDiskIdeWinIo(USHORT wait_addr)
{
BYTE xx = 0xFF;
for(WORD i=0; i<0x300; i++)
{
xx = inportb(wait_addr);
if(xx < 0x80) break;
SckMsDelay(100);
}
return xx;
}
// 用WinIo驱动读取IDE硬盘的设备信息,不受操作系统和用户权限的限制
static BOOL ReadHardDiskInfoFromWinIo(void)
{
HMODULE hWinIoDLL = StartWinIoDriver(); // WinIo动态库句柄
if(hWinIoDLL == NULL) return FALSE; // 启动驱动程序失败
USHORT base_addr, order_addr, wait_addr; // 基、命令、等待地址
BYTE masl_para, dev_type; // 主从盘、ATA/ATAPI
UINT xx, i, nWhich; // 各循环标志变量
BOOL bSuccess = FALSE; // 操作过程是否成功
IDSECTOR *pHdInfo = (IDSECTOR *)SCK_HD_INFO; // 硬盘信息结构指针
HD_OPER_ISOK = FALSE; END_HDNO = -1; // Which HDisk Found
memset(SCK_HD_INFO, 0x00, sizeof(SCK_HD_INFO)); // Clear hdisk infor
for(nWhich=(UINT)FROM_HDNO; nWhich<=(UINT)TO_HDNO; nWhich++)
{
base_addr = IDE_CTRL_PORT[nWhich / 2]; // 硬盘的各项参数设置
order_addr = base_addr + 0x06;
wait_addr = base_addr + 0x07;
masl_para = IDE_MASL_PARA[nWhich % 2];
for(i=0; i<2; i++) // 若不是ATA,则试ATAPI型
{
// 等待硬盘空闲状态,以检测其是否存在
WaitHardDiskIde(wait_addr);
bSuccess = outportb(order_addr, masl_para); // 选择主从盘
if(!bSuccess) break;
bSuccess = outportb(wait_addr, 0x10); // 返到00磁道
if(!bSuccess) break;
WaitHardDiskIde(wait_addr); // 是否有硬盘
xx = inportb(wait_addr);
if((xx & 0x50) != 0x50) {bSuccess = FALSE; break;}
// 试着两次分别发送读取ATA/ATAPI设备信息
dev_type = IDE_DEV_TYPE[i];
bSuccess = outportb(order_addr, masl_para); // 选择主从盘
if(!bSuccess) break;
bSuccess = outportb(wait_addr, dev_type);// 送读参数命令
if(!bSuccess) break;
xx = WaitHardDiskIde(wait_addr); // 是否成功返回
if((xx & 0x58) == 0x58) break; else bSuccess = FALSE;
}
if(bSuccess == FALSE) continue; // 硬盘尚未安装或无法处理
for(i=0; i<256; i++) // 读取硬盘共512字节信息
SCK_HD_INFO[i] = inportw(base_addr);
if(!pHdInfo->sModelNumber[0]) continue; // 校验数据结构
HD_OPER_ISOK = TRUE; END_HDNO = nWhich; break;
}
StopWinIoDriver(hWinIoDLL); return HD_OPER_ISOK; // 返回提取信息结果
}
//-------------------------------------------------------------------------//
// Win9x下给逻辑磁盘加锁/解锁:在对磁盘扇区进行写操作时使用
static BOOL Win9xLockLogicalDisk(HANDLE hVmm32Drv, BYTE byWhichDisk,
BOOL bLockOrNot)
{
if(hVmm32Drv == INVALID_HANDLE_VALUE) return FALSE;
DEVIOCTL_REGISTERS reg; // 模拟的32位寄存器
memset(®, 0, sizeof(reg));
if(bLockOrNot == TRUE) // 加锁逻辑磁盘
{
reg.ECX = 0x084A;
reg.EBX = 0x0100 + byWhichDisk;
reg.EDX = 1;
}
else // 解锁逻辑磁盘
{
reg.ECX = 0x086A;
reg.EBX = byWhichDisk;
}
reg.EAX = 0x440D;
DWORD dwReturn = 0L; // Return from device
return (DeviceIoControl(hVmm32Drv, VWIN32_DIOC_DOS_IOCTL,
®, sizeof(reg), ®, sizeof(reg), &dwReturn,
NULL) && (reg.Flags & 1) == 0); // 返回加/解锁磁盘结果
}
// Win9x读写逻辑磁盘扇区(A: B: C: D:...),扇区大小为DISK_SECTOR_SIZE字节
static BOOL Win9xLogicalDiskSectorIO(BYTE byWhichDisk, DWORD dwStartSector,
DWORD dwSumSectors, BYTE *pBuffer,
BOOL bOperation)
{
DEVIOCTL_DISKIOPACK dio; // 读写命令字段
DEVIOCTL_REGISTERS reg; // 模拟的32位寄存器
BOOL bSuccess = FALSE; // Operate if Success
DWORD dwReturn = 0L, i = 0; // Return from device
HANDLE hVmm32Drv = CreateFile("\\\\.\\VWIN32", 0, 0, 0,
0, FILE_FLAG_DELETE_ON_CLOSE, 0);
if(hVmm32Drv == INVALID_HANDLE_VALUE) return FALSE; // Open DiskIO.VXD failed
if(bOperation && !Win9xLockLogicalDisk(hVmm32Drv,
byWhichDisk, TRUE)) goto TheEnd; // 加锁逻辑磁盘
for(i=0; i<dwSumSectors; i++) // 读写所有扇区
{
dio.dwStartSector = dwStartSector; // 操作开始扇区
dio.wSectors = 1; // 共操作扇区数
dio.lpBuffer = pBuffer; // 缓冲区的指针
memset(®, 0, sizeof(reg)); // 填充REGS结构
reg.EAX = 0x7305;
reg.EBX = (DWORD)(&dio); // 命令结构指针
reg.ECX = -1;
reg.EDX = byWhichDisk; // 操作哪个磁盘
reg.ESI = bOperation == 0 ? 0 : 1; // 是读或写操作
reg.Flags = 0;
if(!DeviceIoControl(hVmm32Drv, VWIN32_DIOC_DOS_DRIVEINFO,
®, sizeof(reg), ®, sizeof(reg), &dwReturn, NULL) ||
(reg.Flags & 1) != 0) goto TheEnd; // 读写操作失败
dwStartSector++;
pBuffer += DISK_SECTOR_SIZE; // 到下一个扇区
}
if(bOperation && !Win9xLockLogicalDisk(hVmm32Drv,
byWhichDisk, FALSE)) goto TheEnd; // 解锁逻辑磁盘
bSuccess = TRUE;
TheEnd:
CloseHandle(hVmm32Drv); return bSuccess; // Return operate result infor
}
// Win9x读写物理磁盘扇区(0: 1: 2: 3:...),扇区大小为DISK_SECTOR_SIZE字节
static BOOL Win9xPhysicalDiskSectorIO(BYTE byWhichDisk, DWORD dwStartSector,
DWORD dwSumSectors, BYTE *pBuffer,
BOOL bOperation)
{
#ifdef SCK_USE_CIH // 采用INT方式读写
if(SCK_INT_ENABLE) return FALSE; // 中断已经启动
CURR_WORK_TYPE = SCK_RW_HDISK; // 当前工作类型
IOR_WHICH_DISK = byWhichDisk; // 读取哪个磁盘
IOR_START_SECTOR = dwStartSector; // 始操作的扇区
IOR_XFER_COUNT = dwSumSectors; // 所需操作总数
IOR_OUT_BUFFER = pBuffer; // 数据缓冲区域
IOR_R2W_OPERATE = bOperation; // 是读或写操作
return StartInterruptProcess(); // 启动中断服务
#else // 采用VXD方式读写
char chPath[MAX_PATH] = "DiskIO.VXD"; // 获取驱动程序目录
MakeSureDrvExist(chPath, IDR_DISKIOVXD);
HANDLE hDiskIODrv = CreateFile("\\\\.\\DiskIO.VXD", 0, 0, 0,
CREATE_NEW, FILE_FLAG_DELETE_ON_CLOSE, 0);
if(hDiskIODrv == INVALID_HANDLE_VALUE) return FALSE; // Open DiskIO.VXD failed
BOOL bSuccess = FALSE; // Operate if Success
DWORD dwReturn = 0L; // Return from device
SckInputOrder op; // IO的控制结构
op.byWhichDisk = byWhichDisk; // 读取哪个磁盘
op.uiStartSecLo = dwStartSector; // 始操作的扇区
op.uiStartSecHi = 0;
op.uiSumSectors = dwSumSectors; // 所需操作总数
op.bOperation = bOperation; // 是读或写操作
if(!DeviceIoControl(hDiskIODrv, DIOC_DISKIO_MINE_SCK,
&op, sizeof(op), pBuffer, dwSumSectors, &dwReturn, NULL)
|| dwReturn != dwSumSectors) goto TheEnd; // 读写扇区失败
bSuccess = TRUE;
TheEnd:
CloseHandle(hDiskIODrv); return bSuccess; // Return operate result infor
#endif
}
// WinNT读写逻辑(物理)磁盘指定的扇区,扇区大小为DISK_SECTOR_SIZE字节
static BOOL WinNTHandleDiskSectorIO(char chDevFile[],
SCK_LARGE_INTEGER ddOffset,
DWORD dwSumSectors, BYTE *lpBuffer,
BOOL bOperation)
{
HANDLE hDiskDev = INVALID_HANDLE_VALUE; // Handle of device driver
BOOL bSuccess = FALSE; // Result of read info
hDiskDev = CreateFile(chDevFile, GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
if(hDiskDev == INVALID_HANDLE_VALUE) return FALSE;
DWORD dwReturn = 0L, i = 0; // Bytes Just Readed
SetLastError(NO_ERROR); // Seek To Start Sector
SetFilePointer(hDiskDev, ddOffset.u.Low, &ddOffset.u.High, FILE_BEGIN);
if(GetLastError() != NO_ERROR) goto TheEnd; // Move pointer failure
try{for(i=0; i<dwSumSectors; i++)
{
if(bOperation) // Write Sector
{
memcpy(SCK_IO_BUFF, lpBuffer, DISK_SECTOR_SIZE);
if(!WriteFile(hDiskDev, SCK_IO_BUFF, DISK_SECTOR_SIZE, &dwReturn, NULL)
|| dwReturn != DISK_SECTOR_SIZE) goto TheEnd;
}
else // Read Sector
{
if(!ReadFile(hDiskDev, SCK_IO_BUFF, DISK_SECTOR_SIZE, &dwReturn, NULL)
|| dwReturn != DISK_SECTOR_SIZE) goto TheEnd;
memcpy(lpBuffer, SCK_IO_BUFF, DISK_SECTOR_SIZE);
}
lpBuffer += DISK_SECTOR_SIZE; // Next Sector
}}
catch(...) {goto TheEnd;}
bSuccess = TRUE; // Operation(R/W) Success
TheEnd:
CloseHandle(hDiskDev); return bSuccess; // Return result of read info
}
/////////////////////////////////////////////////////////////////////////////
// 从CPU获取其详细的标识信息:只处理Intel CPU的Intel486以上处理器
static int GetCPUnitInforString(char chInfo[])
{
char chOEMstr[13] = ""; chInfo[0] = '\0'; // OEM字串,PSN字串
DWORD dwEAX = 0, dwECX = 0, dwEDX = 0, dwMaxValue = 0;
__asm // 取OEM字符串,最大的指令数值
{
MOV EAX, 00H
CPUID
MOV dwMaxValue, EAX
MOV DWORD PTR chOEMstr, EBX
MOV DWORD PTR chOEMstr+4, EDX
MOV DWORD PTR chOEMstr+8, ECX
MOV BYTE PTR chOEMstr+12, 00H
}
if(lstrcmp(chOEMstr, "GenuineIntel")) return 0; // 非Intel的CPU,返回
if(dwMaxValue >= 0x01) // 取96位PSN的高32位CPU的签名
{
__asm
{
MOV EAX, 01H
CPUID
MOV dwEAX, EAX
MOV dwEDX, EDX
}
}
if(dwMaxValue >= 0x03) // 取96位PSN的余64位CPU序列号
{
__asm
{
MOV EAX, 03H
CPUID
MOV dwEDX, EDX
MOV dwECX, ECX
}
sprintf(chInfo, "%08X%08X%08X", dwEAX, dwEDX, dwECX);
}
else // 无序列号就取CPU厂商和其签名
{
sprintf(chInfo, "%s%08X%08X", chOEMstr, dwEAX, dwEDX);
}
return lstrlen(chInfo); // 返回得到的长度
}
// 获取与一个磁盘C:\\卷相关的信息
static int GetVolumeInforString(char chInfo[])
{
char chVolName[24] = ""; // 磁盘的卷标
DWORD dwVolumeSN = 0; // 磁盘卷序列号
DWORD dwMaxComLen = 0; // 最大路径组件长度
DWORD dwFileFlags = 0; // 文件系统标志位
char chFileName[24] = ""; chInfo[0] = '\0'; // 文件系统的名称
if(GetVolumeInformation("C:\\", chVolName, sizeof(chVolName),
&dwVolumeSN, &dwMaxComLen, &dwFileFlags,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -