簡體   English   中英

如何正確讀取注冊表中C中的多個值?

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

我創建了一個.dll,其運行方式應類似於RunAs命令。 唯一的區別是,它應該從注冊表中讀取。 我的問題是,我需要從注冊表中獲取3個值,但我不能。 它讀取第一個,然后在第二個失敗(密碼)時失敗,錯誤代碼為2,表示“系統找不到指定的文件”。 如果我僅查詢域和用戶名,則可以,如果我僅查詢密碼,則它仍然成功,但是如果我要查詢所有三個,則失敗。 有人可以告訴我,我做錯了嗎?

這是我的代碼:

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;
}

盡管它與您要問的問題沒有直接關系,但我認為診斷問題的第一步是消除代碼中的某些重復項。 現在,幾乎不可能確保所有查詢甚至都以相同的方式工作。 一個很好的例子,說明如果編程編輯器根本不剪切或(尤其是)粘貼命令,為什么會更好。 我想我將從以下代碼開始:

#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

我在注冊表中嘗試了許多不同的路徑/項目,但無法復制您所問的問題。 我不確定這是否意味着代碼可以更好地工作-我沒有您正在查看的注冊表項,因為我沒有安裝該軟件。

我想我能明白為什么。 每次調用RegQueryValueEx之前,都需要初始化dwBufSize。 此函數返回復制到buf的字節數。

您會發現該函數返回ERROR_MORE_DATA。 您已經犯了使用GetLastError()的錯誤。 不要那樣做 Reg函數直接返回錯誤代碼。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM