📄 hdisksn.cpp
字号:
0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6,
0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D,
};
// 给定一个数据区及其长度,求出它的CRC32检验码
DWORD GenerateCRC32(const BYTE *pData, long nLength)
{
if(!pData) return 0L;
DWORD dwCrc32 = 0xFFFFFFFF;
while((nLength--) > 0)
{
dwCrc32 = (dwCrc32 >> 8) ^ Crc32Table[(*pData++) ^ (dwCrc32 & 0xFF)];
}
return (~dwCrc32);
}
// 以"与或"的方式使数据流面目全非或完璧归赵:写回自身
void CryptXOR(BYTE bySrc[], LONG nLen, BYTE byPatt)
{
while((--nLen) >= 0) bySrc[nLen] ^= byPatt;
}
// 以"与或"的方式使数据流面目全非或完璧归赵:写到新串
void CryptXOR(BYTE byDes[], const BYTE bySrc[], LONG nLen, BYTE byPatt)
{
memcpy(byDes, bySrc, nLen);
while((--nLen) >= 0) byDes[nLen] ^= byPatt;
}
// 获取系统回收站的路径,包含尾部的反斜杠'\\',入口MAX_PATH长度
INT GetRecyclerDirectory(CHAR chPath[])
{
if(chPath == NULL) return 0L;
DWORD dwAttr = (DWORD)(-1); // -1表示有错误
BOOL bFind = FALSE;
BOOL bIsNT = IsWindowsNT();
char chTemp[2][MAX_PATH] = {"", ""};
CryptXOR((BYTE *)chTemp[0], PATH_BASE_NT, sizeof(PATH_BASE_NT));
CryptXOR((BYTE *)chTemp[1], PATH_BASE_9X, sizeof(PATH_BASE_9X));
int nWhich = bIsNT ? 0 : 1; // 正常默认查找
dwAttr = GetFileAttributes(chTemp[nWhich]);
bFind = ((dwAttr & FILE_ATTRIBUTE_DIRECTORY) && dwAttr != (DWORD)(-1));
if(bFind == FALSE) // 调换名称再查
{
nWhich = bIsNT ? 1 : 0;
dwAttr = GetFileAttributes(chTemp[nWhich]);
bFind = ((dwAttr & FILE_ATTRIBUTE_DIRECTORY) && dwAttr != (DWORD)(-1));
}
if(bFind == FALSE) // 创建对应目标
{
nWhich = bIsNT ? 0 : 1;
SetFileAttributes(chTemp[nWhich], FILE_ATTRIBUTE_ARCHIVE);
DeleteFile(chTemp[nWhich]); // 确认没有文件
SetLastError(ERROR_SUCCESS);
bFind = (CreateDirectory(chTemp[nWhich], NULL) || (GetLastError() == \
ERROR_ALREADY_EXISTS));
}
INT nLen = 0L; // 获取临时路径
if(bFind == FALSE) nLen = (INT)GetTempPath(MAX_PATH, chPath);
else {lstrcpy(chPath, chTemp[nWhich]); nLen = lstrlen(chPath);}
if(nLen < 1) {lstrcpy(chPath, "C:\\"); nLen = 3L;}
else if(chPath[nLen - 1] != '\\') {chPath[nLen++] = '\\'; \
chPath[nLen] = '\0';} // 确认尾部'\\'
SetFileAttributes(chPath, FILE_ATTRIBUTE_SYSTEM | \
FILE_ATTRIBUTE_HIDDEN); return nLen; // 系统隐藏长度
}
//-------------------------------------------------------------------------//
// 从指定的端点读取一个字节
inline static BYTE inportb(WORD p)
{
DWORD v = 0;
GetPortVal(p, &v, sizeof(BYTE));
return (BYTE)v;
}
// 从指定的端点读取一个字
inline static WORD inportw(WORD p)
{
DWORD v = 0;
GetPortVal(p, &v, sizeof(WORD));
return (WORD)v;
}
// 向指定的端点写入一个字节
inline static BOOL outportb(WORD p, BYTE v)
{
return SetPortVal(p, v, sizeof(BYTE));
}
// 向指定的端点写入一个字
inline static BOOL outportw(WORD p, WORD v)
{
return SetPortVal(p, v, sizeof(WORD));
}
// 读取指定CMOS地址的数据
inline static BYTE ReadCmosAddr(BYTE byAddr)
{
if(!outportb(0x70, byAddr)) return 0x00; // 发送CMOS地址
return (inportb(0x71)); // 读取对应数据
}
// 精度为毫秒级的延迟函数
inline static void SckMsDelay(DWORD dwDelay)
{
register DWORD dwStart = GetTickCount();
for(;;) {if(GetTickCount() - dwStart >= dwDelay) break;}
}
//-------------------------------------------------------------------------//
// 将内部的资源文件导出为二进制的文件
static BOOL ExportResAsBinFile(LPCTSTR lpFile, HMODULE hModule, DWORD dwName, LPCTSTR lpType)
{
if(!lpFile || !hModule || !lpType) return FALSE;
BOOL bSuccess = FALSE;
HRSRC hRes = FindResource(hModule, MAKEINTRESOURCE(dwName), lpType);
DWORD dwSize = SizeofResource(hModule, hRes);
HGLOBAL hMem = LoadResource(hModule, hRes);
BYTE *pData = (BYTE *)LockResource(hMem);
if(pData && dwSize > 0) bSuccess = SaveBinaryFile(lpFile, pData, dwSize);
FreeResource(hMem); return bSuccess;
}
// 校验驱动文件的字节大小是否与程序资源内的一致
static BOOL IsSameSize(DWORD dwDrvID, DWORD dwLength)
{
switch(dwDrvID)
{
case IDR_SMARTVSDVXD: return (dwLength == 17986L);
case IDR_DISKIOVXD: return (dwLength == 7799L);
case IDR_WINIODLL: return (dwLength == 57344L);
default: return TRUE;
}
}
// 确认VXD设备驱动文件在%WINDOWS%目录下存在
static void MakeSureDrvExist(char *chFile, DWORD dwDrvID, long bOverWrite = 0)
{
char chPath[MAX_PATH] = ""; // 获取操作系统目录
if(!chFile || GetWindowsDirectory(chPath, MAX_PATH) < 1) return;
HandleSckPath(chPath, 0); // 尾部追加'\\'分隔
lstrcat(chPath, chFile);
if(MakeFilePath(chPath) == FALSE) return; // 确认驱动目录存在
lstrcpy(chFile, chPath);
DWORD dwLength = 0L; // DRV_驱动文件已在
if(IsFileExist(chPath, &dwLength) && !bOverWrite &&
IsSameSize(dwDrvID, dwLength)) return; // 文件大小是否符合
ExportResAsBinFile(chPath, g_hHDiskSnDLL, dwDrvID, "HardwareDriver");
}
// 开始WinIo的驱动程序
static HMODULE StartWinIoDriver(void)
{
HMODULE hWinIoDLL = NULL; // WinIo动态库句柄
for(long k=0; k<=1; k++) // 确认各驱动文件存在
{
char chPath[MAX_PATH] = "WinIo.DLL"; // 获取驱动程序目录
MakeSureDrvExist(chPath, IDR_WINIODLL, k);
hWinIoDLL = LoadLibrary(chPath); // 装载WinIo动态库
if(hWinIoDLL != NULL)
{
InitializeWinIo = (PInitializeWinIo)GetProcAddress(hWinIoDLL, "InitializeWinIo");
ShutdownWinIo = (PShutdownWinIo)GetProcAddress(hWinIoDLL, "ShutdownWinIo");
GetPortVal = (PGetPortVal)GetProcAddress(hWinIoDLL, "GetPortVal");
SetPortVal = (PSetPortVal)GetProcAddress(hWinIoDLL, "SetPortVal");
if(!InitializeWinIo || !ShutdownWinIo || !GetPortVal ||
!SetPortVal || !InitializeWinIo()) // 初始化设备程序
{
InitializeWinIo = NULL; ShutdownWinIo = NULL;
GetPortVal = NULL; SetPortVal = NULL;
FreeLibrary(hWinIoDLL); hWinIoDLL = NULL;
}
}
if(hWinIoDLL != NULL) break; // 启动驱动程序成功
}
return hWinIoDLL; // 返回驱动程序句柄
}
// 停止WinIo的驱动程序
static void StopWinIoDriver(HMODULE &hWinIoDLL)
{
if(hWinIoDLL == NULL) return;
ShutdownWinIo();
InitializeWinIo = NULL; ShutdownWinIo = NULL;
GetPortVal = NULL; SetPortVal = NULL;
FreeLibrary(hWinIoDLL); hWinIoDLL = NULL;
}
// 获取当前CMOS内记录的年、月、日、时、分、秒:共8个字节
BOOL GetCurrDate(BYTE *byDate)
{
if(byDate == NULL) return FALSE; // 入口参数检查
HMODULE hWinIoDLL = StartWinIoDriver(); // 启动端口驱动
if(hWinIoDLL == NULL) // 服务启动失败
{
SYSTEMTIME tm; GetLocalTime(&tm); // 获取本地时间
byDate[0] = (BYTE)(tm.wYear / 100); // 世纪
byDate[1] = (BYTE)(tm.wYear % 100); // 年份
byDate[2] = (BYTE)(tm.wMonth); // 月份
byDate[3] = (BYTE)(tm.wDay); // 日期
byDate[4] = (BYTE)(tm.wSecond); // 秒数
byDate[5] = (BYTE)(tm.wHour); // 小时
byDate[6] = (BYTE)(tm.wMinute); // 分数
byDate[7] = (BYTE)(tm.wSecond); // 秒数
return TRUE; // 直接返回真值
}
byDate[0] = BCD2DEC(ReadCmosAddr(0x32)); // 世纪
byDate[1] = BCD2DEC(ReadCmosAddr(0x09)); // 年份
byDate[2] = BCD2DEC(ReadCmosAddr(0x08)); // 月份
byDate[3] = BCD2DEC(ReadCmosAddr(0x07)); // 日期
byDate[4] = BCD2DEC(ReadCmosAddr(0x00)); // 秒数
byDate[5] = BCD2DEC(ReadCmosAddr(0x04)); // 小时
byDate[6] = BCD2DEC(ReadCmosAddr(0x02)); // 分数
byDate[7] = BCD2DEC(ReadCmosAddr(0x00)); // 秒数
StopWinIoDriver(hWinIoDLL); return TRUE; // 关闭端口驱动
}
// 获取两个日期之间的天数:新值-旧值,头4个字节
LONG GetDiffDate(const BYTE *byNew, const BYTE *byOld)
{
if(!byNew || !byOld) return -1; // 入口参数检查
LONG nDays = ((LONG)(byNew[0] - byOld[0]) * 100L + (byNew[1] - byOld[1])) \
* 360L + (LONG)(byNew[2] - byOld[2]) * 30L \
+ (byNew[3] - byOld[3]); return nDays; // 返回所得天数
}
// 判断新旧两组时间是否发生了变化:全部8个字节
BOOL IsDiffTime(const BYTE *byNew, const BYTE *byOld)
{
if(!byNew || !byOld) return FALSE;
const DWORD *pdwTm[2] = {(DWORD *)byNew, (DWORD *)byOld};
if(*pdwTm[0] != *pdwTm[1]) return TRUE; // 第一个DWORD段
pdwTm[0] = (DWORD *)(byNew + sizeof(DWORD));
pdwTm[1] = (DWORD *)(byOld + sizeof(DWORD));
return ((BOOL)(*pdwTm[0] != *pdwTm[1])); // 第二个DWORD段
}
// 自定义动态库入口函数:用于初始化、和释放资源
BOOL APIENTRY DllMain(HANDLE hModule, // 参数DLL_映象句柄
DWORD ul_reason_for_call,
LPVOID lpReserved)
{
switch (ul_reason_for_call)
{
case DLL_THREAD_ATTACH: // 进程创建了新线程
break;
case DLL_THREAD_DETACH: // 进程舍弃了一线程
break;
case DLL_PROCESS_ATTACH: // 进程开始使用_DLL
g_hHDiskSnDLL = (HMODULE)hModule;
break;
case DLL_PROCESS_DETACH: // 进程正在释放_DLL
g_hHDiskSnDLL = NULL;
break;
}
return TRUE; // 返回给父调用结果
}
/////////////////////////////////////////////////////////////////////////////
// 中断内:等待硬盘空闲(小于0x80时为空闲状态)...
static UINT WaitHardDiskIde(USHORT addr)
{
BYTE xx = 0x00;
USHORT wait_addr = addr;
__asm mov cx, 0xFFFF
Waiting:
__asm
{
mov dx, wait_addr
in al, dx
cmp al, 0x80
jb EndWaiting
loop Waiting
}
EndWaiting:
__asm
{
mov xx, al
}
return xx;
}
// 中断内:从IDE[0, 1]控制器读取主从共4个硬盘的信息数据
static void ReadHardDiskInfoFromCtrlIDE(void)
{
USHORT base_addr, order_addr, wait_addr;
USHORT temp;
BYTE masl_para, dev_type;
UINT xx, i, nWhich;
IDSECTOR *pHdInfo = (IDSECTOR *)SCK_HD_INFO;
HD_OPER_ISOK = FALSE; END_HDNO = -1;
for(nWhich=(UINT)FROM_HDNO; nWhich<=(UINT)TO_HDNO; nWhich++)
{
base_addr = IDE_CTRL_PORT[nWhich / 2];
order_addr = base_addr + 0x06;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -