《Windows via C/C++》學習筆記 —— 裝置I/O之“裝置的開啟和關閉”

來源:互聯網
上載者:User

  裝置的輸入輸出,即裝置I/O,可以分為“同步”和“非同步”兩種方式。同步的裝置I/O,調用的API函數總是等到裝置I/O完成才返回。而非同步裝置I/O,可以通過多種方法來實現,但是其根本原理是得到“裝置I/O的完成通知”。

 

  本篇主要討論如何開啟和關閉一個裝置。注意,這裡的裝置,不是指像鍵盤、顯示器那種實體。而是一種抽象的概念,指一種與外界通訊的對象,可以接受外界的輸入,也可以對外界的請求作出響應,稱之為裝置I/O。這個概念比較抽象,這些裝置往往和某個核心對象關聯。要開啟這些裝置,就要建立相關的核心對象。

  這些裝置包括檔案、目錄、邏輯磁碟驅動、物理磁碟驅動、序列埠、並行連接埠、郵槽、管道、通訊端、控制台(如下表):

裝置

主要用途 

檔案

儲存資料

目錄

屬性和檔案壓縮設定

邏輯磁碟驅動

磁碟格式化

物理磁碟驅動

訪問分區表

序列埠

串列傳輸資料

並行連接埠

多位元據同時傳輸,主要是將資料轉送給印表機

郵槽

一對多傳輸資料,往往適用於一個網路中的一台電腦向其他機器發送資料

具名管道

一對一傳輸資料,往往適用於一個網路中的一台電腦向其他機器發送資料

匿名管道

一對一傳輸資料,適用於簡單的資料轉送,不適用於網路

通訊端

以流或資料報的形式發送資料,適用於一個網路中的通訊

控制台

一個文字視窗顯示緩衝區

 

  要使用這些裝置,你首先應該開啟這些裝置。

  Windows努力隱藏這些裝置的差異,所以,很多裝置的開啟的I/O工作可以通過同一個API函數完成,如下表:

裝置

經常用來開啟裝置的API函數和用法

檔案

CreateFile —— 開啟裝置的函數。

將參數pszName是一個檔案路徑名。

目錄

CreateFile —— 開啟裝置的函數。

將參數pszName是一個目錄名。Windows允許你開啟一個目錄,通過使用參數FILE_ FLAG_BACKUP_SEMANTICS旗標來呼叫CreateFile函數。開啟目錄之後,就可以這是目錄屬性,即檔案夾屬性,比如正常、隱藏、系統、唯讀等。

邏輯磁碟驅動

CreateFile —— 開啟裝置的函數。

將參數pszName設定為字串“\\.\x:”。 比如要開啟C盤,就將其設定為“\\.\C:”。

物理磁碟驅動

CreateFile —— 開啟裝置的函數。

將參數pszName設定為“\\.\PHYSICALDRIVEx”。比如開啟第一個物理硬碟扇區:可以這麼調用CreateFile函數:

CreateFile(TEXT("\\.\PHYSICALDRIVE0"), ...);

這樣就可以開啟一個物理磁碟驅動,並且可以直接存取硬碟分區表。

但是開啟物理磁碟驅動是存在潛在危險的,特別是當錯誤的寫入,會造成物理磁碟內容的破壞。

序列埠

CreateFile —— 開啟裝置的函數。

將參數pszName設定為“COMx”,比如開啟COM1串口裝置,只要將其設定為“COM1”。

並行連接埠

CreateFile —— 開啟裝置的函數。

將參數pszName設定為“LPTx”,比如開啟LPT1並行連接埠,將其設定為“LPT1”。

郵槽(伺服器端)

CreateMailslot —— 開啟裝置的函數。

將參數pszName設定為“\\.\mailslot\mailslotname”,其中,“mailsoltname”是為郵槽取的名字,可以任意,前面的字串是固定的。

郵槽(用戶端)

CreateFile —— 開啟裝置的函數。

將參數pszName設定為“\\servername\mailslot\mailslotname”,其中,“mailsoltname”是為郵槽取的名字,可以任意,前面的字串是固定的。

具名管道

(伺服器端)

CreateFile —— 開啟裝置的函數。

將參數pszName設定為“\\.\pipe\pipename”,其中,“pipename”是為具名管道取的名字,可以任意,前面的字串是固定的。

具名管道

(用戶端)

CreateFile —— 開啟裝置的函數。

將參數pszName設定為“\\servername\pipe\pipename”,其中,“pipename”是為具名管道取的名字,可以任意,前面的字串是固定的。

匿名管道

CreatePipe —— 開啟裝置的函數。

無論是用戶端還是伺服器端都以該函數建立或開啟匿名管道。

通訊端

socket —— 建立一個通訊端描述符accept, or AcceptEx.

控制台

Console

CreateConsoleScreenBuffer,GetStdHandle —— 開啟裝置的函數

 

  從上表可以發現,很多裝置都以CreateFile函數來建立和開啟。這個函數以後會講。

  開啟了裝置,你得到了一個裝置的控制代碼,你就可以通過該控制代碼使用其他函數,來對相關裝置進行設定。

  比如,現在開啟了一個序列埠,然後要設定它的傳輸傳輸速率:

BOOL SetCommConfig(
   HANDLE       hCommDev,
   LPCOMMCONFIG pCC,
   DWORD        dwSize);

 

  或者,你獲得了一個郵槽控制代碼,可以設定讀取資料的等待時間:

BOOL SetMailslotInfo(
   HANDLE hMailslot,
   DWORD  dwReadTimeout);

 

  最後,不要忘記關閉控制代碼,從而正確地關閉裝置:

BOOL CloseHandle(HANDLE hObject);int closesocket(SOCKET s);   //通訊端的關閉

 

  如果你有了一個裝置控制代碼,你可以調查它的裝置類型,通過使用GetFileType函數,該函數的傳回值表明了它是一個什麼類型的裝置,可以參考MSDN。

DWORD GetFileType(HANDLE hDevice);

 

  好了,現在讓我們來討論一下CreateFile函數:

HANDLE CreateFile(
   PCTSTR pszName,     //指明裝置類型或一個特定的裝置實體
   DWORD dwDesiredAccess,     //訪問限制
   DWORD dwShareMode,         //共用方式
   PSECURITY_ATTRIBUTES psa,     //安全描述結構
   DWORD dwCreationDisposition,  //建立和開啟檔案
   DWORD dwFlagsAndAttributes,   //屬性旗標,與緩衝區和檔案操作屬性有關
   HANDLE hFileTemplate);        //裝置模版,一個裝置控制代碼

 

  該函數成功,返回控制代碼,失敗返回INVALID_HANDLE_VALUE(值為-1)。

  如果設定了最後一個參數hFileTemplate,那麼就照著這個參數所代表的裝置,建立一個屬性相同的裝置,當然,這個參數所表示的裝置要具有“可讀”的許可權,即有GENERIC_READ存取權限。

  至於該函數的具體用法,可以參看本書或MSDN。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.