Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

[C/C++]Рекурсия, реестр,сохранение строки.

52K
29 октября 2009 года
alex_ac
7 / / 29.10.2009
Делаю дамп реестра в файл.
Хочу, чтобы в файле оказалось
что-то типа:
HKEY_CURRENT_USER\AppEvents\
HKEY_CURRENT_USER\AppEvents\bla-bla-bla
~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~
HKEY_CURRENT_USER\printers\
HKEY_CURRENT_USER\printers\bla-bla-bla
~~~~~~~~~~~~~~~~~~~~~~
----------------------------------
Ежу понятно, что всё это делается рекурсивно.
Написал функцию.

Код:
LONG Dump(HKEY Key, char Subkey[MAX_PATH], char prefix)
{
       //инициализация переменных
       error = RegOpenKeyEx(Key, Subkey, bla-bla-bla, &key);
       //открываем подключ ключа key
       error = RegQueryInfoKey(key, bla-bla-bla);
      //узнаём количество значений и подключей
      fprintf(log, "%s; SubKeys: %d; Values %d\n", prefix, Subkeys, Values);
      printf("%s; SubKeys; %d; Values %d\n", prefix, Subkeys, Values);
      for(int loop = 0; loop < Subkeys; loop++)
      {
            RegEnumKeyEx(key, loop, ...);
            //Узнаём имя подключа
            //---------точка 1
            sprintf(prefix, "%s\\%s", prefix, SubKey);
            error = Dump(Key, SubKey, prefix);
            //---------точка 2
      }
      for(int loop = 0; loop < Values; loop ++)
      {
            //узнаём значения.
            fprintf(log, "%s\\%s: %s\n", prefix, value, Type);
            printf("%s\\%s: %s\n", prefix, value, Type);
      }
      return error;
}

---------------------------------------------
Как видно в prefix хранится название ключа реестра, в котором осуществляется в данный момент поиск подключей и ключей, в Key - родительский по отношению к текущему ключ, key - этот подключ.
Нетрудно догадаться, что если нигде не сохранять текущие значения аргументов и цикла в точке 1 и не восстанавливать их в точке 2 функция будет работать неправильно, т.к. при рекурсии новые значения будут в памяти писаться поверх. Я реализовал что-то вроде стека:
Код:
struct Stack
{
    HKEY Key;
    HKEY Parent;
    int Index;
    char Prefix[MAX_PATH];
}

Stack memory[128];//этого думаю будет достаточно.
int StackPointer = 0;

inline int PUSH(Stack *buffer)
{
    memory[StackPointer].Key = buffer->Key;
    memory[StackPointer].Parent = buffer->Parent;
    memory[StackPointer].Index = buffer->Index;
    strcpy(memory[StackPointer].Prefix, buffer->Prefix);
    return ++StackPointer;
}

inline int POP(Stack *buffer)
{
    buffer->Key = memory[--StackPointer].Key;
    buffer->Parent = memory[StackPointer].Parent;
    buffer->Index = memory[StackPointer].Index;
    strcmp(buffer->Prefix, memory[StackPointer].Prefix);
    return StackPointer;
}
//Функции довольно прозрачны.
//Следующий код вставляю в точку 1
buffer.Key = key;
buffer.Parent = Key;
buffer.Index = loop;
strcpy(buffer.Prefix, prefix);
PUSH(&buffer);
//а это вместо в точку 2
POP(&buffer);
key = buffer.Key;
Key = buffer.Parent;
loop = Index;
strcpy(prefix, buffer.Prefix);
////////////////////////////////

Компилируется всё как по маслу(MiGW в составе Dev-C++ 4.9)
А вот при выполнении вылетает ошибка и предложение начать дебаг.
Опытным путём (подстановкой в разных местах printf("Ya krevedko!\n"); ) я выяснил, что если закоментировать строки
 
Код:
strcpy(buffer.Prefix, prefix);//в точке 1
strcpy(memory[StackPointer].Prefix, buffer->Prefix);//В PUSH

Всё работает, правда без красивого вывода. (вместо этого пишет "(null)"\bla-bla-bla). Как добиться того, чтобы всё работало так, как задумано?

P.S. Пробовал менять на sprintf(buffer.prefix, "%s", ... - нет изменений.
P.P.S. Пробовал гуглить - ничего подобного не встретил.
P.P.P.S. Извиняюсь за кривой код - писал сам, и постоянно думал, как лучше назвть переменные - не плучилось :(.
7
29 октября 2009 года
@pixo $oft
3.4K / / 20.09.2006
Правильно,делаем велосипеды!А про то,что бравые ребята из Microsoft давным-давно сделали удобные функции для этого,даже и не задумываемся?[QUOTE=МыСДыН]Saves the specified key and all of its subkeys and values to a new file,in the standard format[/QUOTE]Вот у них ничего не вылетало,когда они реализовывали рекурсию
52K
30 октября 2009 года
alex_ac
7 / / 29.10.2009
Удобные функции? Я не делаю дамп реестра в полном смысле этого слова. Я только сохраняю в файл дерево реестра, с указанием типов значений и дат модификации - эта функция выдаст файл с значениями, ключей и подключей, но без дат, а значения мне не нужны. К чему парсить файл и всё равно реализовывать рекурсию из которой всё равно можно узнать те данные, которые всё-таки попадут в этот файл?

P.S. Мелкомягкие и бравые ребята - понятия не совместимые.
5
30 октября 2009 года
hardcase
4.5K / / 09.08.2005
Цитата: alex_ac
Я только сохраняю в файл дерево реестра

Команда reg это умеет. Какой смысл делать свою? UPD. А вот PowerShell обладает более мощными инструментами работы с реестром.

 
Код:
Stack memory[128];//этого думаю будет достаточно.
Ваша наивность безгранична :) А почему тогда кода проверки выхода за границы массива не сделали?

Цитата: alex_ac
P.S. Мелкомягкие и бравые ребята - понятия не совместимые.

Простите, но разве разработка, поддержка и продажа самой популярной линейки пользовательских ОС не делает им честь? ;)

288
30 октября 2009 года
nikitozz
1.2K / / 09.03.2007
Цитата: alex_ac

P.S. Мелкомягкие и бравые ребята - понятия не совместимые.



Без обид, но как-то смешно это слышать от человека, который сам не может справиться с довольно несложной задачей. Вы хоть что-то о "мелкомягких" знаете? Или все это навеяно байками из интернетов?
А может это просто модно для вас, обс...ть MS, даже не разбираясь почему?
P.S. простите за оффтоп.

52K
30 октября 2009 года
alex_ac
7 / / 29.10.2009
Цитата:

[QUOTE]Сообщение от alex_ac Посмотреть сообщение
Я только сохраняю в файл дерево реестра
Команда reg это умеет. Какой смысл делать свою? UPD. А вот PowerShell обладает более мощными инструментами работы с реестром.


[/QUOTE]
Собственно это попутная задача, а основная - контроль за изменениями в реестре в режиме реального времени.
Собственно сейчас можно отмести в сторону реестр. Мне непонятно, чем вызвана эта ошибка в копировании строки.

Цитата:

 
Код:
Stack memory[128];//этого думаю будет достаточно.

Ваша наивность безгранична А почему тогда кода проверки выхода за границы массива не сделали?


Собственно потому, что в том-же regedit редко увидишь больше 20 уровней вложенности. Я сделал массив с 4-5 кратным запасом.

P.S. Популярная - не значит лучшая. К тому-же я придерживаюсь мнения, что они украли её у Apple, поковырялись и стали продавать как свою. Вы слышали о тупом баге в их новом антивирусе, от которого он может не обновляться неделю при доступе к инету и пропускать довольно старые вирусы, лишь по тому, что их нет в базе Антивирус от Microsoft обновляется не слишком охотно?

52K
30 октября 2009 года
alex_ac
7 / / 29.10.2009
Вопрос решён - это всё легко и просто делается через stl.

 
Код:
#include <"stack">
//заголовок stl с классом стека.

std::stack<std::string> prefixes;
//объявляем стек

в коде:
 
Код:
prefixes.push(prefix);
    sprintf(prefix, "%s\\%s", prefix, SubKey);
    Dump(Key, SubKey, prefix);
    strcpy(prefix, prefixes.top().c_str());
    prefixes.pop();

Извините все, кого побеспокоил.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог