RegEnumValue和REG_MULTI_SZ类型

时间:2013-05-15 10:55:28

标签: c winapi registry

MSDN说RegEnumValue得到的字符串数据

  

如果数据具有REG_SZ,REG_MULTI_SZ或REG_EXPAND_SZ类型,则   字符串可能没有与正确的空终止存储   字符。因此,即使函数返回ERROR_SUCCESS,也是如此   应用程序应确保字符串正确终止   在使用之前;否则,它可能会覆盖缓冲区。 (注意   REG_MULTI_SZ字符串应该有两个以空字符结尾的字符。)

假设一个值是REG_MULTI_SZ,这是否意味着序列中的每个字符串都可以或不能以空值终止,或者只是只有最后一个双空终止符可能不存在,但是所有内部空终止符都存在?

3 个答案:

答案 0 :(得分:2)

  

假设一个值是REG_MULTI_SZ,这是否意味着序列中的每个字符串都可以或不能以空值终止

序列中的字符串必须为空终止,否则将无法确定其中一个字符串结束和下一个字符串的开始位置。来自描述REG_MULTI_SZ的{​​{3}}:

A sequence of null-terminated strings, terminated by an empty string (\0).
The following is an example:

    String1\0String2\0String3\0LastString\0\0

The first \0 terminates the first string, the second to the last \0 terminates
the last string, and the final \0 terminates the sequence.
Note that the final terminator must be factored into the length of the string.

文档含糊不清但我的解释是最后的空终止符可能会丢失:

String1\0String2\0String3\0LastString

并且读取该值的代码必须确保它们随后用于后续字符串提取。

如果用于包含该值的缓冲区足够大,包括终止空字符的空间,只要代码确保存在尾随空值,就没有什么可担心的。

答案 1 :(得分:1)

你必须注意最后一个终结者。只需检查它是否存在。

答案 2 :(得分:1)

在处理C字符串的程序中,这是一个非常常见的错误,它们可以轻松地使用strlen()或wcslen()来测量字符串长度,并将其作为RegSetValueEx的 cbData 参数传递( )。忘记零终结者,那些一个一个一个的错误是猖獗的。 Windows并不关心,它只是写字节而不是试图解释字符串。

所以出现问题的是当你读取注册表值时,你将得到没有零终止符的字节。如果你再将它解释为一个C字符串,你将只有0.4%的几率你会看到实际的字符串,当你使用调试分配器时为零。你可以通过自己编写零终结符来避免它。如果它已经存在则无关紧要,以可能的缓冲区溢出为模,如果没有,则使用错误数据避免使用程序。