• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            極品垃圾

            初學VC ,就是把每天所看到的整理到博客,慢慢消化這些內容。見證我的學習之路吧。很多都是轉載。

            公告

            初學VC ,就是把每天所看到的整理到博客,慢慢消化這些內容。見證我的學習之路吧。很多都是轉載。
            <2025年7月>
            293012345
            6789101112
            13141516171819
            20212223242526
            272829303112
            3456789

            統(tǒng)計

            • 隨筆 - 0
            • 文章 - 61
            • 評論 - 1
            • 引用 - 0

            常用鏈接

            留言簿(2)

            隨筆分類

            文章分類(55)

            文章檔案(61)

            搜索

            •  

            最新評論

            VC++完成Win2000下直接讀寫磁盤扇區(qū)
            由于Windows 操作系統(tǒng)在很大程度上采取了訪問安全保護機制(例如,在Windows操作系統(tǒng)下不能直接訪問物理內存、不能使用各種DOS、BIOS中斷等等),使得廣大程序設計人員在長時間的開發(fā)過程中不知不覺地逐漸養(yǎng)成了這樣的潛意識——在Windows操作系統(tǒng)下直接操縱硬件設備是極端困難和非常煩瑣的,并將其看作Windows編程的一個禁區(qū)。盡管在大多數(shù)場合下這樣的論斷還算是貼切,但也并非對所有的硬件設備訪問都那么困難。其實Windows在采取“實保護”措施的同時也提供了另外的一種有別于在DOS下訪問硬件設備的方法,即把所有的硬件設備全部看做“文件”,并允許按照對文件的讀寫方式來對其進行數(shù)據(jù)存取訪問。撰寫本文的另外一個目的也就是幫助讀者打消在Windows環(huán)境下對硬件編程的恐懼心理。

            對磁盤扇區(qū)數(shù)據(jù)的訪問

            前面已經(jīng)提過,在Windows 下把所有的設備當作文件進行操作。如果對串口進行編程或許不少讀者還比較熟悉:對于串行端口1、2,可以用”COM1”、”COM2”作為參數(shù)調用CreateFile()函數(shù),這里的”COM1”、”COM2”即以文件存放路徑的方式指出了要操作的硬件設備。但是如果需要對磁盤的某個扇區(qū)進行讀寫,可能不少讀者不會想到使用CreateFile()函數(shù)或是不知如何使用。其實,與對串行端口的訪問類似,需要用與文件存放路徑相類似的方式指出要操作的硬件設備(硬盤)。但是這里并不是用“DISK1”、“DISK2”等去標識某一塊物理存在的硬盤。由于邏輯扇區(qū)是存在于邏輯分區(qū)上的,因此這里需要以某種特定的格式來指定需要訪問的磁盤邏輯分區(qū)。對于邏輯分區(qū)X,其格式為”\\.\X:”。

            HANDLE CreateFile( LPCTSTR lpFileName,

            DWORD dwDesiredAccess,

            DWORD dwShareMode,

            LPSECURITY_ATTRIBUTES lpSecurityAttributes,

            DWORD dwCreationDisposition,

            DWORD dwFlagsAndAttributes,

            HANDLE hTemplateFile );


            CreateFile()函數(shù)原型如上所示,由于訪問的是事實上已經(jīng)存在的磁盤扇區(qū),因此只能以OPEN_EXISTING標志設置dwCreationDisposition參數(shù)指出將要打開已經(jīng)存在的文件(設備)。至于其他參數(shù)的使用與操作普通文件時的用法相同。

            通過CreateFile()打開的是整個磁盤邏輯分區(qū),而要操作的是該分區(qū)的某些扇區(qū),因此還要通過SetFilePointer()函數(shù)以文件操作的方式把指針移到要操作的磁盤扇區(qū)開始處。SetFilePointer()函數(shù)原型為:

            DWORD SetFilePointer(HANDLE hFile,

            LONG lDistanceToMove,

            PLONG lpDistanceToMoveHigh,

            DWORD dwMoveMethod);


            參數(shù)hFile為CreateFile()返回的文件(設備)句柄;lDistanceToMove和lpDistanceToMoveHigh指出了要設置偏移量的低端和高端部分;dwMoveMethod指出文件指針從何處開始移動,可能的選項有FILE_START(從文件開始)、FILE_END(從文件結尾)和FILE_CURRENT(從文件當前位置)。

            在定位到要訪問的扇區(qū)開始位置后就可以通過ReadFile()或WriteFile()函數(shù)實施相應的讀寫訪問了,具體操作與文件讀寫并沒有什么太大的差別。最后,在完成訪問操作后以CloseHandle()關閉文件句柄釋放資源,從而完成一次完整的磁盤扇區(qū)數(shù)據(jù)訪問操作。下面給出具體的讀、寫處理過程:

            BOOL CDirectAccessHDDlg::WriteSectors(BYTE bDrive, DWORD dwStartSector, WORD wSectors, LPBYTE lpSectBuff)

            // 對磁盤扇區(qū)數(shù)據(jù)的寫入

            {

             if (bDrive == 0) return 0;

             char devName[] = "\\\\.\\A:";

             devName[4] ='A' + bDrive - 1;

             HANDLE hDev = CreateFile(devName, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);

             if (hDev == INVALID_HANDLE_VALUE) return 0;

             SetFilePointer(hDev, 512 * dwStartSector, 0, FILE_BEGIN);

             DWORD dwCB;

             BOOL bRet = WriteFile(hDev, lpSectBuff, 512 * wSectors, &dwCB, NULL);

             CloseHandle(hDev);

             return bRet;

            }

            BOOL CDirectAccessHDDlg::ReadSectors(BYTE bDrive, DWORD dwStartSector, WORD wSectors, LPBYTE lpSectBuff)

            // 對磁盤扇區(qū)數(shù)據(jù)的讀取

            {

             if (bDrive == 0) return 0;

             char devName[] = "\\\\.\\A:";

             devName[4] ='A' + bDrive - 1;

             HANDLE hDev = CreateFile(devName, GENERIC_READ, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);

             if (hDev == INVALID_HANDLE_VALUE) return 0;

             SetFilePointer(hDev, 512 * dwStartSector, 0, FILE_BEGIN);

             DWORD dwCB;

             BOOL bRet = ReadFile(hDev, lpSectBuff, 512 * wSectors, &dwCB, NULL);

             CloseHandle(hDev);

             return bRet;

            }


            磁盤扇區(qū)數(shù)據(jù)直接讀寫技術的應用

            上一步實現(xiàn)了對磁盤扇區(qū)數(shù)據(jù)進行讀寫訪問的核心處理過程。在此基礎上可以完成一些有實用價值的應用,例如,可以實現(xiàn)對指定磁盤分區(qū)中指定起止扇區(qū)的內容查看:

            if (ReadSectors(uDiskID, m_uFrom, (UINT)dwSectorNum, bBuf) == FALSE) {

             MessageBox("所選磁盤分區(qū)不存在!", "錯誤", MB_OK | MB_IConERROR);

             return;

            }


            為了方便數(shù)據(jù)的顯示,可做如下處理以完成格式轉換等工作:

            for (DWORD i = 0; i < dwSectorNum * 512; i++) {

             sprintf(cBuf, "%s%02X ", cBuf, bBuf[i]);

             if ((i % 512) == 511)

            sprintf(cBuf, "%s\r\n第%d扇區(qū)\r\n", cBuf, (int)(i / 512) + m_uFrom);

             if ((i % 16) == 15)

            sprintf(cBuf, "%s\r\n", cBuf);

             else if ((i % 16) == 7)

            sprintf(cBuf, "%s- ", cBuf);

            }




            顯示結果如上圖所示。另外一種應用與之類似,即對磁盤扇區(qū)內容的備份與恢復處理。不少防病毒軟件都提供這樣的功能:對硬盤引導區(qū)內容的備份,一旦硬盤引導扇區(qū)被病毒破壞后能夠通過對備份數(shù)據(jù)的寫入實現(xiàn)恢復。備份操作與前面的數(shù)據(jù)顯示操作類似,只是把讀取的內容不經(jīng)格式處理而直接保存到指定的文件中即可:

            file.Open(fileDlg.GetPathName(), Cfile::modeCreate | Cfile::modeReadWrite);

            ……

            if (ReadSectors(uDiskID, m_uFrom, (UINT)dwSectorNum, bBuf) == FALSE) {

             MessageBox("所選磁盤分區(qū)不存在!", "錯誤", MB_OK | MB_IConERROR);

             return;

            }

            file.Write(bBuf, dwSectorNum * 512);

            file.Close();


            數(shù)據(jù)的恢復處理正好與之相反,首先打開備份文件并根據(jù)文件長度計算要寫的扇區(qū)數(shù),然后讀取其內容到緩存,最后將其寫入到指定扇區(qū)完成數(shù)據(jù)的恢復:

            file.Open(fileDlg.GetPathName(), Cfile::modeReadWrite);

            DWORD dwSectorNum = file.GetLength();

            if (dwSectorNum % 512 != 0) return;

             dwSectorNum /= 512;

             unsigned char* bBuf = new unsigned char[dwSectorNum * 512];

             file.Read(bBuf, dwSectorNum * 512);

             if (WriteSectors(uDiskID, m_uFrom, (UINT)dwSectorNum, bBuf) == FALSE) {

            MessageBox("所選磁盤分區(qū)不存在!", "錯誤", MB_OK | MB_IConERROR);

            return;

             }

             file.Close();

             delete[] bBuf;


            面將要給出的最后一個應用是對磁盤數(shù)據(jù)的安全擦除。眾所周知,在操作系統(tǒng)下是通過文件管理系統(tǒng)實現(xiàn)對文件訪問管理的。當刪除一個文件時,該文件的全部內容并沒有發(fā)生任何損壞,如果沒有外部數(shù)據(jù)的覆蓋,完全可以通過各種數(shù)據(jù)恢復軟件將先前刪除的文件恢復出來。但在軍工、政府等特殊的涉密行業(yè)、部門中,要求的是數(shù)據(jù)的徹底刪除,即經(jīng)刪除過的數(shù)據(jù)是不可進行再恢復處理的。為了確保磁盤數(shù)據(jù)的可靠清空,可以對每一個扇區(qū)寫入全1后再寫入全0。之所以多次寫入數(shù)據(jù),是因為一次寫入只能防止數(shù)據(jù)恢復軟件的恢復處理。如果覆蓋次數(shù)不多的化,通過一種被稱做“磁盤放大鏡”的特殊儀器仍能夠以物理的方法將先前刪除的數(shù)據(jù)恢復出來,因此這里需要對扇區(qū)多次重復寫入數(shù)據(jù),反復次數(shù)越多擦除效果越好。下面是這部分的具體實現(xiàn)代碼:

            unsigned char bBuf[512];

            UINT i = 0;

            BOOL bRet = TRUE;

            while (m_bAllDisk){

             memset(bBuf, 0xFF, sizeof(bBuf));

             bRet = WriteSectors(uDiskID, i, 1, bBuf);

             memset(bBuf, 0, sizeof(bBuf));

             bRet = WriteSectors(uDiskID, i, 1, bBuf);

             if (bRet == FALSE){

            if (i == 0)

             MessageBox("所選磁盤分區(qū)不存在!", "錯誤", MB_OK | MB_IConERROR);

            else

             MessageBox("磁盤數(shù)據(jù)擦除完畢!", "錯誤", MB_OK | MB_IConERROR);

             return;

             }

             i++;

            }


            小結

            本文僅對磁盤扇區(qū)內容的直接讀寫方法做了介紹并給出了扇區(qū)數(shù)據(jù)內容的顯示、備份與恢復、磁盤數(shù)據(jù)的徹底擦除等幾個主要的應用作了介紹。讀者可以根據(jù)需要實現(xiàn)其他的應用如利用磁盤扇區(qū)內容進行身份認證、數(shù)據(jù)隱藏、磁盤刪除數(shù)據(jù)的恢復等。本文所述程序代碼在Windows 2000 Professional + SP4下由Microsoft Visual C++ 6.0編譯通過。

            posted on 2009-05-21 22:19 極品垃圾 閱讀(350) 評論(0)  編輯 收藏 引用 所屬分類: vc

            久久久久久久亚洲Av无码| 久久99热狠狠色精品一区| 久久精品人妻一区二区三区| 亚洲国产小视频精品久久久三级 | 国产精品久久久久a影院| 亚洲午夜无码久久久久| 亚洲一区中文字幕久久| 日本精品一区二区久久久| 久久99精品久久久久子伦| 久久人人爽人人爽人人片AV东京热| 亚洲精品乱码久久久久久蜜桃不卡| 久久久久久狠狠丁香| 色狠狠久久AV五月综合| 欧美精品福利视频一区二区三区久久久精品| 伊人久久大香线蕉综合Av | 国产午夜免费高清久久影院| 久久精品成人免费国产片小草| 久久人人爽人人爽人人片AV麻烦| 久久综合久久综合久久| 青青草原精品99久久精品66| 久久综合视频网站| 丁香五月综合久久激情| 国产精品久久久久久久久| 久久久精品国产免大香伊 | 久久精品aⅴ无码中文字字幕不卡| 久久精品国产一区二区| 99久久无码一区人妻| 久久精品www| 久久噜噜电影你懂的| 国产成人精品久久免费动漫| 人妻丰满AV无码久久不卡| 久久亚洲日韩精品一区二区三区 | 无码人妻少妇久久中文字幕| 久久青草国产手机看片福利盒子| 久久精品国产亚洲AV无码娇色| 麻豆亚洲AV永久无码精品久久| 亚洲国产香蕉人人爽成AV片久久| 一本久久a久久精品综合香蕉| 久久精品视屏| 久久久精品国产免大香伊| 久久AV高潮AV无码AV|