[C/C++]Рекурсия, реестр,сохранение строки.
Хочу, чтобы в файле оказалось
что-то типа:
HKEY_CURRENT_USER\AppEvents\
HKEY_CURRENT_USER\AppEvents\bla-bla-bla
~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~
HKEY_CURRENT_USER\printers\
HKEY_CURRENT_USER\printers\bla-bla-bla
~~~~~~~~~~~~~~~~~~~~~~
----------------------------------
Ежу понятно, что всё это делается рекурсивно.
Написал функцию.
{
//инициализация переменных
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 функция будет работать неправильно, т.к. при рекурсии новые значения будут в памяти писаться поверх. Я реализовал что-то вроде стека:
{
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(memory[StackPointer].Prefix, buffer->Prefix);//В PUSH
Всё работает, правда без красивого вывода. (вместо этого пишет "(null)"\bla-bla-bla). Как добиться того, чтобы всё работало так, как задумано?
P.S. Пробовал менять на sprintf(buffer.prefix, "%s", ... - нет изменений.
P.P.S. Пробовал гуглить - ничего подобного не встретил.
P.P.P.S. Извиняюсь за кривой код - писал сам, и постоянно думал, как лучше назвть переменные - не плучилось :(.
P.S. Мелкомягкие и бравые ребята - понятия не совместимые.
Команда reg это умеет. Какой смысл делать свою? UPD. А вот PowerShell обладает более мощными инструментами работы с реестром.
Простите, но разве разработка, поддержка и продажа самой популярной линейки пользовательских ОС не делает им честь? ;)
P.S. Мелкомягкие и бравые ребята - понятия не совместимые.
Без обид, но как-то смешно это слышать от человека, который сам не может справиться с довольно несложной задачей. Вы хоть что-то о "мелкомягких" знаете? Или все это навеяно байками из интернетов?
А может это просто модно для вас, обс...ть MS, даже не разбираясь почему?
P.S. простите за оффтоп.
[QUOTE]Сообщение от alex_ac Посмотреть сообщение
Я только сохраняю в файл дерево реестра
Команда reg это умеет. Какой смысл делать свою? UPD. А вот PowerShell обладает более мощными инструментами работы с реестром.
[/QUOTE]
Собственно это попутная задача, а основная - контроль за изменениями в реестре в режиме реального времени.
Собственно сейчас можно отмести в сторону реестр. Мне непонятно, чем вызвана эта ошибка в копировании строки.
Ваша наивность безгранична А почему тогда кода проверки выхода за границы массива не сделали?
Собственно потому, что в том-же regedit редко увидишь больше 20 уровней вложенности. Я сделал массив с 4-5 кратным запасом.
P.S. Популярная - не значит лучшая. К тому-же я придерживаюсь мнения, что они украли её у Apple, поковырялись и стали продавать как свою. Вы слышали о тупом баге в их новом антивирусе, от которого он может не обновляться неделю при доступе к инету и пропускать довольно старые вирусы, лишь по тому, что их нет в базе Антивирус от Microsoft обновляется не слишком охотно?
//заголовок stl с классом стека.
std::stack<std::string> prefixes;
//объявляем стек
в коде:
sprintf(prefix, "%s\\%s", prefix, SubKey);
Dump(Key, SubKey, prefix);
strcpy(prefix, prefixes.top().c_str());
prefixes.pop();
Извините все, кого побеспокоил.