注册表实际上是一个管理配置系统运行参数的核心数据库,它记录了安装软件与运行程序的关联关系,计算机的硬件配置等信息。可以说计算机上所有针对硬件、软件、网络的操作都是源于注册表的。 可以使用 regedit.exe 这个系统提供的注册表编辑器去管理编辑注册表,他只是一个编辑器不是注册表的文件。
如上图所示,注册表预设有五个根键:
HKEY_CLASSES_ROOT HKEY_CURRENT_USER HKEY_LOCAL_MACHINE HKEY_USER HKEY_CURRENT_CONFIG
根键展开后可以看到跟键的子健(子项):像 "System, Software等都是HKEY_CURRENT_CONFIG的子健(子项)。 就像文件夹一样,每个键都可以创建子项,同时也可以拥有键值项。 键值项由3部分组成:名称、类型、值。
HKEY_LOCAL_MACHINE 根键中包含了操作系统、安装软件及硬件的相关信息。如计算机总线类型、系统可用内存、当前装载了哪些设备驱动程序以及启动控制数据等。 实际上,HKEY_LOCAL_MACHINE 根键保存着注册表中的大部分信息,而另外4个根键都是其子键的别名。
HKEY_CURRENT_USER 根键包含这当前登录到计算机上的用户的配置文件。其子键包含着环境变量、个人程序组、桌面设置、网络连接、打印机和应用程序首选项等信息。 计算机把当前用户的信息映射到这个根键下,若未激活用户配置,则它指向子键 HKEY_USERS.DEFAULT。
HKEY_CLASSES_ROOT 根键记录的是系统中各类文件与其应用程序之间的对应关系,即记录了某类文件和打开该类文件的应用程序之间的相互关联关系。 HKEY_CLASSES_ROOT 根键是 HKEY_LOCAL_MACHINE\SOFTWARE\Classes 的快捷方式,是注册表的一个最大分支,包括了成千上万的与程序、文件相关联的键和值以及ActiveX类的定义等内容。
HKEY_USERS 根键下包含了计算机的所有用户的信息。用户根据个人爱好设置的诸如桌面、背景、开始菜单程序项、应用程序快捷键、显示字体、屏幕节电设置等信息均记录在这个跟建中 HKEY_CURRENT_USER 也是 HKEY_USERS 其中的的一个快捷键部分。
HKEY_CURRENT_CONFIG 根键包含的主要内容是计算机的当前配置情况,如显示器、打印机等可选外部设备及其设置信息等。
MSDN: RegCreateKeyExA function (winreg.h) 功能:创建或打开注册表键。 函数原型:
LONG RegCreateKeyEx( HKEY hKey, // 已打开的键的句柄 (RegOpenKeyEx, RegCreateKeyEx 的返回值) 或者 预定义的值( 即根键)。 LPCTSTR lpSubKey, // 指向 要创建或要打开的子健名称。 DWORD Reserved, // 保留值必须为 0, LPTSTR lpClass, // 字符串指针,指向用户自定义的键类别名称。可以设为NULL。 DWORD dwOptions, // 新创建的键的属性。 REGSAM samDesired, // 键的访问权限。 LPSECURITY_ATTRIBUTES lpSecurityAttributes, // 指向 SECURITY_ATTRIBUTES 结构的指针,用于定义返回的句柄是否可以被子进程继承,为 NULL 表示不继承。 PHKEY phkResult, // 指向新创建或打开的键的句柄的指针,保存返回的句柄。 LPDWORD lpdwDisposition // 指明键是被创建还是被打开的 );参数: 【入参】hKey: 已经打开的注册表键的句柄。
可以是以下的值:
HKEY_CLASSES_ROOTHKEY_CURRENT_CONFIGHKEY_CURRENT_USERHKEY_LOCAL_MACHINEHKEY_USERSRegOpenKeyEx或RegCreateKeyEx 返回的phkResult【入参】dwOptions: 键的属性。
可以是以下的值:
REG_OPTION_NON_VOLATILE 新创建的键为一个非短暂性的键 (数据信息保存在文件中,当系统重新启动时,数据信息恢复)REG_OPTION_VOLATILE 新创建的键为一个短暂性的键(数据信息保存在内存中)。REG_OPTION_BACKUP_RESTORE 仅在WINNT中支持,可以提供优先级支持。【入参】samDesired: 键的访问权限。
KEY_ALL_ACCESS 包含所有权限。KEY_CREATE_LINK 系统保留。KEY_CREATE_SUB_KEY 允许创建子键。KEY_ENUMERATE_SUB_KEYS 允许枚举子健。KEY_EXECUTE 等同于KEY_READ。KEY_NOTIFY 允许提供更改通知(详见 RegNotifyChangeKeyValue)KEY_QUERY_VALUE 允许查询键值KEY_READ 读取权限,包括STANDARD_RIGHTS_READ, KEY_QUERY_VALUE, KEY_ENUMERATE_SUB_KEYS 和 KEY_NOTIFY 。KEY_SET_VALUE 创建、删除、设置键值。KEY_WOW64_32KEY 32位注册表/64位注册表路径重定向,设置后将访问32位注册表路径。KEY_WOW64_64KEY 32位注册表/64位注册表路径重定向,设置后将访问64位注册表路径。KEY_WRITE 写权限包括 STANDARD_RIGHTS_WRITE, KEY_SET_VALUE 和【出参】phkResult: 创建或打开的键的句柄。
【出参】lpdwDisposition: 指明键是被创建还是被打开的。 REG_CREATED_NEW_KEY 键先前不存在,现在被创建。 REG_OPENED_EXISTING_KEY 键先前已存在,现在被打开。
【返回值】如果函数调用成功,则返回 ERROR_SUCCESS。否则返回非零的错误代码。
MSDN:RegOpenKeyExA function (winreg.h) 功能:打开注册表键。 函数原型:
LSTATUS RegOpenKeyExA( HKEY hKey, //已打开的键的句柄或根键 LPCSTR lpSubKey, //子健相对路径 DWORD ulOptions, //一般设为0 ,也可以是REG_OPTION_OPEN_LINK表示该键为符号链接(未使用过,待测试) REGSAM samDesired,//访问需要的权限 PHKEY phkResult //返回的键句柄 );【返回值】如果函数调用成功,则返回 ERROR_SUCCESS。否则返回非零的错误代码。
MSDN: RegDeleteKeyExA function (winreg.h) 功能:删除注册表键。 函数原型:
LSTATUS RegDeleteKeyExA( HKEY hKey, //已打开的键的句柄或根键 LPCSTR lpSubKey, //子健相对路径 REGSAM samDesired, //访问32位路径还是64位注册表路径 使用KEY_WOW64_32KEY 或 KEY_WOW64_64KEY DWORD Reserved //保留,必须为0 );【返回值】如果函数调用成功,则返回 ERROR_SUCCESS。否则返回非零的错误代码。
MSDN:RegCloseKey function (winreg.h) 功能:关闭已经打开的注册表句柄。 函数原型:
LSTATUS RegCloseKey( HKEY hKey //已打开的键的句柄 );【返回值】如果函数调用成功,则返回 ERROR_SUCCESS。否则返回非零的错误代码。
MSDN:RegSetValueExA function (winreg.h) 功能:设置注册表的键值项。 函数原型:
LSTATUS RegSetValueExA( HKEY hKey, //已打开的键的句柄 LPCSTR lpValueName, //键值名称,如果为NULL或“”,则设置键值名为“默认”的项 DWORD Reserved, //保留,必须为0 DWORD dwType, //设置的键值数据类型 const BYTE *lpData, //指向键值数据的指针 DWORD cbData //设置的键值数据长度 );【入参】dwType:设置的键值数据类型 可以是以下值:
REG_BINARY 二进制数据REG_DWORD 32字节数据REG_DWORD_LITTLE_ENDIAN 小端的4字节数据(windows是基于小端处理器设计的,所以等同于REG_DWORD)REG_DWORD_BIG_ENDIAN 大端的4字节数据REG_EXPAND_SZ 可扩展的字符串,此类型的键值中存在的%xxx%的部分会被系统解释,而REG_SZ不会REG_LINK 指向符号链接的注册表项路径的字符串REG_MULTI_SZ 多个字符串,用\0分隔,例如:String1\0String2\0String3\0LastString\0\0REG_NONE 未定义的类型REG_QWORD 8字节数据REG_QWORD_LITTLE_ENDIAN 等同于REG_QWORDREG_SZ 字符串【返回值】如果函数调用成功,则返回 ERROR_SUCCESS。否则返回非零的错误代码。
MSDN: RegQueryValueExA function (winreg.h) 功能:根据名称获取对应注册表项的数据类型和数据。 (要确保返回的任何字符串值(REG_SZ、REG_MULTI_SZ和REG_EXPAND_SZ)都以null结尾,请使用RegGetValue函数。) 函数原型:
LSTATUS RegQueryValueExA( HKEY hKey, //已打开的键的句柄 LPCSTR lpValueName, //键值名称,如果为NULL或“”,则设置键值名为“默认”的项 LPDWORD lpReserved, //保留,必须为0 LPDWORD lpType, //【出参】,返回数据类型 LPBYTE lpData, //【出参】, 返回数据 LPDWORD lpcbData //【出参】, 返回数据长度 );【返回值】如果函数调用成功,则返回 ERROR_SUCCESS。否则返回非零的错误代码。
MSDN:RegGetValueA function (winreg.h) 功能:根据名称获取对应注册表项的数据类型和数据。 函数原型:
LSTATUS RegGetValueA( HKEY hkey, //已打开的键的句柄,一般是根键 LPCSTR lpSubKey, //hKey的子键路径 LPCSTR lpValue, //键值项名称 DWORD dwFlags, //对于返回键值类型的限制,如果不满足,函数会执行失败 LPDWORD pdwType, //【出参】 返回的数据类型 PVOID pvData, //【出参】, 返回数据 LPDWORD pcbData //【出参】, 返回数据长度 );【入参】 dwFlags:对于返回键值类型的限制,如果不满足,函数会执行失败。 可以是以下值或它们的组合(按位或|):
RRF_RT_ANY 无任何限制RRF_RT_DWORD 允许32位RRF_RT_REG_BINARY或RRF_RT_REG_DWORD类型RRF_RT_QWORD 允许64位RRF_RT_REG_BINARY或RRF_RT_REG_QWORD类型RRF_RT_REG_BINARY 仅允许REG_BINARY类型RRF_RT_REG_DWORD 仅允许REG_DWORD类型RRF_RT_REG_EXPAND_SZ 仅允许 REG_EXPAND_SZ类型RRF_RT_REG_MULTI_SZ 仅允许 REG_MULTI_SZ类型RRF_RT_REG_NONE 仅允许 REG_NONERRF_RT_REG_QWORD 仅允许 REG_QWORDRRF_RT_REG_SZ仅允许 REG_SZRRF_NOEXPAND 当数据类型为REG_EXPAND_SZ时,不自动展开环境变量字符串。RRF_ZEROONFAILURE 当pvData 不为NULL时,执行失败会把缓冲区全置为0。RRF_SUBKEY_WOW6464KEY 访问64位注册表路径。RRF_SUBKEY_WOW6432KEY 访问32位注册表路径。1.RegGetValue不需要打开注册表句柄(这个API自动会打开和关闭句柄)
2.RegGetValue可以限制键值的类型,如果注册表中的类型跟自己想要的类型(由dwFlags设置的)不符,函数会返回0x0000065E错误 :“这个类型的数据不受支持。 ” 。值得注意的是,即使此时返回值不是ERROR_SUCCESS ,pdwType 和pvData仍然会返回正确的数据。
3.RegQueryValueEx不保证查询的字符串已NULL结尾,而RegGetValue会进行检查。(经过个人测试,并未发现此类情况,RegQueryValueEx仍然需要包含\0结尾的大小的buffer才能执行成功。只不过当数据类型是REG_MULTI_SZ 时,RegQueryValueEx返回的数据结尾是\0,而RegGetValue返回的数据结尾是\0\0,环境: win7 64)。
MSDN:RegEnumKeyExA function (winreg.h) 功能:枚举子健名称。 函数原型:
LSTATUS RegEnumKeyExA( HKEY hKey, //已打开的键的句柄 DWORD dwIndex, //子健索引 LPSTR lpName, //【出参】子健名称 LPDWORD lpcchName, //【入参/出参】子健名称缓冲区大小/返回的子健名称长度 LPDWORD lpReserved, //保留,必须为0 LPSTR lpClass, //【出参】类名名称,如果不需要,可以传NULL LPDWORD lpcchClass, //【入参/出参】类名缓冲区大小/返回的类名长度 PFILETIME lpftLastWriteTime // FILETIME指针,返回子健最后的更改日期,可以创NULL );【返回值】如果函数调用成功,则返回 ERROR_SUCCESS,如果全部枚举完毕,返回ERROR_NO_MORE_ITEMS,其他情况返回非零的错误代码。
MSDN:RegEnumValueA function (winreg.h) 功能:枚举键值项。 函数原型:
LSTATUS RegEnumValueA( HKEY hKey, //已打开的键的句柄 DWORD dwIndex, //键值项索引 LPSTR lpValueName, //【出参】键值项名称 LPDWORD lpcchValueName, //【入参/出参】键值项名称缓冲区大小/返回的键值项名称长度 LPDWORD lpReserved, //保留,必须为0 LPDWORD lpType, //【出参】键值项的数据类型 LPBYTE lpData, //【出参】键值项数据 LPDWORD lpcbData //【入参/出参】数据长度 );【返回值】如果函数调用成功,则返回 ERROR_SUCCESS,如果全部枚举完毕,返回ERROR_NO_MORE_ITEMS,其他情况返回非零的错误代码。
未完待续。。。