简体   繁体   English

如何正确读取注册表中C中的多个值?

[英]How to read registry correctly for multiple values in c?

I created a .dll which should work like the RunAs command. 我创建了一个.dll,其运行方式应类似于RunAs命令。 The only difference is, that it should read from registry. 唯一的区别是,它应该从注册表中读取。 My problem is, that i need to reed 3 values from the registry, but i can't. 我的问题是,我需要从注册表中获取3个值,但我不能。 It reads the first, than it fails at the second one (Password) with error code 2, which means "The system cannot find the file specified". 它读取第一个,然后在第二个失败(密码)时失败,错误代码为2,表示“系统找不到指定的文件”。 If i query only for domain and username then it is ok, if i query only for password then it it still succeeds, but if i want to query all three then it fails. 如果我仅查询域和用户名,则可以,如果我仅查询密码,则它仍然成功,但是如果我要查询所有三个,则失败。 Can someone tell me, what i am doing wrong? 有人可以告诉我,我做错了吗?

Heres my code: 这是我的代码:

HKEY hKey = 0;
DWORD dwType = REG_SZ;    
DWORD dwBufSize = sizeof(buf);
TCHAR szMsg [MAX_PATH + 32]; 
HANDLE handle;
LPVOID lpMsgBuf;

if( RegOpenKeyEx( HKEY_CURRENT_USER, TEXT("SOFTWARE\\Kampi Corporation\\RunAs!"), 0, KEY_QUERY_VALUE, &hKey ) == ERROR_SUCCESS )    
{
    if( RegQueryValueEx( hKey, TEXT("Username"), 0, &dwType, (LPBYTE)buf, &dwBufSize ) == ERROR_SUCCESS )        
    {
        memset( szMsg, 0, sizeof( szMsg ) );
        wsprintf ( szMsg, _T("%s"), buf );
        mbstowcs( wuser, szMsg, 255 );
        RegCloseKey( hKey );
    }        
    else
    {
        MessageBox ( pCmdInfo->hwnd, "Can not query for Username key value!", _T("RunAs!"), MB_ICONERROR );
        RegCloseKey( hKey );
        return -1;
    }
}
else
{
    CSimpleShlExt::showerror( GetLastError(), pCmdInfo->hwnd, "RegOpenKeyEx failed for Username with error code :: " );
    return -1;
}

if( RegOpenKeyEx( HKEY_CURRENT_USER, TEXT("SOFTWARE\\Kampi Corporation\\RunAs!"), 0, KEY_QUERY_VALUE ,&hKey ) == ERROR_SUCCESS )    
{
    if( RegQueryValueEx( hKey, TEXT("Password"), 0, &dwType, (LPBYTE)buf, &dwBufSize ) == ERROR_SUCCESS )        
    {
        memset( szMsg, 0, sizeof( szMsg ) );
        wsprintf ( szMsg, _T("%s"), buf );
        mbstowcs( wpass, szMsg, 255 );
        RegCloseKey( hKey );
    }        
    else
    {
        char test[200];
        sprintf(test,"Can not query for Password key value! EC: %d",GetLastError() );
        MessageBox ( pCmdInfo->hwnd, test, _T("RunAs!"), MB_ICONERROR );
        RegCloseKey( hKey );
        return -1;
    }
}
else
{
    CSimpleShlExt::showerror( GetLastError(), pCmdInfo->hwnd, "RegOpenKeyEx failed for Password with error code :: " );
    return -1;
}

if( RegOpenKeyEx( HKEY_CURRENT_USER, TEXT("SOFTWARE\\Kampi Corporation\\RunAs!"), 0, KEY_QUERY_VALUE ,&hKey ) == ERROR_SUCCESS )    
{
    if( RegQueryValueEx( hKey, TEXT("Domain"), 0, &dwType, (LPBYTE)buf, &dwBufSize ) == ERROR_SUCCESS )        
    {
        memset( szMsg, 0, sizeof( szMsg ) );
        wsprintf ( szMsg, _T("%s"), buf );
        mbstowcs( wdomain, szMsg, 255 );
        RegCloseKey( hKey );
    }        
    else
    {
        sprintf(test,"Can not query for Password key value! EC: %d",GetLastError() );
        MessageBox ( pCmdInfo->hwnd, test, _T("RunAs!"), MB_ICONERROR );
        RegCloseKey( hKey );
        return -1;
    }
}
else
{
    CSimpleShlExt::showerror( GetLastError(), pCmdInfo->hwnd, "RegOpenKeyEx failed for Domain with error code :: " );
    return -1;
}

Though it doesn't directly relate to the problem you're asking about, I think the first step toward diagnosing the problem is to get rid of some of the duplication in your code. 尽管它与您要问的问题没有直接关系,但我认为诊断问题的第一步是消除代码中的某些重复项。 Right now, it's almost impossible to be sure that all the queries even work the same way. 现在,几乎不可能确保所有查询甚至都以相同的方式工作。 A good example of why it would probably be better if programming editors didn't have cut or (particularly) paste commands at all. 一个很好的例子,说明如果编程编辑器根本不剪切或(尤其是)粘贴命令,为什么会更好。 I think I'd start with code more like this: 我想我将从以下代码开始:

#include <windows.h>
#include <string>
#include <sstream>
#include <iostream>
#include <exception>
#include <iterator>

namespace { 
void check(DWORD value, char const *op) { 
    if (value != ERROR_SUCCESS) {
        std::ostringstream buf;
        buf << op << " failed error code = " << value;
        throw std::logic_error(buf.str().c_str());
    }
}

class reg_key { 
    HKEY key;
public:
    reg_key(wchar_t const *path, HKEY topkey = HKEY_CURRENT_USER, DWORD q=KEY_QUERY_VALUE) {
        check(RegOpenKeyExW(topkey, path, 0, q, &key), "RegOpenKeyExW");
    }
    operator HKEY() { return key; }
    ~reg_key() { RegCloseKey(key); }
};
}

template <class outIt>
void read_reg(wchar_t const *path, wchar_t const *name, outIt out) { 
    static const int buf_size = 256;
    wchar_t buffer[buf_size];
    DWORD size = buf_size, type = REG_SZ;
    reg_key key(path);

    check(RegQueryValueExW(key, name, 0, &type, (LPBYTE)buffer, &size), "RegQueryValueExW");
    std::copy(buffer, buffer+wcslen(buffer), out);  
}

#ifdef TEST
int main() {
    std::wstring code_page, font;

    try { 
        read_reg(L"Software\\Microsoft\\CharMap", L"CodePage", std::back_inserter(code_page));
        read_reg(L"Software\\Microsoft\\CharMap", L"Font", std::back_inserter(font));
        std::wcout << "Code Page: " << code_page << "\n";
        std::wcout << "Font: " << font << std::endl;
    }
    catch (std::exception &e) { 
        MessageBox(NULL, e.what(), "Reading Registry failed", MB_ICONERROR);
    }
    return 0;
}
#endif

I've tried this with a number of different paths/items in my registry, and haven't been able to duplicate the problem you ask about. 我在注册表中尝试了许多不同的路径/项目,但无法复制您所问的问题。 I'm not sure whether that means the code works better or not though -- I don't have the same registry entries you're looking at since I don't have that particular software installed. 我不确定这是否意味着代码可以更好地工作-我没有您正在查看的注册表项,因为我没有安装该软件。

I think I can see why. 我想我能明白为什么。 You need to initialize dwBufSize each time before you call RegQueryValueEx. 每次调用RegQueryValueEx之前,都需要初始化dwBufSize。 This function returns the number bytes copied to buf. 此函数返回复制到buf的字节数。

You will find the function returns ERROR_MORE_DATA. 您会发现该函数返回ERROR_MORE_DATA。 You've made the mistake of using GetLastError(). 您已经犯了使用GetLastError()的错误。 Don't do that. 不要那样做 The Reg functions return an error code directly. Reg函数直接返回错误代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM