WindowsCEnet的存储管理.docx
- 文档编号:29127698
- 上传时间:2023-07-20
- 格式:DOCX
- 页数:64
- 大小:284.44KB
WindowsCEnet的存储管理.docx
《WindowsCEnet的存储管理.docx》由会员分享,可在线阅读,更多相关《WindowsCEnet的存储管理.docx(64页珍藏版)》请在冰豆网上搜索。
WindowsCEnet的存储管理
WindowsCE.NET的儲存管理
本章將介紹MicrosoftWindowsCE.NET(以下簡稱CE.NET)的儲存管理。
我們將本章內容分為兩大部分,前半部會依序介紹CE.NET的檔案系統類型、CE.NET儲存管理結構和每一個層次、以及如何自行開發檔案系統並載入之,後半部則以Ramdisk上的檔案系統為例,實際分析儲存管理相關的原始程式碼與資料型態。
5.1CE.NET的儲存管理架構
5.1.1概述
CE.NET提供了三種類型的檔案系統:
RAM-based檔案系統、ROM-based檔案系統、以及用於支援ATA(AdvancedTechnologyAttachment)裝置和SRAM卡等週邊儲存裝置的FAT檔案系統。
其中,前兩種檔案系統屬於CE.NET的內建檔案系統,後者屬於可安裝性檔案系統。
另外,嵌入式系統的開發人員也可以編寫自己的檔案系統,並在系統中註冊使用。
CE.NET提供了platform-independentAPI,不論是何種儲存裝置,所有對檔案系統的存取都是透過Win32API完成。
CE.NET預設的儲存裝置為最大可達256MB的RAM記憶體。
RAM被分割為程式空間(programmemory)和物件空間(objectstore)。
程式空間和一般電腦系統中RAM的使用類似,用來儲存執行程式及所需資料。
物件空間則類似一般電腦系統中的硬碟,用來儲存應用程式及檔案。
物件空間中存放的資料可分為三大類:
(1)檔案系統(filesystem),
(2)註冊資訊(registry),(3)CE.NET資料庫(CE.NETdatabase)。
CE.NET系統的電源管理機制,即使在關機狀態時,仍舊有少量的電力從電池供應RAM,以保留儲存在其中的資料。
只有在電池電力完全耗盡時,RAM中儲存的資料才會消失。
與物件空間相關的RAM-based檔案系統和ROM-based檔案系統,是CE.NET預設支援的內建檔案系統。
除此之外,使用者還可以安裝用於支援週邊儲存裝置的檔案系統,比如FAT、UDFS等等。
對週邊儲存裝置的存取,都是透過這種可安裝性檔案系統來完成的。
另外,我們還可以將一個週邊儲存裝置,分為多個volume(卷)並分別載入,其中每個volume可以使用不同的檔案系統。
CE.NET沒有像WindowsXP或WindowsME使用磁碟機代號來表示volume,載入後的volume在CE.NET內以目錄的形式呈現。
5.1.2物件空間
如前所述,物件空間的資料分為三部分-檔案系統、系統註冊資訊及資料庫。
然而,檔案系統、資料庫以及註冊資訊都不一定要儲存在物件空間中,它們也可以被存放ROM或是週邊儲存裝置中。
資料的建立和使用,與實際的儲存裝置無關,只是依賴於儲存的類型。
作業系統負責管理記憶體堆,在必要的時候會對檔案進行壓縮和解壓縮。
物件空間使用基於事務的資料管理機制。
如果當資料寫入物件空間時,發生了電源中斷的情況,CE.NET會透過各種手段保證物件空間不被破壞,例如在系統重啟後繼續完成該寫操作,或是恢復到電源中斷前的狀態。
在早期的WindowsCE版本中,RAM檔案系統和檔案大小最大皆只能達16MB。
到了WindowsCE3.0這個版本,RAM檔案系統最大可達256MB,而檔案大小最大也能達32MB。
另外,物件空間中的物件數目也由原本的65,536增加到4,000,000左右。
最新的CE.NET允許檔案最大可達4GB。
CE.NET為物件空間中的每個物件,都分配了一個唯一的物件識別碼(WindowsCEobjectidentifier,簡稱CEOID)。
物件識別碼的作用就是用於存取物件空間中的物件。
在物件空間中,以下列出的各項都可以被定義為一個物件:
∙註冊資訊中的一個鍵
∙註冊資訊中的一個值
∙一個檔案
∙檔案資料中大小為4KB的一部分(意即一個12KB的檔案本身會對應一個檔案物件,另外其所含的三個4KB的資料塊也分別對應著一個物件)
∙資料庫中的一項記錄(最多可達4KB資料)
∙資料庫中一項記錄的擴展資訊(也可達4KB資料)
∙一個資料庫
∙資料庫的一個volume(adatabasevolume)
需要說明的一點是,CE.NET僅僅保證物件識別碼在同一個volume中是唯一的,當有多個volume,可能在不同volume中發現相同物件識別碼的物件。
因此,CE.NET為每個資料庫volume(databasevolume)都分配了一個唯一的資料庫識別碼(CEGUID)。
資料庫識別碼和物件識別碼的結合,就可以表示資料庫volume中的某個物件了。
要對物件空間中的物件進行存取,第一步就是獲得該物件的物件識別碼。
根據不同的物件類型,CE.NET提供了相對應的函式以獲得該物件的物件識別碼,參考表5.1。
表5.1獲得物件識別碼函式
物件類型
獲得物件識別碼的方法
目錄或檔案
FindFirstFile和FindNextFile函式回傳的WIN32_FIND_DATA結構的dwOID欄位。
GetFileInformationByHandle函式回傳的BY_HANDLE_FILE_INFORMATION結構的dwOID欄位。
資料庫
CeCreateDatabaseEx2或CeFindNextDatabaseEx函式的回傳值
資料庫記錄
CeSeekDatabaseEx、CeReadRecordPropsEx以及CeWriteRecordProps函式的回傳值。
已載入的資料庫volume
CeMountDBVol和CeEnumDBVolumes函式可以回傳已掛載資料庫volume中的資料庫識別碼。
有了物件識別碼,就可以使用CeOidGetInfoEx函式得到該物件內的資料。
CeOidGetInfoEx函式會回傳一個CEOIDINFO結構(結構原型列於程式碼5.1)。
CEOIDINFO結構有一個wObjType欄位說明了物件的類型。
假如該欄位的值為OBJTYPE_DATABASE,就指這是一個資料庫物件。
由wObjType可得知該物件是檔案、目錄、資料庫還是資料庫記錄,同時也得知該物件的資料位址。
例如,如果對一個資料庫物件使用CeOidGetInfoEx的話,那麼回傳的類型值為OBJTYPE_DATABASE,而與之相關的資料庫名稱、類型識別碼、記錄的數目、資料庫的大小以及排序方式等資訊,都將保存在一個CEDBASEINFO結構中。
程式碼5.1CEOIDINFO資料結構
typedefstruct_CEOIDINFO{
WORDwObjType;//Typeofobject
//OBJTYPE_INVALID|Therewasnovalidobject
//withthisCEOID
//OBJTYPE_FILE|Theobjectisafile
//OBJTYPE_DIRECTORY|Theobjectisadirectory
//OBJTYPE_DATABASE|Theobjectisadatabase
//OBJTYPE_RECORD|Theobjectisarecordinside
//adatabase
WORDwPad;//dwordalignment
union{//Thisisaunion
CEFILEINFOinfFile;//Validforfileobjects
CEDIRINFOinfDirectory;//Validfordirectoryobjects
//@CESYSGENIFFILESYS_FSDBASE
CEDBASEINFOinfDatabase;//Validfordatabaseobjects
CERECORDINFOinfRecord;//Validforrecordobjects
//@CESYSGENENDIF
};
}CEOIDINFO,PCEOIDINFO;
5.1.3儲存管理程式
儲存管理程式(StorageManager)負責管理週邊儲存裝置所使用的檔案系統和區塊裝置驅動程式(BlockDeviceDriver)。
儲存管理程式的功能實作位在fsdmgr.dll模組,它由三部分組成,包括區塊裝置管理程式(BlockDriverManager)、分割區管理程式(PartitionManager)以及檔案系統管理程式(FileSystemDriverManager,或簡稱FSDManager)。
所有對檔案和volume的處理,都是經由儲存管理程式完成的,儲存管理程式在永久性儲存介質的存取過程中,扮演了很重要的角色。
圖5.1儲存管理程式結構圖
CE.NET的儲存管理程式是一個分層結構,其結構如圖5.1所示,因此做DiskI/O必需經過儲存管理程式的各個階層。
首先是篩檢程式層(FileSystemFilter),在將I/O請求交由檔案系統驅動程式處理之前,在篩檢程式這一層可以完成一些加密、壓縮和病毒掃描等性質的額外工作。
接下來是檔案系統驅動程式(FileSystemDriver),在這裡對參數進行格式化,將檔案名稱轉換為區塊裝置驅動程式可以識別的物理位址。
在這之後,就可以經分割區管理程式,或直接交由區塊裝置驅動程式,完成實體的I/O操作了。
在儲存管理程式的啟動過程中,有很多資訊是從系統的註冊資訊中得到的。
例如,下面的註冊資訊會告知系統載入儲存管理程式模組:
[HKEY_LOCAL_MACHINE\System\StorageManager]
"Dll"="fsdmgr.dll"
另外,每當系統檢測到新的週邊儲存裝置時,裝置管理程式會自動載入支援該裝置的區塊裝置驅動程式,之後向儲存管理程式報告,該裝置的配置資訊在註冊資訊中的位置。
儲存管理程式就是根據這些資訊,決定如何載入適當的分割區驅動程式(partitiondriver)和檔案系統驅動程式。
下面是所有裝置都可使用的預設配置資訊:
[HKEY_LOCAL_MACHINE\System\StorageManager\Profiles]
"AutoMount"=dword:
1
"AutoPart"=dword:
0
"AutoFormat"=dword:
0
"MountFlags"=dword:
0
"DefaultFileSystem"="FATFS"
"PartitionDriver"="mspart.dll"
"Folder"="MountedVolume"
其中AutoFormat表明是否對該裝置進行自動格式化,AutoPart表明是否用該裝置上的最大可用空間自動建立分割區,AutoMount表明是否自動掛載每個檢測到的分割區,而MountFlags則指出了應如何對分割區進行掛載。
如果裝置管理程式向儲存管理程式,指定新裝置的配置資訊所在的位置,那麼儲存管理程式會使用該裝置的指定配置資訊。
例如,硬碟的配置資訊可能如下:
[HKEY_LOCAL_MACHINE\System\StorageManager\Profiles\HDProfile]
"Name"="IDEHardDiskDrive"
"Folder"="HardDisk"
對於未提供一些配置資訊,比如AutoFormat、AutoPart和AutoMount,則要使用系統提供的預設值。
當系統發現新的週邊儲存裝置時,儲存管理程式為其載入分割區驅動程式和檔案系統驅動程式的程序如下:
1.裝置管理程式負責載入區塊裝置的驅動程式,
2.由該裝置發出一個通知,告知儲存管理程式該裝置的裝置名稱及其GUID,
3.儲存管理程式根據註冊資訊中的配置資訊,為該裝置載入分割區驅動程式,
4.儲存管理程式列舉該裝置上的所有分割區,
5.儲存管理程式為每個分割區,載入檔案系統驅動程式。
5.1.3.1檔案系統篩檢程式
檔案系統篩檢程式和檔案系統驅動程式類似,它們都有一組輸出函式被CreateFile和CreateDirectory這類的標準檔案系統API映射到。
二者不同之處在於,檔案系統篩檢程式要提供HookVolume和UnhookVolume這兩個函式,而檔案系統驅動程式必須提供的是MountDisk和UnmountDisk這兩個函式。
檔案系統驅動程式和檔案系統篩檢程式的載入,都是透過檔案系統管理程式完成的。
有關檔案系統篩檢程式的資訊,也是保存在註冊資訊中。
檔案系統管理程式需要到以下各處搜尋應載入的檔案系統篩檢程式:
[HKEY_LOCAL_MACHINE\System\StorageManager\AutoLoad\FileSystem
\Filters]
[HKEY_LOCAL_MACHINE\System\StorageManager\Profiles\ProfileName
\FileSystem\Filters]
[HKEY_LOCAL_MACHINE\System\StorageManager\FileSystem\Filters]
[HKEY_LOCAL_MACHINE\System\StorageManager\Filters]
此處,FileSystem代表檔案系統在註冊資訊中所使用的名稱,例如FATFS、UDFS等等。
如果在
[HKEY_LOCAL_MACHINE\System\StorageManager\AutoLoad\FileSystem
\Filters]
[HKEY_LOCAL_MACHINE\System\StorageManager\Profiles\ProfileName
\FileSystem\Filters]
中出現了一個篩檢程式的話,那麼所有使用該配置資訊的檔案系統,都將使用該篩檢程式。
如果在
[HKEY_LOCAL_MACHINE\System\StorageManager\FileSystem\Filters]
中出現了一個篩檢程式的話,那麼名為FileSystem的檔案系統將使用該篩檢程式。
如果一個篩檢程式出現在
[HKEY_LOCAL_MACHINE\System\StorageManager\Filters]
中,那麼所有的檔案系統都將使用該篩檢程式。
下面是一個註冊資訊中有關篩檢程式資訊的例子:
[HKEY_LOCAL_MACHINE\System\StorageManager\...\Filters\FilterName]
"dll"="filter.dll"
"Order"=dword:
x
其中dll的值,是該篩檢程式所對應的動態連結程式庫,Order的值,則是建造篩檢程式堆疊時各篩檢程式之間的順序。
5.1.3.2檔案系統管理程式與檔案系統驅動程式
首先來看一下檔案系統驅動程式(FileSystemDriver-FSD)。
檔案系統驅動程式只適用於區塊裝置。
我們知道,任何裝置載入系統後,都需要對應的裝置驅動程式的配合才能得以工作,對於區塊裝置而言,自然也少不了區塊裝置驅動程式。
但是與其他裝置不同的是,區塊裝置除了需要直接和硬體溝通的區塊裝置驅動程式之外,還需要一個檔案系統驅動程式,這是因為,雖然區塊裝置驅動程式已經向上層提供了各種函式介面,透過這些介面就可以對區塊裝置進行初始化、讀寫資料區塊等等各種操作了,但是這種介面的操作物件卻是資料區塊,如果直接將這種介面提供給使用者使用的話,使用者所見到的區塊裝置就是一個雜亂無章、毫無規律的資料區塊集合,這對使用者而言非常地不方便。
因此必需將這些散亂的資料區塊,組織成檔案的形式,並向使用者提供一個按名存取的檔案系統介面,這就是檔案系統驅動程式的主要功能。
意即檔案系統驅動程式建立在區塊裝置驅動程式模組之上,負責對區塊裝置的進一步抽象,把毫無規律的資料區塊,組織成對使用者來說,更為方便易用的檔案,並向上提供了檔案操作的函式介面。
檔案系統程式與區塊裝置驅動程式間的關係如圖5.2所示。
圖5.2檔案系統驅動程式和區塊裝置驅動程式關係圖
CE.NET支援大多數WindowsXP或WindowsME使用的檔案I/O函式,例如CreateFile、ReadFile、WriteFile和CloseHandle等Win32API呼叫。
同時,CE.NET仍然遵循使用控制碼對檔案進行存取的傳統方法。
由CreateFile函式回傳,新建立或打開的檔案控制碼,之後的讀寫操作,都使用該控制碼來決定檔案操作的物件。
當然,對讀寫操作來說,還需要一個指標,來指出在檔案中進行讀寫的位置。
系統中所有的可安裝檔案系統,都是由檔案系統管理程式負責管理的。
每個可安裝檔案系統,都對應著一個檔案系統驅動程式,並且以動態連結程式庫(DynamicLinkLibrary)的形式提供,它有一組輸出函式被映射到標準的檔案系統Win32API上。
像CreateFile、ReadFile、WriteFile和CloseHandle這些檔案系統API的功能,最後都是呼叫某個檔案系統驅動程式的函式MyFSD_CreateFileW、MyFSD_ReadFile、MyFSD_WriteFile和MyFSD_CloseFile完成的。
另外值得注意的一點是,檔案系統驅動程式的動態連結程式庫的名字,與該檔案系統驅動程式的輸出函式的首碼(prefix)是相同的。
例如,如果檔案系統名為MyFSD,那麼對應的動態連結程式庫就是MyFSD.dll,其輸出函式的首碼為MyFSD_*。
在應用程式中存取可安裝檔案系統,使用的是標準的檔案系統Win32API。
例如,當應用程式想要在某個儲存裝置上建立一個目錄時,可以呼叫CreateDirectory。
之後由檔案系統管理程式對CreateDirectory中指明的路徑加以識別,如果發現該路徑指向一個使用可安裝檔案系統的裝置,便會呼叫相對應的檔案系統驅動程式-MyFSD.dll內的建立目錄函式MyFSD_CreateDirectoryW。
也就是說,應用程式呼叫CreateDirectory的結果,是導致檔案系統管理程式,呼叫相對應檔案系統驅動程式的函式MyFSD_CreateDirectoryW。
在CE.NET中,負責管理檔案系統驅動程式的模組,稱為檔案系統管理程式(FileSystemDriverManager)。
由於現代作業系統一般都支援多個檔案系統並存,因此需要對系統中用到的各個檔案系統加以管理,這就是檔案系統管理程式的作用。
從功能上講,CE.NET中的檔案系統管理程式與Linux中的虛擬檔案系統VFS類似,如圖5.3所示。
首先,作為不同的檔案系統,它們向上層提供的函式介面必然也是不同的。
但是,如果為了使用系統中不同的檔案系統,就必須記憶多套不同的函式介面,這對使用者來說是難以接受的。
我們所希望的是向使用者提供一套CreateFile、ReadFile、WriteFile和CloseHandle這樣的標準介面,為使用者隱藏掉不同的檔案系統間的差異。
這個任務就是由檔案系統管理程式來完成的。
在CE.NET中,使用者見到的並不是檔案系統驅動程式所提供的介面,而是經過檔案系統管理程式統一包裝過的Win32API函式介面。
這種統一介面的作法雖方便了使用者,但另一方面卻又不可避免的帶來了系統複雜性。
對使用者而言,使用者根本不用關心,他所使用的檔案所在的volume到底使用何種檔案系統,因為檔案系統管理程式已經為使用者隱藏了其中的細節,但是在進行的實際的檔案操作時,我們又必須要能夠找出對應的檔案系統,這也是由檔案系統管理程式來完成的。
在CE.NET中沒有目前目錄(currentdirectory)的概念,所有對檔案的存取都必需提供完整路徑名稱。
在為週邊儲存裝置安裝檔案系統驅動程式的同時,檔案系統管理程式會為其註冊一個標識性的目錄名稱。
如此一來,當使用者對週邊儲存裝置上的檔案進行存取時,檔案系統管理程式就可以根據使用者提供的完整目錄名稱,分析出該檔案所在的volume、使用的檔案系統等。
圖5.3檔案系統管理程式與檔案系統驅動程式關係圖
5.1.3.3分割區管理程式與分割區驅動程式
一個儲存裝置是由多個磁區(sector)組成的,每個磁區包含了一組連續的位元組,所有磁區的大小都是相同的。
儲存裝置可能被劃分為多個邏輯分割區,每個分割區由一組連續的磁區組成。
分割區之間不能相互重疊,否則作業系統將停止回應。
沒有被劃分到任何分割區中的儲存空間屬於未分割區空間。
分割區管理程式是儲存管理程式的一部分,它透過呼叫分割區驅動程式來完成對這些分割區的管理、掛載(mount)與卸載(unmount)。
同一儲存裝置上的不同分割區可以使用不同的檔案系統,每個分割區所使用的檔案系統類型是在建立或格式化時就確定了。
在對該分割區進行掛載時,分割區管理程式會通知儲存管理程式啟動對應的檔案系統。
CE.NET可以同時支援多個分割區驅動程式,但是對於一個指定的儲存裝置來講只能使用一個分割區驅動程式,由它為分割區管理程式解釋該裝置上的所有分割區。
如前所述,分割區是對儲存裝置進行邏輯劃分的結果。
在CE.NET中,多個分割區既可以使用相同的檔案系統,也可以使用不同的檔案系統。
分割區管理程式透過呼叫分割區驅動程式完成對分割區的操作。
分割區驅動程式也是以動態連結程式庫的形式提供的,在CE.NET中預設的分割區驅動程式是MSPart.dll,它輸出了一組API。
使用者也可以編寫自己的分割區驅動程式,只要該分割區驅動程式支援與MSPart.dll相同的API即可。
為了使自己編寫的分割區驅動程式MyPart.dll生效,還需要在註冊資訊的配置資訊中填寫"PartitionDriver"="MyPart.dll",這樣就可以使用自己的分割區驅動程式了。
表5.2說明了一個分割區驅動程式應該提供的所有函式。
表5.2分割區驅動程式提供的函式
函式名
功能
PD_ClosePartition
結束I/O操作,關閉分割區
PD_CloseStore
關閉儲存裝置上的volume
PD_CreatePartition
在儲存裝置的volume上建立分割區
PD_DeletePartition
從儲存裝置的volume上刪除分割區
PD_DeviceIoControl
向指定的裝置驅動程式直接發送控制碼,完成相對應的操作
PD_FindPartitionClose
關閉列舉分割區時使用的搜尋控制碼
PD_FindPartitionNext
在列舉分割區時得到下一個分割區的資訊。
PD_FindPartitionStart
開始列舉分割區。
PD_FormatPartition
在儲存裝置的volume上格式化一個分割區
PD_FormatStore
對儲存裝置進行格式化操作
PD_GetPartitionInfo
得到指定分割區的屬性資訊
PD_GetStoreInfo
得到儲存裝置的資訊
PD_IsStoreFormatted
查詢儲存裝置是否已被格式化
PD_OpenPartition
打開分割區以進行I/O操作
PD_OpenStore
打開儲存裝置上的volume
PD_Ren
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- WindowsCEnet 存储 管理
![提示](https://static.bdocx.com/images/bang_tan.gif)