2.Windows CE注册表的实现方式
嵌入式系统的特点是小型化,因此一些嵌入式设备是没有外存的。为此Windows CE注册表提供了两种实现方式:基于RAM的注册表(RAM-Based Registry)和基于Hive的注册表(Hive-Based Registry)。在定制内核的时候只能选择其中一种,从理论上讲这两种注册表都能够实现永久保存注册表数据。注册表实现类型对于用户和应用程序来说是透明的,但是采用不同的类型会影响Windows CE的启动顺序和启动速度,还会影响内存的使用量。
(1)基于RAM的注册表
基于RAM的注册表,也叫基于对象存储(Object Storage)的注册表。正如其名,基于RAM的注册表把整个注册表作为一个对象存储堆存放在系统的内存中。这意味着如果对系统进行冷启动或者系统断电,对注册表的所有改动都会丢失。优点是使用基于RAM的注册表,对注册表的读写访问操作会变得非常高效。因此,基于RAM的注册表比较适用于没有外部存储,而且有电池保存内存数据(battery-backed RAM)的设备,它适合频繁热启动而不冷启动的设备。
如果有外存且经常冷启动的设备采用基于RAM的注册表,则需要在系统断电的时候对注册表进行保存,等系统再次启动时再对保存的注册表进行还原。为此,Windows CE提供了两种方法用来断电保存基于RAM的注册表:
①第一种方式是在设备关闭前调用RegCopyFile函数,将整个注册表数据以文件形式保存到永久存储器上。Windows CE提供了两个系统API用来保存和还原整个注册表。当要保存和恢复注册表时,先在系统断电的时候调用RegCopyFile函数将整个注册表保存为外存上的一个文件;当系统重新启动时再调用RegRestoreFile函数将文件全部读出RAM中,然后再热启动系统,先前保存的注册表就可以生效了。
需要注意的是,这时必须多一次热启动才能使恢复的注册表有效。因为只有在系统启动的时候才会去检测RegRestoreFile放在RAM里的注册表信息。但是此方法的缺点是需要两次启动,因此效率相对比较低。
②第二种方式是利用OEM函数。这一种方式可以避免前一种方式需要两次启动的缺点。OEM可以在BSP的OAL层中实现 WriteRegistryToOEM和ReadRegistryFromOEM两个函数。Windows CE会在系统启动和关闭的时候自动调用这两个函数来保存和恢复注册表。当应用程序调用RegFlushKey函数时,这个函数会调用 WriteRegistryToOEM函数写注册表数据到永久存储器上。
此种方法虽然可以避免两次启动的缺陷,但问题是在内核启动时,调用ReadRegistryFromOEM之前文件系统驱动程序还没加载,因此无法使用 CreateFile,ReadFile API来打开、读取文件,而只能使用一些更底层的操作来实现。因此,建议如果要采用基于RAM的注册表保存机制,而且要求永久保存注册表数据,使用第一种方式比较容易实现。
(2)基于Hive的注册表
基于Hive的注册表是把注册表数据存放在文件系统的文件上,这种文件被称作蜂箱Hive。这就意味着不再需要在系统断电和启动时进行保存恢复注册表操作。Hive是注册表中的一组键,包括子键、键值、数据,它是保存或者加载注册表数据的单位。
Hive在文件系统上表现为单个文件,分为:①Boot Hive,包括HKEY_LOCAL_MACHINE, HKEY_CLASSES_ROOT, HKEY_USERS中的所有数据,一般只在启动时使用。②System Hive,包括OEM的HKEY_LOCAL_MACHINE, HKEY_CLASSES_ROOT, HKEY_USERS的所有数据,是指设备范围内不随着用户改变而改变的数据。③User Hive,包括HKEY_CURRENT_USER的所有数据,是指用户特有的设置,每个用户都有一个单独的User.hv。
基于Hive的Windows CE注册表加载过程可分为两部分:boot.hv和system.hv。前者是启动时的注册表项,后者是系统注册表项。所谓Hive注册表就是先加载 boot.hv,把注册表保存所在的存储驱动和文件系统先加载;然后再加载system.hv,也就是从磁盘上去读系统的注册表项。在启动时加载 boot.hv的标签是HIVE BOOT SECTION 和END BOOT SECTION。
基于Hive的注册表适用于有永久存储并且需要经常冷启动的设备。因为基于Hive的注册表把系统数据和用户数据分开存放,这就意味着基于Hive的注册表可以提供多用户支持。例如,为对每个用户提供不同的User.hv,当用户登录时加载相应的User.hv,从而达到多用户目的。
3.Windows CE加载注册表的步骤
Windows CE采用新的注册表保存技术,基于Hive的注册表是让人很兴奋的事情。在这之前基于Windows CE的设备,大多数采用给RAM供电方式来保存注册表数据,虽然也可以通过RegCopyFile函数永久保存,但毕竟启动时还要再热启动一次。有了基于 Hive的技术,启动系统会自动加载数据,免去了热启动的麻烦。而且当内核更新升级时,不用再担心保存在永久存储器上的系统HIVE文件影响新的内核,因为系统会自动判断并删除过时的系统HIVE文件。
实际上,也可以认为只有拥有了这样的技术,基于Windows CE的产品才算是一个真正的电脑。现在以基于Hive的注册表为例,简述Windows CE在启动时是如何加载已保存的注册表数据:
(1)nk.exe执行,启动filesys.exe。filesys.exe首先加载Boot Hive,此时Boot Hive位于nk.bin解压之后的文档中。然后,filesys.exe启动device.exe后处于等待状态,等待device.exe将包含 System Hive的文档系统和存储设备的驱动程序加载完毕,而这个文档系统和存储设备的驱动程序存在于Boot Hive中。
(2)device.exe加载上述所说的文档系统驱动和存储设备驱动,使之开始工作。之后device.exe处于等待状态。然后,filesys.exe再被唤醒,加载并且安装System Hive,然后filesys.exe再次处于等待状态。
(3)nk.exe按照System Hive的信息开始执行初始化工作,包括加载驱动和启动一些应用程序。其中加载驱动一般由device.exe执行,而启动应用程序由filesys.exe执行。这时device.exe和filesys.exe都被唤醒。
因为Boot Hive和System Hive可能有重复的地方,所以可能重复加载了驱动或重复启动了应用程序。为此,Windows CE允许在描述驱动程序的注册表信息中加入防止重复的标志,而应用程序是采用事件对象来防止重复启动。
/////////////////////////////////////////
桌面Windows一样,Windows CE也使用注册表(Registry)来保存应用程序、驱动程序和用户的设定以及其他一些配置信息。Windows CE注册表也采用树形结构来管理配置信息,由于Windows CE注册表的结构和功能与桌面Windows几乎一样,在这里就不详细介绍了,读者可以参考其它关于注册表的资料。
【注册表实现类型对于用户和应用程序来说是透明的,但是采用不同的类型会影响Windows CE的启动顺序和启动速度,还会影响内存的使用量。】
Windows CE支持四个根键,描述如下:
键名 描述
HKEY_LOCAL_MACHINE 硬件和驱动配置数据
HKEY_CURRENT_USER 用户配置数据
HKEY_CLASSES_ROOT OLE和文件类型匹配配置数据
HKEY_USERS 适用于所有用户的数据
由于嵌入式系统的特点,一些嵌入式设备是没有外存的。因此Windows CE的注册表提供了两种实现方式:基于RAM的注册表(RAM-Based Registry)和基于Hive的注册表(Hive-Based Registry)。我们可以选择在Windows CE中使用任何一种注册表,注册表类型对于用户和应用程序来说是透明的。
◎ 基于RAM的注册表
基于RAM的注册表,也叫基于对象存储(Object Storage)的注册表。正如其名,基于RAM的注册表把整个注册表作为一个对象存储堆存放在系统的内存中。这意味着如果对系统进行冷启动或者系统断电,对注册表的所有改动都会丢失。优点是使用基于RAM的注册表,对注册表的读写访问操作会变得非常高效。因此,基于RAM的注册表比较适用于没有外部存储,而且有电池保存内存数据(battery-backed RAM)的设备,它适合频繁热启动而不冷启动的设备。
如果有外存且经常冷启动的设备采用基于RAM的注册表,则需要在系统断电的时候对注册表进行保存,等系统再次启动时再对保存的注册表进行还原。为此,Windows CE提供了两种方法用来断电保存基于RAM的注册表:
Windows CE提供了两种方法用来断电保存基于RAM的注册表:
1. Windows CE提供了两个系统API用来保存和还原整个注册表,它们的原形如下:
BOOL RegCopyFile(
LPCWSTR lpszFile // 保存注册表信息的文件的名字
);
BOOL RegRestoreFile(
LPCWSTR lpszFile // 保存注册表信息的文件的名字
);
如果要保存和恢复注册表,我们只需要在系统断电的时候调用RegCopyFile函数将整个注册表保存为外存上的一个文件。当系统重新启动时,我们再调用RegRestoreFile函数将文件全部读出RAM中,然后再热启动系统,我们保存得注册表就可以生效了。值得注意的是这次热启动是必须的,因为只有在系统启动的时候才会去检测RegRestoreFile放在RAM里的注册表信息。这种方法的优点是完全可以使用应用程序来实现基于RAM的注册表的保存,而且这种方法相对简单。但是此方法的缺点是需要两次启动。因此效率相对比较低。
2. 第二种方法需要OEM的参与,OEM可以在BSP的OAL层中实现WriteRegistryToOEM和ReadRegistryFromOEM两个函数,它们的声明为:
DWORD ReadRegistryFromOEM(
DWORD dwFlags, // 参数, REG_READ_BYTES_START表示读新的注册表
LPBYTE lpData, // 指向注册表数据的缓冲区,由OS分配
DWORD cbData // 缓冲区的大小
);
BOOL WriteRegistryToOEM(
DWORD dwFlags, // 参数,REG_WRITE_BYTES_START表示写新的注册表
LPBYTE lpData, // 指向注册表数据的缓冲区,由OS分配
DWORD cbData // 缓冲区的大小,0表示到达注册表尾部
);
Windows CE会在系统启动和关闭的时候调用这两个函数来保存和恢复注册表。此种方法虽然可以避免两次启动,但是困难的地方是ReadRegistryFromOEM函数的实现比较困难,因为在系统启动的时候,块设备驱动和文件系统的驱动都还没有加载,因此不能使用CreateFile,ReadFile这样的文件系统API来实现ReadRegistryFromOEM函数,只能使用一些更底层的操作来实现。
◎ 基于Hive的注册表
基于Hive的注册表是把注册表数据存放在文件系统的文件上,这种文件被称作蜂箱Hive。这就意味着不再需要在系统断电和启动时进行保存恢复注册表操作。Hive是注册表中的一组键,包括子键、键值、数据,它是保存或者加载注册表数据的单位。
Hive在文件系统上表现为单个文件,分为:①Boot Hive,包括HKEY_LOCAL_MACHINE, HKEY_CLASSES_ROOT, HKEY_USERS中的所有数据,一般只在启动时使用。②System Hive,包括OEM的HKEY_LOCAL_MACHINE, HKEY_CLASSES_ROOT, HKEY_USERS的所有数据,是指设备范围内不随着用户改变而改变的数据。③User Hive,包括HKEY_CURRENT_USER的所有数据,是指用户特有的设置,每个用户都有一个单独的User.hv。
基于Hive的Windows CE注册表加载过程可分为两部分:boot.hv和system.hv。前者是启动时的注册表项,后者是系统注册表项。所谓Hive注册表就是先加载boot.hv,把注册表保存所在的存储驱动和文件系统先加载;然后再加载system.hv,也就是从磁盘上去读系统的注册表项。在启动时加载boot.hv的标签是HIVE BOOT SECTION 和END BOOT SECTION。
基于Hive的注册表适用于有永久存储并且需要经常冷启动的设备。因为基于Hive的注册表把系统数据和用户数据分开存放,这就意味着基于Hive的注册表可以提供多用户支持。例如,为对每个用户提供不同的User.hv,当用户登录时加载相应的User.hv,从而达到多用户目的。
--------------------------------------------------------------------------------------------------------------
关于wince注册表的几个问题
1、Hive_based 和 ram_based的CE系统哪个启动更快?
2、我所谓的启动过程指的是从冷启动到所有的内置的驱动都已加载的过程,大约各需要多长时间?
3、采用基于hive的注册表(注册表文件较大)是否有可能导致系统的文件系统被破坏的概率加大?
4、就你认为,采用RAM+外部文件,即将用户改动的信息放在外部存储器上,当用户开机时读取外部文件,修改注册表的相应内容和采用基于hive的注册表,两者哪个更有优势一些?请从整个系统的角度多方面给出综合的建议。
============================
在WinCE第一次引导的时候,所有的.hv都会被放到RAM中,WinCE系统会首先读取boot.hv进行相关引导时候的设置.当系统第二次启动的时候,会比较磁盘上的.hv和内存中的.hv是否一致,如果不一致,会拷贝磁盘上面的.hv到内存中.
我们可以看出,实际上HIVE注册表在运行的时候也是放在RAM中的,这样速度比较快.启动的时候会从磁盘上读出,在用户更改注册表以后,会被保存在磁盘上,保存的时机也是可以设置的,可以选择在用户更改后立刻保存到磁盘上,也可以选择在reboot的时候保存.
因此,RAM的速度要快(ROM速度就是比RAM慢,要不PDA上就会用大RAM加扩展卡解决).不会导致破坏机率加大,因为HIVE只是在ROM存取次数多.ROM不是机械式的.应该是HV方案有优势,毕竟这是系统解决的办法.你说的RAM+外存也类似HV,但自定义的优化没有现成的好.
------疑问--------
1、当系统第二次启动的时候,会比较磁盘上的.hv和内存中的.hv是否一致,如果不一致,会拷贝磁盘上面的.hv到内存中.
是不是说反了?一般磁盘上的.hv(system.hv) 和内存中的.hv(boot.hv)不一致是由操作系统升级(内核更新)引起的。此时引导hive是最新的,当与磁盘上的hv不一致的时候,应该替换掉system.hv才对吧,不知理解是否正确?
2、注册表修改的保存时机一般是在reboot的时候保存还是立刻保存到磁盘上比较好?
3、应该是HV方案有优势,毕竟这是系统解决的办法.你说的RAM+外存也类似HV,但自定义的优化没有现成的好
优化指的是哪些方面?能否详细说一下
/////////////////////////////////////////////
1.让桌面不显示"我的电脑","回收站"
删除以下键值:
[HKEY_LOCAL_MACHINE\Explorer\Desktop]
{000214A0-0000-0000-C000-000000000046} ;"My Computer"
{000214A1-0000-0000-C000-000000000046} ;Recycle Bin"
存在这两个键值的文件有:
$(_WINCEROOT)\PUBLIC\SHELL\OAK\FILES\shell.reg
$(_WINCEROOT)\PUBLIC\WCESHELLFE\OAK\FILES\wceshellfe.reg
$(_WINCEROOT)\PUBLIC\WCESHELLFE\OAK\FILES\wceshellfe88.reg
2.直接删除文件,不放回回收站
[HKEY_LOCAL_MACHINE\Explorer]
"UseRecycleBin"=dword:0 ;设置0为直接删除;设置1为放入回收站
3.修改XP皮肤的系统界面颜色
如果选择了XP SKIN,则在控制面板的"显示"选项中是无法更改一些窗口的颜色的.不过,我们倒是可以通过更改$(_WINCEROOT)\PUBLIC\COMMON\OAK\FILES\common.reg文件中的XP颜色参数来达到更改窗口颜色的目的.
原XP样式的颜色参数如下:
[HKEY_LOCAL_MACHINE\SYSTEM\GWE]
"SysColor"=hex:\
00,00,00,00,\
3A,6E,A5,00,\
00,00,00,00,\
00,00,00,00,\
EF,EB,DE,00,\
FF,FF,FF,00,\
00,00,00,00,\
00,00,00,00,\
00,00,00,00,\
FF,FF,FF,00,\
C0,C0,C0,00,\
C0,C0,C0,00,\
80,80,80,00,\
31,69,C6,00,\
FF,FF,FF,00,\
EF,EB,DE,00,\
AD,AA,9C,00,\
80,80,80,00,\
00,00,00,00,\
00,00,00,00,\
FF,FF,FF,00,\
73,6D,63,00,\
FF,FF,FF,00,\
00,00,00,00,\
FF,FF,E1,00,\
EF,EB,DE,00,\
00,00,00,00
代表的意思是:
0 COLOR_SCROLLBAR Color of the gray area of a scroll bar.
1 COLOR_BACKGROUND Background color of the desktop window.
2 COLOR_ACTIVECAPTION Color of the title bar of an active window.
3 COLOR_INACTIVECAPTION Color of the title bar of an inactive window.
4 COLOR_MENU Background color of a menu.
5 COLOR_WINDOW Background color of a window.
6 COLOR_WINDOWFRAME Color of a window frame.
7 COLOR_MENUTEXT Color of the text in a menu.
8 COLOR_WINDOWTEXT Color of the text in a window.
9 COLOR_CAPTIONTEXT Color of the text in a title bar and of the size box and scroll bar arrow box.
10 COLOR_ACTIVEBORDER Color of the border of an active window.
11 COLOR_INACTIVEBORDER Color of the border of an inactive window.
12 COLOR_APPWORKSPACE Background color of multiple document interface (MDI) applications.
13 COLOR_HIGHLIGHT Color of an item selected in a control.
14 COLOR_HIGHLIGHTTEXT Color of the text of an item selected in a control.
15 COLOR_BTNFACE Color of the face of a button.
16 COLOR_BTNSHADOW Shadow color of buttons for edges that face away from the light source.
17 COLOR_GRAYTEXT Color of shaded text. This color is set to 0 if the current display driver does not support a solid gray color.
18 COLOR_BTNTEXT Color of the text for push buttons.
19 COLOR_INACTIVECAPTIONTEXT Color of the text in the title bar of an inactive window.
20 COLOR_BTNHIGHLIGHT Highlight color of buttons for edges that face the light source.
21 COLOR_3DDKSHADOW Color of the dark shadow for three-dimensional display elements.
22 COLOR_3DLIGHT Highlight color of three-dimensional display elements for edges that face the light source.
23 COLOR_INFOTEXT Color of the text for ToolTip controls.
24 COLOR_INFOBK Background color for ToolTip controls.
25 COLOR_STATIC Background color for static controls and dialog boxes. Supported in Windows CE 2.0 and later.
26 COLOR_STATICTEXT Color of the text for static controls. Supported in Windows CE 2.0 and later.
27 COLOR_GRADIENTACTIVECAPTION Color of the title bar of an active window that is filled with a color gradient.
28 COLOR_GRADIENTINACTIVECAPTION
4.文件夹映射更改
假设我们要将"桌面"文件夹从根目录(在这里指的是RAM空间)移动到某个外部储存器"HardDisk"中,可以按如下步骤:
1.将$(_WINCEROOT)\PUBLIC\COMMON\OAK\FILES\INTLTRNS\0804\common.str文件中的LOC_PATH_DESKTOP宏定义改为"file://harddisk//Windows//桌面"
2.然后将所有.dat文件中关于LOC_DESKTOP_DIR的选项,全部在windows前添加"\HardDisk",
如:Directory("\Windows\LOC_DESKTOP_DIR"):-File("LOC_INTERNETEXPLORER_LNK", "\Windows\iesample.lnk")
改为:Directory("\HardDisk\Windows\LOC_DESKTOP_DIR"):-File("LOC_INTERNETEXPLORER_LNK", "\Windows\iesample.lnk")即可.
如果有创建文件夹的话,也要改:
如:root:-Directory("\LOC_PROGRAMFILES_DIR")
改为:root:-Directory("HardDisk\LOC_PROGRAMFILES_DIR")