2011-07-27 4 views
1

응용 프로그램을 작성하려고합니다. HKLM \ hardware \ description \ system과 같은 레지스트리 경로를 지정할 수 있습니다. 응용 프로그램은 모든 키 이름을 시스템 아래에서 읽어야하며, 하위 키가있는 경우 더 이상 하위 키가 있고 그 이름도 마찬가지입니다 ...레지스트리에서 모든 키와 하위 키를 가져 오는 방법은 무엇입니까?

내 응용 프로그램이 작동하고 있지만 문제는 하위 키 수를 계산하는 것입니다. 예를 들어, 시스템 아래에 2 개의 키가 있고, a와 b가 있고, 아래에 3 개의 키가 있고, b 아래에 5가 더 있다면, 나는 하위 레벨을 어떻게 계산해야합니까? 레지스트리 경로를 연결하는 방법을 알아야하기 때문에 이것은 중요합니다. 여기

는 (그것의 대부분은 MSDN에서입니다,하지만 난 아무데도 비슷한 예를 찾을 수 없습니다) 지금까지 내 코드입니다 :

#include <windows.h> 
#include <stdio.h> 
#include <tchar.h> 
#include <conio.h> 

#define MAX_KEY_LENGTH 255 
#define MAX_VALUE_NAME 16383 

void test(wchar_t * OriginalCopy); 
void QueryKey(HKEY hKey, wchar_t * proba); 
void CutLastSubkey(wchar_t * SubKey, int howmuch); 

wchar_t OriginalLocation[] = L"hardware\\description\\system"; 
DWORD Level = 0; 
int counter = 0; 

void __cdecl _tmain(void) 
{ 
    wchar_t OriginalCopy[ 512 ]; 

wcscpy(OriginalCopy, OriginalLocation); 

test(OriginalCopy); 

} 

void test(wchar_t * OriginalCopy) 
{ 
    HKEY hTestKey; 

    if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, OriginalCopy, 0, KEY_READ, &hTestKey) == ERROR_SUCCESS) 
    { 
     //printf("\n%ls",OriginalCopy); 
     QueryKey(hTestKey, OriginalCopy); 
    } 
    else printf("\nTest Failed"); 
    RegCloseKey(hTestKey); 

} 

void QueryKey(HKEY hKey, wchar_t * OriginalCopy) 
{ 
printf("\n1. OriginalCopy: %ls Level %d", OriginalCopy, Level); 

TCHAR achKey[MAX_KEY_LENGTH]; // buffer for subkey name 
DWORD cbName;     // size of name string 
TCHAR achClass[MAX_PATH] = TEXT(""); // buffer for class name 
DWORD cchClassName = MAX_PATH; // size of class string 
DWORD cSubKeys=0;    // number of subkeys 
DWORD cbMaxSubKey;    // longest subkey size 
DWORD cchMaxClass;    // longest class string 
DWORD cValues;    // number of values for key 
DWORD cchMaxValue;   // longest value name 
DWORD cbMaxValueData;  // longest value data 
DWORD cbSecurityDescriptor; // size of security descriptor 
FILETIME ftLastWriteTime;  // last write time 

DWORD i, retCode; 

TCHAR achValue[MAX_VALUE_NAME]; 
DWORD cchValue = MAX_VALUE_NAME; 

// Get the class name and the value count. 
retCode = RegQueryInfoKey(
    hKey,     // key handle 
    achClass,    // buffer for class name 
    &cchClassName,   // size of class string 
    NULL,     // reserved 
    &cSubKeys,    // number of subkeys 
    &cbMaxSubKey,   // longest subkey size 
    &cchMaxClass,   // longest class string 
    &cValues,    // number of values for this key 
    &cchMaxValue,   // longest value name 
    &cbMaxValueData,   // longest value data 
    &cbSecurityDescriptor, // security descriptor 
    &ftLastWriteTime);  // last write time 

// Enumerate the subkeys, until RegEnumKeyEx fails. 

if (cSubKeys) 
{ 
    printf("\nNumber of subkeys: %d\n", cSubKeys); 

    for (i=0; i<cSubKeys; i++) 
    { 
     cbName = MAX_KEY_LENGTH; 
     retCode = RegEnumKeyExW(hKey, 
           i, 
           achKey, 
           &cbName, 
           NULL, 
           NULL, 
           NULL, 
           &ftLastWriteTime 
          ); 

     if (retCode == ERROR_SUCCESS) 
     { 
      //_tprintf(TEXT("(%d) %s\n"), i+1, achKey); 
      //------------------------------------------------------------------- 
      HKEY subkey; 

      Level++; 
      wcscat(OriginalCopy, L"\\"); 
      wcscat(OriginalCopy, achKey); 
      printf("\nNew subkey found \"%ls\" Number of subkeys: %d\n",achKey, cSubKeys); 
      printf("\nNew OriginalCopy \"%ls\"Level: %d\n", OriginalCopy, Level); 

      if(RegOpenKeyExW(HKEY_LOCAL_MACHINE, OriginalCopy, 0, KEY_READ, &subkey) == ERROR_SUCCESS) 
      {    
       counter++; 
       test(OriginalCopy); 
       RegCloseKey(subkey); 
      } 
      else printf("\n-----Querykey Failed for %ls\n",OriginalCopy); 


      //------------------------------------------------------------------- 
     } 
    } 
} 
else 
{ 
    Level--; 
    printf("\nNo subkeys \"%ls\" Level : %d Counter %d",OriginalCopy, Level, counter); 
    CutLastSubkey(OriginalCopy, 1); 

    //counter--; 
} 

// Enumerate the key values. 

/*if (cValues) 
{ 
    printf("\nNumber of values: %d\n", cValues); 

    for (i=0, retCode=ERROR_SUCCESS; i<cValues; i++) 
    { 
     cchValue = MAX_VALUE_NAME; 
     achValue[0] = '\0'; 
     retCode = RegEnumValue(hKey, 
           i, 
           achValue, 
           &cchValue, 
           NULL, 
           NULL, 
           NULL, 
           NULL 
          ); 

     if (retCode == ERROR_SUCCESS) 
     { 
      _tprintf(TEXT("(%d) %s\n"), i+1, achValue); 
     } 
    } 
}*/ 
} 

void CutLastSubkey(wchar_t * SubKey, int howmuch) 
{ 
wchar_t * pch, tmp[ 1024 ] = { 0 }; 
int location, i; 

printf("\n\nCutlast was called with %d", howmuch); 
pch = wcsrchr(SubKey,'\\');//last occurence of \ in string 
location = pch - SubKey + 1; 
//printf("Last occurence of '\\' found at %d in %ls \n",location, SubKey); 
location--; 

SubKey[ location ] = '\0'; 

printf("\n+++CutLastSubkey result :: \"%ls\"", SubKey); 
if (howmuch > 1) 
{ 
    CutLastSubkey(SubKey, Level -1); 
} 

}//CutLastSubkey 

답변

1

가장 먼저 할 일은 해당 전역을 제거하는 것입니다. 그들은 단지 물건을 복잡하게하고있다. 재귀를 사용하면 모든 것을 스택에 넣을 수 있습니다. 아래 코드는 문제를 해결합니다.

#include <windows.h> 
#include <stdio.h> 
#include <tchar.h> 
#include <conio.h> 

#define MAX_KEY_LENGTH 255 
#define MAX_VALUE_NAME 16383 

void test(wchar_t * OriginalCopy, DWORD Level); 
void QueryKey(HKEY hKey, const wchar_t * proba, DWORD Level); 


int counter = 0; 

void __cdecl _tmain(void) 
{ 

    test(L"hardware\\description\\system", 0); 

} 

void test(wchar_t * OriginalCopy, DWORD Level) 
{ 
    HKEY hTestKey; 

    if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, (LPCWSTR)OriginalCopy, 0, KEY_READ, &hTestKey) == ERROR_SUCCESS) 
    { 
     //printf("\n%ls",OriginalCopy); 
     QueryKey(hTestKey, OriginalCopy, Level); 
    } 
    else printf("\nTest Failed"); 
    RegCloseKey(hTestKey); 

} 

void QueryKey(HKEY hKey, const wchar_t * OriginalCopy, DWORD Level) 
{ 
    //printf("\n1. OriginalCopy: %ls Level %d", OriginalCopy, Level); 

    TCHAR achKey[MAX_KEY_LENGTH];  // buffer for subkey name 
    DWORD cbName;       // size of name string 
    TCHAR achClass[MAX_PATH] = TEXT(""); // buffer for class name 
    DWORD cchClassName = MAX_PATH; // size of class string 
    DWORD cSubKeys=0;      // number of subkeys 
    DWORD cbMaxSubKey;     // longest subkey size 
    DWORD cchMaxClass;     // longest class string 
    DWORD cValues;     // number of values for key 
    DWORD cchMaxValue;   // longest value name 
    DWORD cbMaxValueData;   // longest value data 
    DWORD cbSecurityDescriptor; // size of security descriptor 
    FILETIME ftLastWriteTime;  // last write time 

    DWORD i, retCode; 

    DWORD cchValue = MAX_VALUE_NAME; 

    // Get the class name and the value count. 
    retCode = RegQueryInfoKey(
            hKey,      // key handle 
            achClass,     // buffer for class name 
            &cchClassName,   // size of class string 
            NULL,      // reserved 
            &cSubKeys,     // number of subkeys 
            &cbMaxSubKey,    // longest subkey size 
            &cchMaxClass,    // longest class string 
            &cValues,     // number of values for this key 
            &cchMaxValue,    // longest value name 
            &cbMaxValueData,    // longest value data 
            &cbSecurityDescriptor, // security descriptor 
            &ftLastWriteTime);  // last write time 

    // Enumerate the subkeys, until RegEnumKeyEx fails. 

    if (cSubKeys) 
    { 
     //printf("\nNumber of subkeys: %d\n", cSubKeys); 

     for (i=0; i<cSubKeys; i++) 
     { 
      cbName = MAX_KEY_LENGTH; 
      retCode = RegEnumKeyExW(hKey, 
              i, 
              (LPWSTR)achKey, 
              &cbName, 
              NULL, 
              NULL, 
              NULL, 
              &ftLastWriteTime 
             ); 

      if (retCode == ERROR_SUCCESS) 
      { 
       //_tprintf(TEXT("(%d) %s\n"), i+1, achKey); 
       //------------------------------------------------------------------- 
       HKEY subkey; 

       wchar_t NewCopy[MAX_PATH]; 
       wcscpy(NewCopy, OriginalCopy); 
       wcscat(NewCopy, L"\\"); 
       wcscat(NewCopy, (const wchar_t *)achKey); 
       //printf("\nNew subkey found \"%ls\" Number of subkeys: %d\n",achKey, cSubKeys); 
       printf("\nNew OriginalCopy \"%ls\"Level: %d\n", NewCopy, Level); 

       if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, OriginalCopy, 0, KEY_READ, &subkey) == ERROR_SUCCESS) 
       { 
        counter++; 
        test(NewCopy, Level+1); 
        RegCloseKey(subkey); 
       } 
       else printf("\n-----Querykey Failed for %ls\n",OriginalCopy); 


       //------------------------------------------------------------------- 
      } 
     } 
    } 

    // Enumerate the key values. 

    /*if (cValues) 
    { 
     printf("\nNumber of values: %d\n", cValues); 

     for (i=0, retCode=ERROR_SUCCESS; i<cValues; i++) 
     { 
       cchValue = MAX_VALUE_NAME; 
       achValue[0] = '\0'; 
       retCode = RegEnumValue(hKey, 
               i, 
               achValue, 
               &cchValue, 
               NULL, 
               NULL, 
               NULL, 
               NULL 
              ); 

       if (retCode == ERROR_SUCCESS) 
       { 
        _tprintf(TEXT("(%d) %s\n"), i+1, achValue); 
       } 
     } 
    }*/ 
} 
+0

대단히 감사합니다! 이 코드는 매력처럼 작동합니다. 나는 내가 조금 더 배울 필요가 있다고 생각한다 :) – kampi

1

이 고전 트리 탐색 문제이며, 당신이 있기 때문에하지 하위 키가 얼마나 깊은 지 알면 솔루션은 재귀입니다. 레지스트리 키와 수준을 입력으로 받아들이는 함수를 디자인하십시오. 해당 키의 하위 키를 열거하고 발견 한 각 하위 키에 대해 해당 하위 키와 수준 +1을 매개 변수로 호출합니다.

재귀는 당신의 마음을 감싸는 어려운 개념이지만 일단 그렇게하면 우아함은 이와 같은 문제에서 아름다움의 한 가지입니다.

+0

안녕하세요! 나는 그것을 안다 : 나는 단지 이것을하는 방법을 모른다. 내 코드를 볼 경우 재귀를 사용하고 있지만 잘못된 것으로 생각됩니다. 레벨을 어떻게해야합니까? 어쩌면 예제 코드를 제공 할 수 있을까요? – kampi

+0

죄송합니다. 코드를 너무 빨리 건너 뜁니다. 내 잘못이야. –

관련 문제