2011-07-26 6 views
3

特定のキーが与えられたすべてのサブキーと値を返すWindowsアプリケーションを作成しようとしています。私は指定されたキーの中にサブキーを提供する限り動作するように見えるコードを書いたが、値を適切に列挙することはできない。値を持たないサブキーを正常に列挙し、結果をタブ付きツリー配置の種類で返します。しかし、値を列挙するとき、プログラムは存在する各値(毎回同じランダム値)のランダムな値を返し、その後デバッグエラーでクラッシュします。その上Windowsレジストリキーのすべてのサブキーと値を列挙する

(1) KEY 
    (1) SUBKEY 
    (1) SUBKEYWITHINSUBKEY 
     Code: value1data 
     Code: value2data 
     Code: value3data 
(2) SUBKEY 
    (1) SUBKEYWITHINSUBKEY 
(3) SUBKEY 

...と:

それは意図の出力は基本的にあります。

私が代わりに取得した出力のようなものです:

(1) KEY 
(1) SUBKEY 
    (1) SUBKEYWITHINSUBKEY 
     Code: someValue 
     Code: someValue 
     Code: someValue 

(...そしてクラッシュ)。これは、次のエラーで続いている

:「!デバッグエラー」
ランタイムエラー番号2のチェック - 変数valNameLenのスタックが壊れていました。 "

現在、コードはちょっと乱雑です(私はWindows API初心者ですが)とにかく私のコーディングスタイルを批判する人は、それがぴったりだと感じる、それは素晴らしいだろう。

ありがとうございます!

-R

/* 
Windows Registry Subkey Enumeration Example 
Based on example found at code-blue.org 
*/ 

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

void EnumerateValues(HKEY hKey, DWORD numValues) 
{ 
DWORD dwIndex = 0; 
    LPSTR valueName = new CHAR[64]; 
DWORD valNameLen; 
DWORD dataType; 
DWORD data; 
DWORD dataSize; 

    for (int i = 0; i < numValues; i++) 
{ 
    RegEnumValue(hKey, 
    dwIndex, 
    valueName, 
    &valNameLen, 
    NULL, 
    &dataType, 
    (BYTE*)&data, 
    &dataSize); 

    dwIndex++; 

     printf("Code: 0x%08X\n", data); 
} 
} 


void EnumerateSubKeys(HKEY RootKey, char* subKey, unsigned int tabs = 0) 
{ 
HKEY hKey; 
    DWORD cSubKeys;  //Used to store the number of Subkeys 
    DWORD maxSubkeyLen; //Longest Subkey name length 
    DWORD cValues;  //Used to store the number of Subkeys 
    DWORD maxValueLen; //Longest Subkey name length 
    DWORD retCode;  //Return values of calls 

RegOpenKeyEx(RootKey, subKey, 0, KEY_ALL_ACCESS, &hKey); 

    RegQueryInfoKey(hKey,   // key handle 
        NULL,   // buffer for class name 
        NULL,   // size of class string 
        NULL,   // reserved 
        &cSubKeys,  // number of subkeys 
        &maxSubkeyLen, // longest subkey length 
        NULL,   // longest class string 
        &cValues,  // number of values for this key 
        &maxValueLen, // longest value name 
        NULL,   // longest value data 
        NULL,   // security descriptor 
        NULL);   // last write time 

    if(cSubKeys>0) 
{ 
     char currentSubkey[MAX_PATH]; 

     for(int i=0;i < cSubKeys;i++){ 
    DWORD currentSubLen=MAX_PATH; 

      retCode=RegEnumKeyEx(hKey, // Handle to an open/predefined key 
      i,    // Index of the subkey to retrieve. 
      currentSubkey,   // buffer to receives the name of the subkey 
      &currentSubLen,   // size of that buffer 
      NULL,    // Reserved 
      NULL,    // buffer for class string 
      NULL,    // size of that buffer 
      NULL);    // last write time 

      if(retCode==ERROR_SUCCESS) 
    { 
       for (int i = 0; i < tabs; i++) 
        printf("\t"); 
       printf("(%d) %s\n", i+1, currentSubkey); 

       char* subKeyPath = new char[currentSubLen + strlen(subKey)]; 
       sprintf(subKeyPath, "%s\\%s", subKey, currentSubkey); 
    EnumerateSubKeys(RootKey, subKeyPath, (tabs + 1)); 
    } 
    } 
} 
    else 
{ 
    EnumerateValues(hKey, cValues); 
} 

RegCloseKey(hKey); 
} 


int main() 
{ 
    EnumerateSubKeys(HKEY_CURRENT_USER,"SOFTWARE\\MyKeyToSearchIn"); 
    return 0; 
} 

答えて

2

キーをこのように列挙が過剰です。これは、単にシステムリソース、メモリ、コールスタックを浪費し、レジストリサブシステムに圧力をかけます。必要がない限りはしないでください。

アプリケーションに「検索レジストリ」がありますか?はいの場合は、ユーザーが要求した場合にのみ列挙します。または、「レジストリビューア/エディタ」を開発する場合は、必要なときにのみサブキーを展開して開きます。

キー/値をすべて取得して保存する必要がある場合は、複数のスレッドを使用してキーを列挙できます。スレッドの数は当初はHKEY-major-keysでしたが、キーを列挙している間に実行するサブキーとランタイムヒューリスティックの数に応じて、スレッド数を増やすことができます。

サブキーの「再帰的列挙」には再帰が適しているかもしれません。再帰的実装の最小限の引数を保持する必要があります。引数をstructに入れたり、クラスに入れてください。同じものにstd::stackを使用することもできます。

+0

私はコードを一から書き直して、必要なものすべてを実行します。アルゴリズムは大丈夫だと思います。ユーティリティの全体的なポイントは、この情報やその他のものを取得することです。私が検索するキーは特定であり、多くのサブキーや値が含まれていません。ポインタをありがとう! – 8bitcartridge

1

あなたが適切な値にlpcchValueNameパラメータを設定せずRegEnumValue()を呼び出していることが表示されます。このパラメータは[in]パラメータと[out]パラメータです。これを試してみてください:

for (int i = 0; i < numValues; i++) 
 { 
    DWORD valNameLen = 64; //added this line to match valueName buffer size 
  RegEnumValue(hKey, 
     dwIndex, 
     valueName, 
     &valNameLen, 
     NULL, 
     &dataType, 
     (BYTE*)&data, 
     &dataSize); 

RegEnumValueのドキュメント():http://msdn.microsoft.com/en-us/library/ms724865(v=vs.85).aspx

関連する問題