RegQueryInfoKey - баг в API ?

Тема в разделе "WASM.WIN32", создана пользователем tomeks, 18 янв 2006.

  1. tomeks

    tomeks New Member

    Публикаций:
    0
    Регистрация:
    18 янв 2006
    Сообщения:
    2
    Чтобы не быть голословным, приведу код.


    Код (Text):
    1.  
    2. void RegGo(HKEY hKey, LPTSTR szFullKey,LPTSTR szSubKey){
    3.    LONG res;
    4.    TCHAR szFullName[260];
    5.    TCHAR *szSubKName,*szValueName,*szValue;
    6.    DWORD cName;
    7.    HKEY hSubKey;
    8.    DWORD dwcSubKeys,dwcValues,dwcMaxValueNameLen,dwcMaxValueLen,dwcMaxKeyLen;
    9.    int i;
    10.    DWORD dwType;
    11.    res=RegOpenKeyEx(hKey,szSubKey,0,KEY_READ,&hSubKey);
    12.    char szTest[10];
    13.    if (res==5 || res==2 || hSubKey==NULL) return;
    14.    res=RegQueryInfoKey(hSubKey,NULL,NULL,NULL,&dwcSubKeys,&dwcMaxKeyLen,NULL,
    15.                        &dwcValues,&dwcMaxValueNameLen,&dwcMaxValueLen,NULL,NULL);
    16.    szSubKName=(TCHAR*)malloc(dwcMaxKeyLen+1);
    17.  
    18.    for (i=0;i<dwcSubKeys;i++){
    19.      cName=dwcMaxKeyLen+1;
    20.      res=RegEnumKeyEx(hSubKey,i,szSubKName,&cName,NULL,NULL,NULL,NULL);
    21.      _stprintf(szFullName,_T("%s\\%s"),szFullKey,szSubKName);
    22.      RegGo(hSubKey,szFullName,szSubKName);
    23.    }
    24.    RegCloseKey(hSubKey);      
    25.    free(szSubKName);
    26. }
    27.  
    28. .
    29. .
    30. .
    31.  
    32. // где-то из потока вызываем
    33.   RegGo(HKEY_LOCAL_MACHINE,"HKEY_LOCAL_MACHINE",NULL);
    34.  




    Скажу сразу, что если передавать функции RegGo в качестве параметра HKEY_CURRENT_USER, то все будто бы нормально (у меня на системе). Как только передам HKEY_LOCAL_MACHINE, через примерно 128000 рекурсивных вызовов (устанавливал счетчик) получаю эксепшн С00000005. Пройдясь по стеку немного вниз, обнаружил странную особенность функции RegQueryInfoKey, которая при определенном

    параметре возращает количество подключей 3, а максимальную длину строки — 0! И вот код, который я воспроизвел у себя и получил такой глюк:


    Код (Text):
    1.  
    2.    HKEY hKey;
    3.    LONG res=RegOpenKeyEx(HKEY_LOCAL_MACHINE,
    4.                 "SYSTEM\\ControlSet002\\Control\\Class\\{4D36E96E-E325-11CE-BFC1-08002 BE10318}",
    5.                 0,KEY_READ,&hKey);
    6.    
    7.    DWORD dwcSubKeys,dwcValues,dwcMaxValueNameLen,dwcMaxValueLen,dwcMaxKeyLen;
    8.    res=RegQueryInfoKey(hKey,NULL,NULL,NULL,&dwcSubKeys,&dwcMaxKeyLen,NULL,
    9.                        &dwcValues,&dwcMaxValueNameLen,&dwcMaxValueLen,NULL,NULL);
    10.  


    Имею в ответе : dwcSubKeys=3,dwcValues=7,dwcMaxValueLen=62,dwcMaxKeyLen=0 ,dwcMaxValueNameLen=16.

    Система : win2000+sp4. Среда : VC++6,SP6.

    И вот нашел в инете такое(здесь):

    Fixed a very nasty bug that caused stack overflow in the search function. This could occur if RegQueryInfoKey() returned a pcbMaxSubKeyLen of zero, even if it was not. Am I looking at a bug in the Windows Registry API here? What I do, is to allocate a buffer with the size pcbMaxSubKeyLen+1, with the pcbMaxSubKeyLen of zero that leaves our buffer with a size of 1, not enough to store a key name, therefore all subkeys within this key would be reported as an empty string, and the search routine would go into an endless loop. If anyone could elaborate on this, I'd be very happy to listen.