2010-03-21 6 views
1

J'ai créé un .dll qui devrait fonctionner comme la commande RunAs. La seule différence est, qu'il devrait lire du registre. Mon problème est, que j'ai besoin de reed 3 valeurs du registre, mais je ne peux pas. Il lit le premier, qu'il échoue à la seconde (Mot de passe) avec le code d'erreur 2, ce qui signifie "Le système ne peut pas trouver le fichier spécifié". Si je demande seulement pour le domaine et le nom d'utilisateur alors c'est correct, si je demande seulement pour le mot de passe alors cela réussit toujours, mais si je veux interroger tous les trois alors il échoue. Quelqu'un peut-il me dire, ce que je fais mal?Comment lire correctement le registre pour plusieurs valeurs dans c?

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

Répondre

1

Je pense que je peux voir pourquoi. Vous devez initialiser dwBufSize chaque fois avant d'appeler RegQueryValueEx. Cette fonction renvoie le nombre d'octets copiés dans buf.

Vous trouverez la fonction renvoie ERROR_MORE_DATA. Vous avez fait l'erreur d'utiliser GetLastError(). Ne fais pas ça. Les fonctions Reg renvoient un code d'erreur directement.

+0

Salut! Merci beaucoup. C'était mon problème. J'avais juste besoin d'initialiser dwBufSize avant chaque requête. Merci beaucoup – kampi

4

Bien qu'il ne se rapporte pas directement au problème que vous vous posez au sujet, je pense que la première étape vers le diagnostic du problème est de se débarrasser de certains des doubles emplois dans votre code. À l'heure actuelle, il est presque impossible de s'assurer que toutes les requêtes fonctionnent de la même manière. Un bon exemple de pourquoi il serait probablement mieux si les éditeurs de programmation n'ont pas coupé ou (en particulier) les commandes de collage du tout. Je pense que je commencerais avec le code plus comme ceci:

#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 

J'ai essayé cela avec un certain nombre de chemins/articles dans mon registre, et n'ont pas été en mesure de reproduire le problème que vous posez des questions sur. Je ne suis pas sûr si cela signifie que le code fonctionne mieux ou pas bien - je n'ai pas les mêmes entrées de registre que vous regardez puisque je n'ai pas ce logiciel particulier installé.

+0

@Jerry: Merci beaucoup pour votre aide. J'ai aussi essayé votre code, et cela fonctionne parfaitement, mais dans ce cas, il était plus facile de mettre deux lignes dans mon code que de réécrire le tout. Malheureusement, je ne peux accepter qu'une seule solution alors cette fois ça va pour riche, mais merci encore :) – kampi

Questions connexes