为什么获得MachineGuid看起来不像GUID但是像韩国人一样?

时间:2014-02-25 16:29:24

标签: c++ windows visual-studio-2010 winapi formatting

我创建了一个简单的函数:

std::wstring GetRegKey(const std::string& location, const std::string& name){
    const int valueLength = 10240;

    auto platformFlag = KEY_WOW64_64KEY;
    HKEY key;
    TCHAR value[valueLength];
    DWORD bufLen = valueLength*sizeof(TCHAR);
    long ret;
    ret = RegOpenKeyExA(HKEY_LOCAL_MACHINE, location.c_str(), 0, KEY_READ | platformFlag, &key);
    if( ret != ERROR_SUCCESS ){
        return std::wstring();
    }
    ret = RegQueryValueExA(key, name.c_str(), NULL, NULL, (LPBYTE) value, &bufLen);
    RegCloseKey(key);
    if ( (ret != ERROR_SUCCESS) || (bufLen > valueLength*sizeof(TCHAR)) ){
        return std::wstring();
    }
   std::wstring stringValue(value, (size_t)bufLen - 1);
    size_t i = stringValue.length();
    while( i > 0 && stringValue[i-1] == '\0' ){
        --i;
    }
    return stringValue;
}

我称之为自动result = GetRegKey("SOFTWARE\\Microsoft\\Cryptography", "MachineGuid");

但字符串看起来像

㤴ㄷ㤵戰㌭㉣ⴱ㔴㍥㤭慣ⴹ㍥摢㘵〴㉡ㄵ\0009ca9-e3bd5640a251

不喜欢RegEdit

4971590b-3c21-45e3-9ca9-e3bd5640a251

所以我想知道如何在C ++中正确表达MachineGuid?

1 个答案:

答案 0 :(得分:2)

RegQueryValueExA是自Windows NT以来Unicode版本的ANSI包装器。在基于Unicode版本的Windows上构建时,它不仅会将lpValueName转换为LPCWSTR,还会将从注册表中检索到的lpData转换为LPWSTR在回来之前。

MSDN有以下说法:

  

如果数据具有REG_SZ,REG_MULTI_SZ或REG_EXPAND_SZ类型,则   使用此函数的ANSI版本(通过显式   调用RegQueryValueExA或在包含之前不定义UNICODE   在Windows.h文件中),此函数转换存储的Unicode字符串   在将其复制到指向的缓冲区之前的ANSI字符串   的lpData。

您的问题是,您使用ANSI字符串填充lpData,其中包含TCHAR s(在Unicode版本的Windows上为WCHAR)。

您看到的乱码字符串是2 ANSI char用于填充单个wchar_t的结果。这解释了亚洲人物。看起来像GUID结尾的部分是因为打印函数超过了终止null,因为它只有一个字节并开始打印RegQueryValueExA所使用的缓冲区的一部分。在转换为ANSI之前。

要解决此问题,要么完全坚持使用Unicode,要么坚持使用ANSI(如果您足够勇于在2014年继续使用ANSI),或者对转换非常谨慎。我会将GetRegKey更改为接受wstring并改为使用RegQueryValueExW,但这是一个偏好问题以及您计划使用此代码的代码类型。

(另外,我建议你有人审查这段代码,因为错误检查有很多奇怪的地方,还有硬编码的缓冲区大小。)