?? 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 + -