函數CreateFileMapping為一個指定的檔案建立或打開一個已命名或未命名的檔案映射對象,告知系統檔案映射對象需要多少實體存儲器。
HANDLE CreateFileMapping(HANDLE hFile,
LPSECURITY_ATTRIBUTES lpAttributes,
DWORD flProtect,
DWORD dwMaximumSizeHigh,
DWORD dwMaximumSizeLow,
LPCTSTR lpName);
參數
hFile:
[in] 要映射的檔案的句柄,由CreateFile函數傳回。打開檔案的通路權限必須與參數flProtect指定的保護屬性相容。推薦以獨占的方式打開檔案,雖然這不是必須的。如果hFile為INVALID_HANDLE_VALUE,調用程序必須通過參數dwMaximumSizeHigh和參數dwMaximumSizeLow指定映射的size。這種情況下,函數CreateFileMapping建立一個由系統頁面支援的指定大小的檔案映射對象,而不是磁盤中的一個已命名的檔案。
檔案映射對象可共享副本、被繼承。檔案映射對象的頁面的初始内容為0.
lpAttributes
[in] 一個指向SECURITY_ATTRIBUTES結構的指針,指明了該函數傳回的句柄是否可以被子程序繼承。
如果lpAttributes為NULL,該句柄不可以被繼承(lpAttributes通常為NULL)。
SECURITY_ATTRIBUTES結構的lpSecurityDescriptor成員為新的檔案映射對象指定了安全描述。
如果lpAttributes為NULL(一般取該值即可),檔案映射對象将獲得預設的安全描述。
flProtect
[in] 檔案被映射後,視圖的保護屬性。
該參數可以為下列中的某值。
保護屬性 | 含義 |
---|---|
PAGE_READONLY | 在映射檔案映射對象時,可以讀取檔案中的資料。必須已經向CreateFile函數傳遞了GENERIC_READ時使用 |
PAGE_READWRITE | 在映射檔案映射對象時,可以讀取檔案中的資料,也可以将資料寫入檔案。必須在CreateFile函數傳遞了GENERIC_READ和GENERIC_WRITE時使用 |
PAGE_WRITECOPY | 在映射檔案映射對象時,可以讀取檔案中的資料。在寫入資料時,将建立頁面的私有拷貝(使用寫時複制機制)。必須在已經向CreateFile函數傳遞了GENERIC_READ或者"GENERIC_READ or GENERIC_WRITE"時使用 |
PAGE_EXECUTE_READ | 完成對檔案映射對象的映射時,可以讀取檔案中的資料,也可以運作其中的代碼。在調用CreateFile時必須傳GENERIC_READ和GENERIC_EXECUTE |
PAGE_EXECUTE_READWRITE | 完成對檔案映射對象的映射時,可以讀取檔案中的資料并,可以将資料寫入檔案,還可以運作其中的代碼。在調用CreateFile時必須傳GENERIC_READ、GENERIC_WRITE和GENERIC_EXECUTE |
應用程式還可以指定一個或多個以下段屬性與flProtect通過或操作符一起使用,“段”隻不過是記憶體映射的另一種叫法。
在建立記憶體映射資料檔案時,不能設定這些标志中的任何一個。CreateFileMapping函數會忽略這些标志。
段保護屬性 | 含義 |
---|---|
SEC_COMMIT | 此為預設值;從記憶體或頁面檔案或磁盤上的檔案為節上所有頁面配置設定實體存儲器;在使用映射資料檔案時,不能使用該屬性 |
SEC_IMAGE | 這個屬性告知系統,所映射的檔案是個可移植可執行的(PE)檔案映像。當系統将這個檔案映射到程序的位址空間時,需要檢視檔案的内容,以便确定将哪些保護屬性賦予檔案映像的各個頁面 |
SEC_NOCACHE | 告知系統,沒有将檔案的任何記憶體映射頁面放入告訴緩存。是以,當向這個檔案中寫入資料時,系統必須更加經常地更新磁盤上的檔案資料。這個标志與PAGE_NOCACHE保護屬性一樣,供裝置驅動開發人員使用,應用程式一般不使用 |
SEC_RESERVE | 保留節的所有位址空間;在使用映射資料檔案時,不能使用該屬性 |
dwMaximumSizeHigh
[in]檔案映射對象size(64位)的高32位;由于Windows支援的最大檔案大小可以用64位整數表示,是以必須使用兩個32位值,對于小于4GB的檔案來說,dwMaximumSizeHigh為0
dwMaximumSizeLow
[in]檔案映射對象size(64位)的低32位;如果該參數和dwMaximumSizeHigh均為0,檔案映射對象的最大size為hFile指定的檔案的size。試圖映射一個size為0的檔案将失敗并傳回錯誤碼ERROR_FILE_INVALID。應用程式應當檢查檔案size是否為0,并拒絕映射size為0的檔案。
lpName
[in]一個指向映射對象的以0結尾的字元串。
如果lpName比對一個已存在的并已命名的檔案映射對象,函數将請求flProtect指定的通路權限。
如果lpName為NULL,将建立一個沒有名字的映射對象。
如果lpName比對一個已存在并已命名的事件、信号量、互斥對象、可等待計時器或工作對象,函數将失敗,GetLastError函數将傳回ERROR_INVALID_HANDLE。發生這樣的原因是這些核心對象共享同一個命名空間。
傳回值
如果函數調用成功,将傳回檔案映射對象的句柄。
如果對象在函數調用之前就已存在,函數将傳回已存在的對象句柄(size以已存在的對象size為準),這時,GetLastError将傳回ERROR_ALREADY_EXISTS。
如果函數失敗,傳回NULL。可以調用GetLastError獲得錯誤碼。
注意
- 建立一個記憶體映射檔案相當于先預定一塊位址空間區域,然後再給區域調撥實體存儲器。唯一不同之處在于記憶體映射檔案的實體存儲器來自于磁盤上的檔案,而不是從系統的頁交換檔案中配置設定的。建立一個檔案映射對象的時候,系統不會預定一塊位址空間區域并把檔案映射到該區域中。但是,當系統在映射程序位址空間的時候,它必須知道應該給實體存儲器的頁面指定何種保護屬性
- 如果調用CreateFileMapping函數并傳遞PAGE_READWEITE标志,那麼系統将設法確定磁盤上相關資料檔案的大小與在參數dwMaximumSizeHigh和參數dwMaximumSizeLow中設定的大小相同。如果檔案小于設定的大小,CreateFileMapping函數将對檔案的大小進行擴充,使磁盤上的檔案變大。這種擴充是很有必要的,這樣以後再将這個檔案作為記憶體映射檔案使用時,實體存儲器就已經存在了。如果使用PAGE_READONLY或PAGE_WRITECOPY标志建立這個檔案映射對象,那麼CreateFileMapping函數設定的檔案大小不得大于實體磁盤檔案的大小。這是因為不這樣做就無法将任何資料附加給這個檔案。
版權聲明:本文為CSDN部落客「weixin_34234721」的原創文章,遵循CC 4.0 BY-SA版權協定,轉載請附上原文出處連結及本聲明。
原文連結:https://blog.csdn.net/weixin_34234721/article/details/92594889