CreateFile*****

一、*****CreateFile*****
    這個函數可以創建或打開一個對象的句柄,憑藉此句柄就可以控制這些對象:
控制檯對象、通信資源對象、目錄對象(只能打開)、磁盤設備對象、文件對象、郵槽對象、管道對象。
    函數原型:
HANDLE CreateFile(
LPCTSTR lpFileName,                         // file name對象路徑名
DWORD dwDesiredAccess,                      // access mode控制模式
DWORD dwShareMode,                          // share mode共享模式
LPSECURITY_ATTRIBUTES lpSecurityAttributes, // SD 安全屬性(也即銷燬方式)
DWORD dwCreationDisposition,                // how to create
DWORD dwFlagsAndAttributes,                 // file attributes
HANDLE hTemplateFile                        // handle to template file
);
【Parameters】
1、lpFileName
    一個指向無終結符的字符串的指針,來指明要創建或打開的對象的名字。
    在Windows NT/2000/XP平臺上:如果用ANSI版本的函數,字符串長度應限制在MAX_PATH;如果用Unicode版本的函數,這個限制可以擴充到32000個Unicode字符。
    在Windows95/98/Me平臺上:只能用ANSI版本的函數,字符串長度限制在MAX_PATH。
2、dwDesiredAccess
    指明對象的控制模式。一個應用程序可以包含讀控制、寫控制、讀/寫控制、設備查詢控制。
這個參數的取值可以是下面這些的組合:
    0                                             指定設備查詢控制:程序可以不訪問設備就查詢到設備屬性。
    GENERIC_READ                指定讀控制,可以從對象中讀取數據(指針將可以移動)。
    GENERIC_WRITE               指定寫控制,可以向對象中寫數據(指針將可以移動)。
    ----------------------------------------------------------------------
    另外,還可以指定下面的控制標誌:
標準控制權限(16-23位掩碼):
    DELETE                     刪除對象的權限。
    READ_CONTROL    從對象的安全描述符中讀取信息的權限,但不包括SACL(系統訪問控制列表)中的信息。
    WRITE_DAC              修改對象安全描述符中的DACL(隨機訪問控制列表)的權限
    WRITE_OWNER      修改對象安全描述符中的屬主的權限
    SYNCHRONIZE     同步化使用對象的權限,即可以創建一個線程等待信號量釋放(但有些對象不支持這個權限)。
    STANDARD_RIGHTS_REQUIRED    等價於前面四種權限的總合(通常這四種是必須具有的權限)。
    STANDARD_RIGHTS_READ        一般等價於READ_CONTROL
    STANDARD_RIGHTS_WRITE       一般等價於READ_CONTROL
    STANDARD_RIGHTS_EXECUTE     一般等價於READ_CONTROL
    STANDARD_RIGHTS_ALL         等價於前面五種權限的總合。
特殊控制權限(0-15位掩碼):
    SPECIFIC_RIGHTS_ALL
    ACCESS_SYSTEM_SECURITY
    MAXIMUM_ALLOWED
    GENERIC_READ
    GENERIC_WRITE
    GENERIC_EXECUTE
    GENERIC_ALL
注:實質上是通過ACCESS_MASK結構體的一個雙字值來設置標準權限、特殊權限和一般權限的。
3、dwShareMode
    指定對象的共享模式。如果dwShareMode==0,表示是互斥使用的。如果CreateFile打開成功,則別的程序只能等到當前程序關閉對象句柄CloseHandle後才能在打開或使用。
    使用下面這些值的組合來表示對象的共享模式:
    FILE_SHARE_DELETE       Windows NT/2000/XP:打開操作只有在刪除請求發生時才能返回成功。
    FILE_SHARE_READ                 打開操作只有在讀控制請求發生時才能返回成功。
    FILE_SHARE_WRITE                打開操作只有在寫控制請求發生時才能返回成功。
4、lpSecurityAttributes
    一個指向SECURITY_ATTRIBUTES結構對象的指針,決定返回的句柄是否被子進程所繼承。如果lpSecurityAttributes參數爲NULL,句柄就不能被子進程繼承。
    在Windows NT/2000/XP平臺下:lpSecurityDescriptor這個成員指明瞭這個對象的安全描述符。如果lpSecurityAttributes參數爲NULL,對象將獲得一個默認的安全描述符。目標文件系統必須爲這個參數的在文件上的有效操作保證安全性。
typedef struct _SECURITY_ATTRIBUTES {
DWORD nLength; //結構體的大小(字節爲單位),即siziof(SECURITY_ATTRIBUTES)
LPVOID lpSecurityDescriptor; //指向對象的安全描述符的指針,控制對象的共享屬性。在Windows 95/98/Me平臺                                                     //上這個成員被忽略。
BOOL   bInheritHandle; //指明當一個新的子進程創建時,是否繼承當前返回的句柄
} SECURITY_ATTRIBUTES, *PSECURITY_ATTRIBUTES;
5、dwCreationDisposition
    指明當打開的對象存在或不存在的時候各需怎樣處理。這個參數必須是一下值的其中之一:
    CREATE_NEW            創建新文件/對象(當對象已經存在是將返回失敗)。
    CREATE_ALWAYS         總是創建(如果對象存在就覆蓋它,清除當前屬性,把文件屬性和dwFlagsAndAttributes指定的標誌相結合)。
    OPEN_EXISTING         打開文件(如果不存在就返回失敗)。
    OPEN_ALWAYS      存在就打開;若不存在,假如dwCreationDisposition==CREATE_NEW就創建一個新文件。
    TRUNCATE_EXISTING     存在就打開,且清空文件內容(至少要有GENERIC_WRITE權限);若文件不存在就返回失敗。
6、dwFlagsAndAttributes
    指定文件屬性和標誌。可以是以下值的任意組合(只有FILE_ATTRIBUTE_NORMAL必須單獨使用,唯一例外):
Attribute:
    FILE_ATTRIBUTE_ARCHIVE                 文件存檔(備份或移動時會對文件做標記)。
    FILE_ATTRIBUTE_ENCRYPTED               加密(對文件來說是內容加密,對目錄來說是對將來新建的文件默認爲加密屬性),與此同時,如果還設置了FILE_ATTRIBUTE_SYSTEM屬性,當前這個屬性將無效。
    FILE_ATTRIBUTE_HIDDEN                  隱藏屬性。
    FILE_ATTRIBUTE_NORMAL                  文件沒有其他屬性設置,此屬性只能單獨使用才合法。
    FILE_ATTRIBUTE_NOT_CONTENT_INDEXED     不建立內容索引。
    FILE_ATTRIBUTE_OFFLINE                 脫機屬性。文件內容暫時不可用。此屬性被Remote Storage軟件所用,不能任意更改。
    FILE_ATTRIBUTE_READONLY                只讀文件屬性。應用程序不能寫或刪除。
    FILE_ATTRIBUTE_SYSTEM                  文件是系統文件或被操作系統互斥地使用。
    FILE_ATTRIBUTE_TEMPORARY               臨時文件,使用過程中儘量留在內存以保證存取速度。
Flag:
    FILE_FLAG_WRITE_THROUGH            指示系統立即寫磁盤。這個寫操作允許被cache緩存,但不能被擱置。
    FILE_FLAG_OVERLAPPED                   指示系統初始化對象,如果操作需要大量時間執行就先返回一 個 ERROR_IO_PENDING,當操作 完成後再通過事件使能信號量。指定這個標誌就必須在read和write函數裏初始化OVERLAPPED 結構體,應用程序必須執行重複的讀寫操作。此時,操作系統不維護文件指針,當前的位置   需要通過OVERLAPPED的指針傳遞給讀寫函數。這個標誌還允許多個操作的並行(並行讀寫)。
    FILE_FLAG_NO_BUFFERING                 指示系統不要緩衝,它如果和FILE_FLAG_OVERLAPPED聯合使用,將呈現最好的異步性能,因爲I/O操作並不依賴於內存管理器的同步性。但是有時I/O操作會慢些,因爲沒用cache。有時程序需要做調整,比如文件大小必須是扇區大小的整數倍,Buffer地址的按扇區地址對齊等。按扇區地址對齊內存邊界可以使用VirtualAlloc來分配內存,GerDiskFreeSpace函數可以得到磁盤一個扇區的大小。
    FILE_FLAG_RANDOM_ACCESS                指示文件進行隨即存取,系統可據此對cache的分配進行優化。
    FILE_FLAG_SEQUENTIAL_SCAN              指示順序存取,系統也可據此對cache的分配進行優化。即使有隨即存取的操作,也不會出錯,不過cache的優化就取消了。在連續讀取大文件時性能非常好。
    FILE_FLAG_DELETE_ON_CLOSE              指示系統在句柄關閉時將響應的文件立即刪除,對當前句柄以外的其他句柄也有效。而且隨後的打開請求也會失敗,直到你使用了FILE_SHARE_DELETE屬性。
    FILE_FLAG_BACKUP_SEMANTICS             在Windows NT/2000/XP平臺上:指示文件作爲備份或恢復文件打開,這是如果調用進程擁有特殊權限(SE_BACKUP_NAME 或 SE_RESTORE_NAME),就可以不進行安全檢查。也可以在獲得一個目錄的句柄時設置這個flag,目錄句柄可以代替文件句柄傳遞給一些函數。
    FILE_FLAG_POSIX_SEMANTICS              指明按照操作系統接口規範進行文件存取,這包括允許多文件名的使用。請謹慎使用,因爲MS_DOS或16位Windows系統可能不支持。
    FILE_FLAG_OPEN_REPARSE_POINT           這個標誌指明禁止文件系統的重解析點的動作。文件打開時就返回文件的句柄,而不在乎控制重解析點的過濾器是否可運行。不能和CREATE_ALWAYS同時使用。
    FILE_FLAG_OPEN_NO_RECALL               表明文件數據被請求,但仍然駐留在遠程存儲體中,而不會被傳回本地存儲體。這個標誌 由遠程存儲系統或分層存儲管理系統使用。
    如果CreateFile函數打開一個命名管道的客戶端,dwFlagsAndAttributes 參數也會包含服務信息的安全性。當調用程序指定了
SECURITY_PRESENT標誌時,dwFlagsAndAttributes 參數可以取以下一個或多個值:
    SECURITY_ANONYMOUS                  指定將客戶端模擬在匿名級別(the Anonymous impersonation level)
    SECURITY_IDENTIFICATION             指定將客戶端模擬在身份認證級別(the Identification impersonation level)
    SECURITY_IMPERSONATION              指定將客戶端模擬在僞裝級別(the Impersonation impersonation level)
    SECURITY_DELEGATION                 指定將客戶端模擬在授權級別(the Delegation impersonation level)
    SECURITY_CONTEXT_TRACKING           指定安全跟蹤模式是動態的,否則(不指定此標誌)是靜態的
    SECURITY_EFFECTIVE_ONLY             指定客戶端的安全內容中的有效內容纔可以被服務端使用,否則所有內容都可被使用。 這個標誌允許客戶端限制服務端在模擬客戶端時所具有的權限。
7、hTemplateFile
    把具有GENERIC_READ權限的句柄指定爲一個模板文件。這個模板文件提供了文件屬性和擴展屬性,用於創建文件。在Windows95/98/Me平臺上:這個參數必須爲空,否則如果你提供一個句柄,函數調用將會失敗,用GerLastError函數獲得的出錯信息爲ERROR_NOT_SUPPORTED。

【Return Values】
    調用如果成功,返回值時一個打開文件的句柄。
    如果調用之前文件已存在,且dwCreationDisposetion 爲CREATE_ALWAYS或OPEN_ALWAYS,用GetLastError返回ERROR_ALREADY_EXISTS。
(即使調用成功也會返回這個值)。如果調用之前不存在,GetLastError返回0。
    調用如果失敗,返回值是INVALID_HANDLE_VALUE。要進一步瞭解出錯原因,調用GetLastError。
   
【Remarks】
    在Windows 2000/XP平臺上:
    如果你企圖打開一個遠程機器上的文件或目錄,dwDesiredAccess設置爲DELETE或者任一其他的控制標誌,
而這時遠程文件或目錄還沒有以FILE_SHARE_DELETE的方式打開的話,你的函數調用就會發生共享錯誤了。
爲了避免共享錯誤,一種辦法是單獨用DELETE方式打開遠程文件或目錄,另一種方法是在打開文件或目錄之前先調用DeleteFile函數。
    如果dwCreationDisposition 參數指定爲CREATE_ALWAYS 並且dwFlagsAndAttributes 參數指定爲FILE_ATTRIBUTE_NORMAL 的話,CreateFile調用將失敗,GetLastError報告的錯誤是ACCESS_DENIED。這時,把dwFlagsAndAttributes 參數設置爲FILE_ATTRIBUTE_HIDDEN和FILE_ATTRIBUTE_NORMAL的聯合值,將避免這個問題。

二、*****CloseHandle*****
    用於關掉一個打開的對象句柄。
    函數原型:
BOOL CloseHandle(
HANDLE hObject   // handle to object
);
【Return Values】
    函數調用成功返回非零,失敗返回0。獲得更多錯誤信息,需要調用GetLastError函數。
    在Windows NT/2000/XP平臺上:當應用程序在調試器下運行時,關閉一個不合法的句柄將產生一個異常(Exception)。包括兩次關閉同一個句柄,或者試圖關閉一個由FindFirstFile函數返回的句柄,都會產生異常。

【Remarks】
    CloseHandle使指定的句柄無效,減少對象的句柄計數,進行對象保持檢驗。當對象的最後一個句柄關閉時,對象將從系統中刪除。關閉一個線程句柄並不會終止一個線程,要釋放一個線程對象,必須terminate線程,然後關閉所有的線程句柄。用CloseHandle只能關閉由CreateFile函數返回的句柄。用FindClose來關閉由FindFirstFile返回的句柄。

三、*****ReadFile*****
    ReadFile函數從文件指針指定的位置讀取數據。讀操作完成後,文件指針將根據實際讀出的數據自動進行調整,除非文件句柄是以OVERLAPPED屬性值打開的。如果是以OVERLAPPED打開的I/O,應用程序就需要自己手動調整文件指針。
    這個函數被設計成兼有同步和異步操作。ReadFileEx函數則設計成只支持異步操作,異步操作允許應用程序在讀文件期間可以同時進行其他的操作。
    函數原型:
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
);

【Parameters】
1、hFile
    文件句柄(必須具有GENERIC_READ訪問權限)。
    在Windows NT/2000/XP平臺上:對於異步讀操作,hFile可以是由CreateFile函數以FILE_FLAG_OVERLAPPED方式打開的任何句柄,或者一個由socket或accept函數返回的socket句柄。
    在Windows 95/98/Me平臺上:對於郵槽、命名管道和磁盤文件不能使用異步讀操作。
2、lpBuffer
    用來接收從文件中讀出的數據的緩衝區指針。
3、nNumberOfBytesToRead
    指明要讀的字節總數。
4、lpNumberOfBytesRead
    一個變量指針,用來存儲實際傳輸的字節總數。ReadFile在做所有事情(包括錯誤檢查)之前,先將這個值賦爲0。當ReadFile從一個命名管道上返回TRUE時這個參數爲0,說明消息管道另一端調用WriteFile時設置的nNumberOfBytesToWrite 參數爲0。
    在Windows NT/2000/XP平臺上:如果lpOverlapped 爲NULL,則lpNumberOfBytesRead不能爲NULL。如果lpOverlapped 不是NULL,lpNumberOfBytesRead可以設爲NULL。如果是一個overlapped形式的讀操作,我們可以動用GetOverlappedResult函數來獲得傳輸的實際字節數。如果hFile關聯的是一個完成端口(I/O completion port),那麼可以調用GetQueuedCompletionStatus函數來獲得傳輸的實際字節數。
    如果完成端口(I/O completion port)被佔用,而你用的是一個用於釋放內存的回調例程,對於lpOverlapped參數指向的OVERLAPPED結構體來說,爲這個參數指定NULL可以避免重新分配內存時發生內存泄漏。內存泄漏會導致返回這個參數值時是一個非法值。
    Windows 95/98/Me平臺上:這個參數不允許爲NULL。
5、lpOverlapped
    一個指向OVERLAPPED結構體的指針。如果hFile是以FILE_FLAG_OVERLAPPED方式獲得的句柄,這個結構是必須的,不能爲NULL。(否則函數會在錯誤的時刻報告讀操作已經完成了)。這時,讀操作在由OVERLAPPED中Offset成員指定的偏移地址開始讀,並且在實際完成讀操作之前就返回了。在這種情況下,ReadFile返回FALSE,GerLastError報告從錯誤類型是ERROR_IO_PENDING。這允許調用進程繼續其他工作直到讀操作完成。OVERLAPPED結構中的事件將會在讀操作完成時被使能。
    如果hFile不是以FILE_FLAG_OVERLAPPED方式獲得的句柄,並且lpOverlapped爲NULL,讀操作就從當前文件的開始位置讀起,直到讀操作完成ReadFile函數才能返回。
    在Windows NT/2000/XP平臺上:如果hFile不是以FILE_FLAG_OVERLAPPED方式獲得的句柄,並且lpOverlapped不爲NULL,則讀操作在由OVERLAPPED中Offset成員指定的偏移地址開始讀,直到讀操作完成ReadFile函數才能返回。
    在Windows 95/98/Me平臺上:對於文件、磁盤、管道和郵槽的操作,這個參數必須爲NULL。一個不爲空的OVERLAPPED結構體指針將導致調用失敗。Windows 95/98/Me平臺只支持串行口和並行口的overlapped 讀寫。

【Return Values】
    有如下任一種情況發生都會導致函數返回:(1)在管道另一端的寫操作完成後(2)請求的字節數傳輸完畢(3)發生錯誤。
    如果函數正確,返回非零。
    如果返回值是非零,但接收的字節數是0,那麼可能是文件指針在讀操作期間超出了文件的end位置。然而,如果文件以FILE_FLAG_OVERLAPPED方式打開,lpOverlapped 參數不爲NULL,文件指針在讀操作期間超出了文件的end位置,那麼返回值肯定是FALSE,GetLastError返回的錯誤是ERROR_HANDLE_EOF。

【Remarks】
    如果文件的一部分被另一個進程鎖定,而當前進程試圖重複鎖定,那將會失敗。
    一個應用程序在讀以FILE_FLAG_NO_BUFFERING方式打開的文件時要符合一定的條件。
(1)文件讀的開始地址必須是扇區大小的整數倍。GetDiskFreeSpace函數可以取得扇區的大小。
(2)請求讀的字節數也必須是扇區大小的整數倍。
(3)用於讀寫操作的Buffer地址必須按照扇區大小進行邊界對齊。可以通過用VirtualAlloc 函數申請內存來做到。
    在讀操作期間試圖訪問相應的輸入緩衝區,會導致讀入到緩衝區的數據損壞。讀操作完成之前,應用程序不能對這段輸入緩衝區做任何操作(包括讀、寫、重新分配內存,釋放內存等)。
    ReadFile可以通過指向控制檯輸入對象的句柄將控制檯的輸入字符讀出來。控制檯的模式決定了ReadFile的具體行爲。
    如果一個命名管道正在以消息模式被讀取,並且下一條消息比nNumberOfBytesToRead參數指定的長度還大,那麼ReadFile將返回FALSE並且GetLastError返回錯誤爲ERROR_MORE_DATA。剩下沒讀完的消息可能會被隨後的ReadFile或PeckNamedPipe函數讀出。
    讀取一個通信設備時,ReadFile的行爲被當前的通信延時所支配,延時屬性的設置和取得使用SetCommTimeouts和GetCommTimeouts函數。如果你設置延時屬性失敗,就會得到不可預知的結果。
    如果ReadFile試圖讀取一個buffer太小的郵槽,將會返回FALSE並且GetLastError返回錯誤爲ERROR_INSUFFICIENT_BUFFER 。
    如果一個匿名的寫管道句柄已經關閉,而ReadFile試圖用響應的匿名權限讀這個管道句柄,將返回FALSE並且
GetLastError返回錯誤爲ERROR_BROKEN_PIPE。
    每當有太多的異步I/O請求得不到響應,ReadFile就會失敗,並返回ERROR_INVALID_USER_BUFFER或ERROR_NOT_ENOUGH_MEMORY的錯誤。
    在同步和異步兩種情況下,ReadFile中檢測EOF(文件結尾邊界)的代碼是不同的。當一個同步讀操作到達文件結尾時,ReadFile返回TRUE,並設置*lpNumberOfBytesRead 爲0 。異步讀操作會在開始調用的讀操作中或者隨後的其他異步操作中突然遇到文件結尾。(1)如果EOF在ReadFile期間被檢測到,將會返回FALSE,且 GetLastError返回錯誤描述 ERROR_HANDLE_EOF。(2)如果EOF在隨後的其他異步操作中被檢測到,則類似GetOverlappedResult 等試圖獲取操作結果的函數返回FALSE,且 GetLastError返回錯誤描述ERROR_HANDLE_EOF。
    爲了取消未響應的異步I/O操作,用CancelIo函數。這個函數只能取消由調用進程對特定句柄進行的操作。被取消的I/O操作將被描述爲ERROR_OPERATION_ABORTED。
    如果你正試圖從並不存在的軟驅中讀數據,系統會彈出消息框提示你重新操作。爲了阻止系統的消息框,調用函數SetErrorMode,參數設置爲SEM_NOOPENFILEERRORBOX。

四、*****WriteFile*****
    可以以同步或異步方式向一個對象句柄中寫數據
    函數原型:
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極其相似,可參考上文ReadFile的翻譯。

五、*****DeviceIoControl*****
    這個函數直接向指定的設備驅動程序發送控制碼,使響應的設備產生響應的操作。
    函數原型:
BOOL DeviceIoControl(
HANDLE hDevice,              // handle to device
DWORD dwIoControlCode,       // operation
LPVOID lpInBuffer,           // input data buffer
DWORD nInBufferSize,         // size of input data buffer
LPVOID lpOutBuffer,          // output data buffer
DWORD nOutBufferSize,        // size of output data buffer
LPDWORD lpBytesReturned,     // byte count
LPOVERLAPPED lpOverlapped    // overlapped information
);

【Parameters】
(1)hDevice(輸入)
    用CreateFile獲得的設備句柄,典型的設備對象有卷、目錄、文件、交替的流等。
(2)dwIoControlCode(輸入)
    指定操作碼。這個值區別特定的操作和設備對象的類型。
    IOCTL_DISK_CREATE_DISK                用特定的信息初始化指定的磁盤和磁盤分區表
    IOCTL_DISK_FORMAT_TRACKS              格式化一組連續的磁道
    IOCTL_DISK_GET_DRIVE_GEOMETRY         獲取關於物理磁盤幾何屬性的信息
    IOCTL_DISK_GET_DRIVE_GEOMETRY_EX      獲取關於物理磁盤幾何屬性的信息
    IOCTL_DISK_GET_DRIVE_LAYOUT_EX        獲取一個磁盤的分區數量和每個分區的特徵信息
    IOCTL_DISK_GET_LENGTH_INFO            獲得指定磁盤、卷、分區的長度
    IOCTL_DISK_GET_PARTITION_INFO_EX      獲取自動變速(AT)分區和可擴展固件接口(EFI)分區的分區信息
    IOCTL_DISK_PERFORMANCE                提供磁盤性能信息
    IOCTL_DISK_REASSIGN_BLOCKS            將磁盤塊映射到空閒塊池
    IOCTL_DISK_SET_DRIVE_LAYOUT_EX        將磁盤分區
    IOCTL_DISK_SET_PARTITION_INFO_EX      設置分區類型
    IOCTL_DISK_UPDATE_PROPERTIES          使特定磁盤的cache分區表無效並重新枚舉磁盤
    IOCTL_DISK_VERIFY                     對磁盤大小進行邏輯檢測
    IOCTL_SERIAL_LSRMST_INSERT            (不)使電話線和Modem的連接狀態信息發送到數據流中
    IOCTL_STORAGE_CHECK_VERIFY            檢測可移動媒體設備的改變
    IOCTL_STORAGE_EJECT_MEDIA             彈出SCSI設備中的媒體(比如光盤)
    IOCTL_STORAGE_GET_HOTPLUG_INFO        獲取指定設備的熱插拔配置
    IOCTL_STORAGE_GET_MEDIA_TYPES         獲取媒體支持信息
    IOCTL_STORAGE_LOAD_MEDIA              將媒體裝入設備
    IOCTL_STORAGE_MEDIA_REMOVAL           (不)使能媒體彈出裝置
    IOCTL_STORAGE_SET_HOTPLUG_INFO        設置指定設備的熱插拔配置
    IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS 獲取一個或多個磁盤上指定卷的物理單元
    IOCTL_VOLUME_IS_CLUSTERED             決定是否爲一個卷作索引

(3)lpInBuffer(輸入)
    一個指針,指向存放操作所需數據的緩衝區。如果dwIoControlCode指定一個不需要輸入數據的操作,那麼這個參數可以爲NULL。
(4)nInBufferSize(輸入)
    以字節爲單位,指定輸入緩衝區的大小。
(5)lpOutBuffer(輸出)
    一個指針,指向用來存放輸出數據的緩衝區。如果dwIoControlCode指定一個沒有輸出數據的操作,那麼這個參數可以爲NULL。
(6)nOutBufferSize(輸入)
    以字節爲單位,指定輸出緩衝區的大小。
(7)lpBytesReturned(輸出)
    一個指針,指向一個存放輸出數據長度的變量。
    如果輸出緩衝區太小不足以接收任何數據,那麼函數調用失敗,GetLastError錯誤描述爲ERROR_INSUFFICIENT_BUFFER,輸出數據長度爲0。
    如果輸出緩衝區太小不足以接收所有數據但是可以放一部分,那麼操作系統就返回可以放下的那部分數據,函數調用失敗,
GetLastError錯誤描述爲ERROR_MORE_DATA,輸出數據長度是返回來的那部分數據的長度。你的應用程序應該調用DeviceIoControl 進行相同的操作,重新傳輸(指定那個沒傳完的地方作爲開始點進行續傳)。
    如果lpOverlapped 爲NULL,那麼lpBytesReturned 決不能爲NULL。即使是一個沒有輸出數據的操作,lpOutBuffer爲NULL,DeviceIoControl也將會用到lpBytesReturned指向的那個變量。這樣的操作返回後,這個參數的返回值是無意義的。
    如果lpOverlapped 不爲NULL,那麼lpBytesReturned 可以爲NULL。如果是一次異步操作,我們可以通道函數GetOverlappedResult來獲得返回的數據長度。如果hDevice 指向的是一個完成端口對象,我們可以用函數GetQueuedCompletionStatus獲得返回數據的長度。
(8)lpOverlapped
    一個指向OVERLAPPED結構體的指針。
    如果hDevice用FILE_FLAG_OVERLAPPED 形式打開,lpOverlapped 必須指向一個合法的OVERLAPPED結構體。在這種情況下,進行異步操作。
    如果hDevice用FILE_FLAG_OVERLAPPED 形式打開,而lpOverlapped爲NULL,函數會返回不可預知的錯誤。
    如果hDevice打開時沒有指定FILE_FLAG_OVERLAPPED 標誌,lpOverlapped參數將被忽略,進行同步操作,函數直到操作完成或出現錯誤時才返回。

【Parameters】
    成功返回非零,失敗返回0,錯誤描述用GetLastError取得。

【Remarks】
    如果hDevice用FILE_FLAG_OVERLAPPED 形式打開,lpOverlapped 指向一個合法的OVERLAPPED結構體,這是進行異步操作。在這種情況下,OVERLAPPED結構體必須包含一個手動設置的事件對象(用CreateEvent函數創建)。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章