Windows平台使用C语言在用户模式下注册表的增删改查
一、Wiodws注册表介绍
Windows操作系统提供了一个称为“注册表”的中心存储设施作为系统的配置和管理中心。应用程序和内核通过访问注册表来读写各种配置。Windows同时提供了一些API供应用程序访问注册表,这些API函数在接到注册表访问请求后会将他们转发给内核的系统服务。然后内核会做出相应的处理。
Widows注册表是一个树状结构,每一个节点是一个键或值。键是一个容器,好比文件系统中的文件夹,值存储的是数据,相当于文件系统的文件,键可以包含其它的键(目录)或值(文件)。注册表的根目录称为根键,通常而言注册表对于一般的计算机用户是隐藏的,也即,桌面用户没必要知道注册表的存在。但是,高级用户则需要通过一些工具来访问注册表,Windows系统提供了一个默认的注册表编辑工具(regedit,通过Win+R键输入regedit来打开)。软件安装程序和应用程序则需要通过调用Windows API来操作注册表。
注册表的值(文件)有多重数据类型,它相当于文件系统中文件类型。这些数据类型包括:REG_DWORD(32位整数)、REG_BINARY(二进制数据)、和REG_SZ(字符串)等格式。这些格式仅仅是规定了值的数据结构,但是其存储的形式依然是二进制,就像某种格式的文件内部依然有其数据结构。
注册表的顶级结构下8个根键,它们的缩写和含义如表1所示,其中HKEY_PERFORMANCE_<XXX>根键在regedit.exe中是不可见的,它们是性能数据,并非真正位于注册表中,它们实际上反映了内存中的状态信息,只不过Windows为上层应用程序提供了通过注册表API来获取性能信息的便捷途径而已。
根键 | 缩写 | 说明 |
HKEY_USERS | HKU | 有关该机器上所有的用户的账户信息 |
HKEY_LOCAL_MEACHIN | HKLM | 当前系统的信息 |
HKEY_CURRENT_USER | HKCU | 当前用户的信息,它符号链接自HKU中对应当前用户的子键 |
HKEY_CLASSES_ROOT | HKCR | 保存文件关联和COM的设置信息,它是HKLM\SOFTWARE\Classes 和HKCU\SOFTWARE\Classes两颗子树合并后的视图 |
HKEY_CURRENT_CONFIG | HKCC | 有关当前硬件的配置信息,它符号链接自 HKML\SYSTEM\CurrentControlSet\Hardware Profiles\Current |
HKEY_PERFORMANCE_DTAT | HKPD | 与性能有关的数据,这是系统的运行状态信息 |
HKEY_PERFORMANCE_TEXT | 以美国英语的文本来描述的性能计数器 | |
HKEY_PERFORMANCE_NLSTEXT | 以系统本地语言的文本来描述的性能计数器 |
二、操作注册表的函数
注意:这里我们统一采用UNICODE为字符编码的函数。
1.打开注册表
LSTATUS RegOpenKeyExW(//打开指定的注册表项。注意:键名不区分大小写。如果函数调用成功返回ERROR_SUCCESS
HKEY hKey,//一个已经打开过的注册表项的句柄,或是注册表的一个根键(5个宏定义之一,分别是表1的前5个根键)
LPCSTR lpSubKey,//注册表子项的名称,以hKey为根目录的子项目录路径,就像文件路径一样,这里以hKey为根路径。注意:子项名不区分大小写
DWORD ulOptions,//打开这个注册表子项的选项,可以是0或是REG_OPTION_OPEN_LINK
REGSAM samDesired,//所需的访问权限,不要直接用KEY_ALL_ACCESS,应当根据访问方式使用“|”来将访问权限进行组合,可选的有KEY_READ,KEY_SET_VALUE,KEY_WRITE,KEY_QUERY_VALUE等
PHKEY phkResult//该指针变量接收打开键成功后的句柄。如果该键不是预定义的注册表项之一,则在完成使用句柄后调用RegCloseKey函数来关闭注册表
);
2.枚举注册表的子项
当打开注册表成功后,我们需要检索其子目录(如果需要的话),使用RegEnumKeyExW函数检索其子健(子目录)