第11章档案系统文档格式.docx
- 文档编号:17642180
- 上传时间:2022-12-07
- 格式:DOCX
- 页数:52
- 大小:963.93KB
第11章档案系统文档格式.docx
《第11章档案系统文档格式.docx》由会员分享,可在线阅读,更多相关《第11章档案系统文档格式.docx(52页珍藏版)》请在冰豆网上搜索。
此设备的组态信息在注册表中的位置。
•m_pPartDriver:
设备所使用的分区驱动程序。
•m_pPartitionList:
设备上的CPartition分区串行。
•m_dwStoreId:
由分区管理器维护的与此设备对应的DriverState结构的指针。
•m_pNextStore:
指向g_pStoreRoot队列中下一个CStore。
DriverState由分区管理器负责建立并维护,记录了一些与分区管理器有关的设备细节信息,其中一些成员变量的含义如下:
•pPartState:
设备上的PartState分区串行。
•pSearchState:
指向SearchState结构组成的串行。
•diskInfo:
设备参数,包括CHS值、每个扇区所含的字节数等等。
•snExtPartSector:
设备上扩展分区的起始扇区。
•snExtPartEndSec:
扩展分区的结束扇区。
CPartition也是一个类别,用于描述设备上的分区,由储存管理器负责建立并维护,其中一些成员变量的含义如下:
•m_dwPartitionId:
由分区管理器维护的与此分区对应的PartState的句柄。
与此分区所在的设备对应的DriverState结构的指针。
•m_szPartitionName:
分区的名称。
•m_szFileSys:
此分区所使用的档案系统的名称。
•m_pDsk:
指向由档案系统驱动程序负责维护的与此设备相关的DSK结构。
•m_hFSD:
档案系统驱动程序对应的动态链接库的句柄。
•m_pNextPartition:
指向同一设备上的下一个CPartition对象。
PartState是分区管理器为维护分区信息所使用的数据结构,与DriverState密切相关,其中一些成员变量的含义如下:
•cPartName:
•snStartSector:
该分区的起始扇区号。
•snNumSectors:
此分区所占用的扇区数,即分区大小。
•NextPartState:
指向同一设备上的下一个PartState结构。
•pState:
指向此分区所属设备的DriverState结构。
CPartDriver是一个类别,用于描述一个分区驱动程序,其成员变量m_hPartDriver记录了该分区驱动程序对应的动态链接库的句柄,其它的成员变量均为函数指针,与分区驱动程序的输出函数
一一对应。
以上这些数据结构的关系如图11-1所示:
图11-1几个重要数据结构的关系
下面再来看一下由档案系统驱动程序管理器负责建立并维护的FSD、DSK和VOL这三个数据结构。
FSD结构用来描述一个档案系统驱动程序或是一个过滤器,其中一些成员变量的含义如下:
•hFSD:
档案系统驱动程序或过滤器对应的动态链接库句柄。
•pfnMountDisk:
档案系统驱动程序的输出函数FSD_MountDisk的入口地址。
•pfnUnmountDisk:
档案系统驱动程序的输出函数FSD_UnmountDisk的入口地址。
•pfnHookVolume:
过滤器的输出函数FSD_HookVolume的入口地址。
•pfnUnhookVolume:
过滤器的输出函数FSD_UnhookVolume的入口地址。
•szFileSysName:
档案系统或过滤器的名称。
•szRegKey:
档案系统或过滤器的相关信息在注册表中的位置。
•wsFSD:
档案系统驱动程序输出函数的前置码(prefix)。
•apfnAFS、apfnFile和apfnFind:
记录了所有输出函数的入口地址。
每个档案系统驱动程序和过滤器除了对应一个FSD结构以外,还会对应一个DSK结构,其中一些成员变量的含义如下:
•pVol:
指向VOL结构组成的双向串行的开头结点。
•pFSD:
指向对应的FSD结构。
•fdi:
设备参数信息,包括CHS值、每个扇区所含的字节数等。
•pDeviceIoControl:
DeviceIoControl函数的入口地址。
VOL结构用于描述一个卷(volume),也就是一个分区,其中一些成员变量的含义如下:
•pDsk:
指向此卷(volume)所使用的最上层档案系统或过滤器所对应的DSK结构。
•dwVolData:
由FSDMGR_RegisterVolume提供的某一档案系统驱动程序中使用的VOLUME结构的指针。
•iAFS:
由FSDMGR_RegisterVolume获得的AFS号。
11.1.2情景分析
首先看一下WindowsCE与档案系统相关的原始码组织。
在下面的说明中,%_WINCEROOT%代表安装WINCE400的根目录。
•%_WINCEROOT%\PRIVATE\WINCEOS\COREOS\FSD:
三种档案系统驱动程序的实作,包括FAT、RELFSD以及UDFS。
•%_WINCEROOT%\PRIVATE\WINCEOS\COREOS\STORAGE:
储存管理器的实作。
•%_WINCEROOT%\PRIVATE\WINCEOS\COREOS\STORAGE\DOSPART:
MSPart.dll的实作。
•%_WINCEROOT%\PRIVATE\WINCEOS\COREOS\STORAGE\FSDMAIN:
档案系统驱动程序管理器的实作。
•%_WINCEROOT%\PRIVATE\WINCEOS\COREOS\STORAGE\FSDSERV:
档案系统驱动程序管理器使用的一些服务例程及其提供的API。
•%_WINCEROOT%\PRIVATE\WINCEOS\COREOS\STORAGE\STOREAPI:
储存管理器提供的API的封装。
•%_WINCEROOT%\PRIVATE\WINCEOS\COREOS\STORAGE\STOREMGR:
储存管理器的启动原始码,CStore和CPartition等类别的实作。
另外,与Ramdisk相关的原始码位于以下两个目录:
•%_WINCEROOT%\PUBLIC\COMMON\OAK\DRIVERS\BLOCK\RAMDISK\DRIVER:
Build此目录下的源文件可以得到Ramdisk的驱动程序ramdisk.dll。
•%_WINCEROOT%\PUBLIC\COMMON\OAK\DRIVERS\BLOCK\RAMDISK\LOADER:
Build此目录下的源文件可以得到Ramdisk的安装程序ceramdrv.exe,该程序用于启动Ramdisk。
下面就以Ramdisk的安装程序为例说明当系统中出现新的外围储存设备时,其设备驱动程序、分区驱动程序以及档案系统驱动程序是如何被装入系统的,以及系统是如何透过设备管理器和储存管理器来管理新发现的设备。
在系统的启动程序中会自动加载两个模块,一个是filesys.exe,与对象储存相关的基于RAM和基于ROM的档案系统的功能就是由该模块实作的;
另一个是fsdmgr.dll,当新的外围储存设备装入系统时由它负责加载FAT这种可安装的档案系统。
系统在装入fsdmgr.dll这一模块时会呼叫初始化函数Init,而建立储存管理器分层结构的入口点位于Init函数中的InitStorageManager。
在InitStorageManager中,首先会呼叫CreateAPISet和RegisterAPISet注册储存管理器对外提供的API集合,另外负责建立g_hPNPUpdateEvent这一事件。
下面透过CreateMsgQueue建立了一个讯息队列g_hPNPQueue,由于msgopts.bReadAccess被设为TRUE,因此在StorageManager这方面来讲只能对该讯息队列进行读取操作。
之后是启动用于支持即插即用的执行绪PNPThread。
在此执行绪中,首先由GetProcAddress得到RequestDeviceNotifications和StopDeviceNotifications这两个函数在coredll.dll中的入口地址,然后透过呼叫RequestDeviceNotifications告知设备管理器将发现新的区块设备的通告写入讯息队列g_hPNPQueue中。
这些准备工作完成后PNPThread将进入一个无限循环,每隔一定时间对g_hPNPQueue和g_hPNPUpdateEvent进行一次轮询。
如果设备管理器发现新设备,会透过WriteMsgQueue向讯息队列中写入含有新设备信息(GUID,设备名等)的DEVDETAIL结构。
这时,在PNPThread执行绪中就可以透过ReadMsgQueue将此信息读出,并呼叫MountStore来进行下面的加载工作。
***
%_WINCEROOT%\PRIVATE\WINCEOS\COREOS\STORAGE\STOREMGR\storemain.cppLine608***
BOOLInitStorageManager()
{
DWORDdwThreadId=0;
intiAFS=INVALID_AFS;
MSGQUEUEOPTIONSmsgopts;
iAFS=RegisterAFSName(L"
StoreMgr"
);
if(iAFS!
=INVALID_AFS&
&
GetLastError()==0){
g_hSTRMGRApi=CreateAPISet("
PFSD"
ARRAY_SIZE(apfnSTGMGRAPIs),(constPFNVOID
*)apfnSTGMGRAPIs,asigSTGMGRAPIs);
if(!
RegisterAFSEx(iAFS,g_hSTRMGRApi,(DWORD)1,AFS_VERSION,AFS_FLAG_HIDDEN)){
DEBUGMSGW(ZONE_INIT,(DBGTEXTW("
STOREMGR:
InitStoreMgrfailedregisteringsecondaryvolume\r\n"
)));
DeregisterAFSName(iAFS);
gotoFail;
}
}else{
}
//建立API集合
g_hFindStoreApi=CreateAPISet("
FSTG"
ARRAY_SIZE(apfnFindStoreAPIs),(constPFNVOID*)apfnFindStoreAPIs,asigFindStoreAPIs);
g_hFindPartApi=CreateAPISet("
FPRT"
ARRAY_SIZE(apfnFindPartAPIs),(constPFNVOID*)apfnFindPartAPIs,asigFindPartAPIs);
g_hStoreApi=CreateAPISet("
STRG"
ARRAY_SIZE(apfnSTGAPIs),(constPFNVOID*)apfnSTGAPIs,asigSTGAPIs);
g_hPNPUpdateEvent=CreateEvent(NULL,FALSE,FALSE,NULL);
//建立讯息队列,储存管理器对该队列只能进行读取操作
msgopts.dwSize=sizeof(MSGQUEUEOPTIONS);
msgopts.dwFlags=0;
msgopts.dwMaxMessages=0;
//?
msgopts.cbMaxMessage=sizeof(g_pPNPBuf);
msgopts.bReadAccess=TRUE;
g_hPNPQueue=CreateMsgQueue(NULL,&
msgopts);
g_hFindPartApi||!
g_hFindStoreApi||!
g_hStoreApi||!
g_hPNPUpdateEvent||!
g_hPNPQueue)
//注册API集
RegisterAPISet(g_hFindStoreApi,HT_FIND|REGISTER_APISET_TYPE);
RegisterAPISet(g_hFindPartApi,HT_FIND|REGISTER_APISET_TYPE);
RegisterAPISet(g_hStoreApi,HT_FILE|REGISTER_APISET_TYPE);
InitializeCriticalSection(&
g_csStoreMgr);
//启动PNP执行绪,随时准备加载新发现的外围储存设备
if(g_hPNPThread=CreateThread(NULL,0,PNPThread,NULL,0,&
dwThreadId)){
returnTRUE;
Fail:
CloseAllGlobalHandles();
returnFALSE;
%_WINCEROOT%\PRIVATE\WINCEOS\COREOS\STORAGE\STOREMGR\storemain.cpp
Line493***
DWORDPNPThread(LPVOIDlParam)
externconstTCHAR*g_szSTORAGE_PATH;
//=L"
System\\StorageManager"
;
externconstTCHAR*g_szReloadTimeOut;
UnloadDelay"
DWORDdwFlags,dwSize;
//KEYhDevKey;
HANDLEhReg;
DEVDETAIL*pd=(DEVDETAIL*)g_pPNPBuf;
GUIDguid={0};
HANDLEpHandles[2];
TCHARszGuid[MAX_PATH];
HMODULEhCoreDll;
DWORDdwTimeOut=INFINITE,dwTimeOutReset=DEFAULT_TIMEOUT_RESET;
PSTOPDEVICENOTpStopDeviceNotification=NULL;
PREQUESTDEVICENOTpRequestDeviceNotification=NULL;
pHandles[0]=g_hPNPQueue;
pHandles[1]=g_hPNPUpdateEvent;
HKEYhKey;
//从注册表[HKEY_LOCAL_MACHINE\System\StorageManager]处读取
//PNPUnloadDelay的值
if(ERROR_SUCCESS==RegOpenKeyEx(HKEY_LOCAL_MACHINE,g_szSTORAGE_PATH,0,0,hKey)){
FsdGetRegistryValue(hKey,g_szReloadTimeOut,&
dwTimeOutReset)){
dwTimeOutReset=DEFAULT_TIMEOUT_RESET;
}
}
DEBUGMSG(ZONE_INIT,(L"
UsingPNPunloaddelayof%ld\r\n"
dwTimeOutReset));
AutoLoadFileSystems();
//由coredll.dll中得到RequestDeviceNotifications和StopDeviceNotifications两个函数
//的入口地址
hCoreDll=(HMODULE)LoadLibrary(L"
coredll.dll"
if(hCoreDll){
pRequestDeviceNotification=(PREQUESTDEVICENOT)GetProcAddress(hCoreDll,L"
RequestDeviceNotifications"
pStopDeviceNotification=(PSTOPDEVICENOT)GetProcAddress(hCoreDll,L"
StopDeviceNotifications"
FreeLibrary(hCoreDll);
if(pRequestDeviceNotification&
pStopDeviceNotification){
DEBUGMSG(ZONE_INIT,(L"
PNPThreadCreated\r\n"
));
while(!
IsAPIReady(SH_DEVMGR_APIS)){
Sleep(1000);
//告知系统将新发现的区块装置的信息写入刚刚建立的讯息队列g_hPNPQueue中
hReg=pRequestDeviceNotification(&
BLOCK_DRIVER_GUID,g_hPNPQueue,TRUE);
while(TRUE){
DWORDdwWaitCode;
dwWaitCode=WaitForMultipleObjects(2,pHandles,FALSE,dwTimeOut);
if(dwWaitCode==WAIT_OBJECT_0){
//讯息队列有新的讯息写入,读取有关新设备的信息
if(ReadMsgQueue(g_hPNPQueue,pd,sizeof(g_pPNPBuf),&
dwSize,INFINITE,&
dwFlags)){
FsdStringFromGuid(&
pd->
guidDevClass,szGuid);
DEBUGMSG(ZONE_INIT,(L"
Gotaplugandplayevent%Class(%s)Attached=%s!
!
\r\n"
pd->
szName,szGuid,pd->
fAttached?
L"
TRUE"
:
L"
FALSE"
//检查新发现的设备是否为区块装置
if(memcmp(&
guidDevClass,&
BLOCK_DRIVER_GUID,sizeof(GUID))==0){
//如果新的区块装置的状态为Attached则继续后面的加载工作
if(pd->
fAttached){
//将设备名及其GUID作为参数传给MountStore
MountStore(pd->
szName,pd->
guidDevClass);
⋯⋯//后面略去
对于Ramdisk来说,当运行其安装程序ceramdrv.exe之后,系统便会发现这块虚拟的外围储存设备并首先由设备管理器负责为其加载区块装置驱动程序ramdisk.dll。
Ramdisk所使用的设备驱动程序等信息是由安装程序ceramdrv.exe填写进注册表的,见图11-2,其中dll的键值就是Ramdisk的设备驱动程序,而IClass的键值{A4E7EDDA-E575-4252-9D6B-4195D48BB865}即为CE中标识区块设备所用的GUID,它将作为参数之一传给MountStore。
另外还有很重要的一个键是Profile,它的键值指明了Ramdisk的组态信息所在的位置,在后面还会提到这一点。
另外,在成功为其装入区块装置驱动程序之后,设备管理器会将Ramdisk作为已经启动(Active)的设备填写进注册表(见图11-3),并透过WriteMsgQueue将Ramdisk的设备名及其GUID等信息写入讯息队列。
可以看到,与Ramdisk有关的设备基本信息位于[HKEY_LOCAL_MACHINE\Drivers\Builtin\Ramdisk],也就是图11-2所示的注册表位置;
另外,Name的键值即为Ramdisk的设备名称,也就是说DSK1:
将作为参数之一传给MountStore。
图11-2注册表中有关Ramdisk的信息
图11-3Ramdisk启动之后的注册表
进入MountStore之后,首先在由StorageManager维护的以g_pStoreRoot为开头结点的串行中寻找是否已存在具有相同设备名的store。
如果发现了具有相同设备
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 11 档案 系统