2013-07-30 1 views
1

RegQueryValueEx을 사용할 때 이상한 결과가 발생하며 그 이유를 알 수 없습니다. Windows RegQueryValueEx 홀수 반환 결과

내가

LONG ret = RegQueryValueEx(hKey, dataKey, NULL, NULL, (LPBYTE)data, &dataSize); 

ret 234 (ERROR_MORE_DATA)

동일 호출 RegQueryValueEx

DWORD dataSize; 
TCHAR data[256]; 

처음하기 전에 설정 한 것입니다 그러나 나는 호출 할 때 다음 줄에 똑같은 것

LONG ret2 = RegQueryValueEx(hKey, dataKey, NULL, NULL, (LPBYTE)data, &dataSize); 

ret2 왜이 함수의 반환 ERROR_MORE_DATA 내가 전화를 처음으로 후 바로 다음 줄에 같은 통화 ERROR_SUCESS을 반환 0 (ERROR_SUCCESS)

같다?

TCHAR data[1024]을 변경하려고 시도했지만 동일한 결과가 나타납니다. 어떤 아이디어?

전체 코드는 :

for(int i=0; i<NUM_HISTORY; i++){ 
    CString dataKey = getDataKey(i); 

    DWORD dataSize = 1024; 
    TCHAR data[1024]; 

    LONG ret = RegQueryValueEx(hKey, dataKey, NULL, NULL, (LPBYTE)data, &dataSize); 
    LONG ret2 = RegQueryValueEx(hKey, dataKey, NULL, NULL, (LPBYTE)data, &dataSize); 

    // Breakpoint to see what ret and ret2 are equal to 
    int j = 0; 
} 

답변

0

이것은 의도적으로 설계된 동작입니다. 크기가 너무 작아서 첫 번째 호출이 실패했습니다. 그러나 당신이 기대하지 않은 것은 이 당신의 dataSize 변수를 업데이트 한 것입니다. 할당 할 메모리 양을 알려주기 위해 호출이 성공할 수 있습니다. 당신은 지금 올바른 정확히을의 크기를 지정하기 때문에

그래서 두 번째 호출은 성공했다. 그러나 다른 작업을 수행하지 않고 실제로 버퍼를 더 크게 만듭니다. 호출이 버퍼 오버 플로우를 일으키고 스택 프레임을 손상 시키면/RTC 컴파일 옵션을 사용해야하므로 런타임 오류가 발생합니다.

버퍼 크기를 256에서 1024로 늘리면이 문제를 피할 수 있습니다. 그러나 코드가 인 경우에도이 올바르지 않으면 레지스트리 값이 1024 바이트보다 커지면 프로그램이 비참하게 실패합니다. 로컬 배열을 사용하지 마십시오. 새로운 연산자 또는 malloc()을 사용하여 버퍼를 할당하십시오. 이렇게하면 결코 실패 할 수 없습니다. 또는 단순히 전화를 끊고 "불량 데이터"를 선언하십시오.

또 다른 버그에 유의하십시오. 데이터 크기는 바이트이지만 버퍼는 바이트가 아니라 TCHAR입니다. 아마도 스택 프레임을 손상시키지 않은 것일 수 있습니다. 버퍼가 우연히 충분히 커졌습니다. 이런 사고에 의지하고 싶지는 않습니다. 이런 종류의 실수를 피하기 위해 CRegKey와 같은 도우미 클래스를 고려하십시오.

+0

고맙습니다. 적어도 버퍼 오버플로 문제는 해결했습니다. 지금은'RegQueryValueEx'를 처음 호출하여'dataSize'에 올바른 크기를 얻고, _new_ 연산자를 사용하여'TCHAR' 버퍼에'dataSize' 크기를 할당합니다. 'dataSize'가 바이트 단위이고 버퍼가 바이트가 아니라'TCHAR'라고 명시하고 있기 때문에 이것은 여전히 ​​버그입니까? –

+0

예. malloc()을 사용하여 문제를 해결할 수 있습니다. –