2010-03-21 5 views
1

RunAs 명령처럼 작동해야하는 .dll을 만들었습니다. 유일한 차이점은 레지스트리에서 읽어야한다는 것입니다. 내 문제는, 내가 레지스트리에서 3 값을 리드해야하지만, 내가 할 수 없다는 것입니다. "시스템이 지정된 파일을 찾을 수 없습니다"라는 오류 코드 2가있는 두 번째 암호 (암호)에서 실패하는 것보다 먼저 읽습니다. 만약 내가 도메인과 사용자 이름에 대한 쿼리를 누른 다음 괜찮아요, 나는 단지 암호를 다음 쿼리를 여전히 성공,하지만 만약 내가 모든 세 쿼리를 실패하려면 그럼. 누군가 내가 잘못하고있는 것을 말해 줄 수 있습니까? Heres는C에서 여러 값에 대해 레지스트리를 올바르게 읽는 방법?

내 코드 :

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

답변

1

나는 왜 볼 수 있다고 생각합니다. RegQueryValueEx를 ​​호출하기 전에 매번 dwBufSize를 초기화해야합니다. 이 함수는 buf에 복사 된 바이트 수를 반환합니다.

이 함수는 ERROR_MORE_DATA를 반환합니다. GetLastError()를 사용하여 실수를 범했습니다. 그러지 마. Reg 함수는 오류 코드를 직접 반환합니다.

+0

안녕하세요! 고맙습니다. 이것은 내 문제였다. 각 쿼리 전에 dwBufSize를 초기화하는 것이 필요했습니다. 대단히 감사합니다. – kampi

4

이 직접 당신에 대해 요구하고있는 문제에 관련되지 않지만, 그 문제를 진단위한 첫 번째 단계에서 중복의 일부를 제거하는 생각 당신의 코드. 지금은 모든 쿼리가 동일한 방식으로 작동한다는 것을 확신하는 것은 거의 불가능합니다. 프로그래밍 편집자가 명령을 잘라내거나 (특히) 붙여 넣지 않은 경우에 더 좋은 이유에 대한 좋은 예입니다. 나는 더 같은 코드로 시작하는 거라고 생각 :

#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 

내가 내 레지스트리에 다른 경로/항목의 번호와이 시도했습니다, 그리고 당신에 대해 물어 문제를 복제 할 수 없었다. 그 코드가 더 잘 작동하는지 여부는 확실하지 않습니다. 특정 소프트웨어를 설치하지 않았으므로 내가 본 레지스트리 항목이 없습니다.

+0

@ 제리 : 도와 주셔서 대단히 감사합니다. 나는 당신의 코드도 시도해 보았지만 완벽하게 작동하지만,이 경우 전체 코드를 재 작성하는 것보다 코드에 두 줄을 넣는 것이 더 쉬웠다. 불행히도, 나는 단지 하나의 솔루션을 받아 들일 수 있으므로 이번에는 부자가되지만, 다시 한번 감사드립니다. :) – kampi

관련 문제