Модераторы: Snowy, bartram, MetalFan, bems, Poseidon, Riply
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Работа с реестром на API, Работа с реестром из сервиса на API 
:(
    Опции темы
TeX
Дата 27.10.2008, 16:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 16
Регистрация: 23.12.2007

Репутация: нет
Всего: нет



Здравствуйте уважаемые !
Пишу сервис, который должен проверять определенные ветки реестра (), на появление "левых" записей.
Подскажите как правильно работать с реестром из сервиса с помощью API. Я нашел похожую тему, но там было только создание и удаление и то , из обычного приложения. Хорошо было бы если примерчик дадите.

Это сообщение отредактировал(а) TeX - 27.10.2008, 16:20
PM MAIL   Вверх
ne0n
Дата 27.10.2008, 21:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


PlayBoy
**


Профиль
Группа: Участник
Сообщений: 733
Регистрация: 5.8.2005
Где: Н.Новгород

Репутация: 4
Всего: 11



PM MAIL ICQ   Вверх
TeX
Дата 28.10.2008, 08:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 16
Регистрация: 23.12.2007

Репутация: нет
Всего: нет



Цитата(ne0n @ 27.10.2008,  21:49)
TeX, http://delphiworld.narod.ru/base/registry_api.html

Спасибо за ссылку, очень полезная, НО... хотелось бы разобраться как работать с реестром с помощью функций из ntdll.dll.
PM MAIL   Вверх
ne0n
Дата 28.10.2008, 11:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


PlayBoy
**


Профиль
Группа: Участник
Сообщений: 733
Регистрация: 5.8.2005
Где: Н.Новгород

Репутация: 4
Всего: 11



Цитата(TeX @  28.10.2008,  08:45 Найти цитируемый пост)
Спасибо за ссылку, очень полезная, НО... хотелось бы разобраться как работать с реестром с помощью функций из ntdll.dll.


так и надо было сказать что нужно именно Native Api,  Вообщем  есть очень хорошая книга - 
Справочник по базовым функциям API Windows NT/2000, Гэри Неббет. Есть глава посвященная реестру, в которой все подробно расписано. Но там все прототипы приводяться для C++, для Delphi я вроде не встречал  подоного. При желании перевести не сложно.

PM MAIL ICQ   Вверх
TeX
Дата 28.10.2008, 14:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 16
Регистрация: 23.12.2007

Репутация: нет
Всего: нет



Цитата(ne0n @ 28.10.2008,  11:53)
так и надо было сказать что нужно именно Native Api,  Вообщем  есть очень хорошая книга - 
Справочник по базовым функциям API Windows NT/2000, Гэри Неббет. Есть глава посвященная реестру, в которой все подробно расписано. Но там все прототипы приводяться для C++, для Delphi я вроде не встречал  подоного. При желании перевести не сложно.

За наводку на книгу, спасибо, найду-почитаю. У JEDI нашел интерфейсный модуль Windows NT Native API   для delphi, в котором описаны все структуры, процедуры и функции. Вот сижу сейчас разбираюсь с этим.
PM MAIL   Вверх
TeX
Дата 30.10.2008, 10:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 16
Регистрация: 23.12.2007

Репутация: нет
Всего: нет



Два дня упражнений привели лишь к номальному открытию ветки реестра, а вот с чтением туго.
Подскажите ка работать с функцией

Код

   function NtQueryValueKey(KeyHandle:THandle; 
                                             ValueName:PUNICODE_STRING;
                                             KeyValueInformationClass:KEY_VALUE_INFORMATION_CLASS; 
                                             var KeyValueInformation:PVOID; 
                                             Length:ULONG;
                                             var ResultLength:PULONG):NTSTATUS; stdcall; external ntdll name 'NtQueryValueKey';

Загвоздка в буфере, куда будет помещена информация.
В зависимости  KeyValueInformationClass должны использоваться разные структуры, описания которых в интерфейсном модуле нет. Пришлось самому сделать эту структуру:
Код

PKEY_VALUE_PARTIAL_INFORMATION = ^_KEY_VALUE_PARTIAL_INFORMATION;
 _KEY_VALUE_PARTIAL_INFORMATION = packed record
    TitleIndex:ULONG;
    Type_:ULONG;
    DataLength:ULONG;
    Data:array [0..0] of UCHAR; // Variable length data
 end;
 KEY_VALUE_PARTIAL_INFORMATION=_KEY_VALUE_PARTIAL_INFORMATION;


Вод код процедуры:

Код

procedure TForm1.SpeedButton1Click(Sender: TObject);
var
   KeyName: UNICODE_STRING;
   ValueName: UNICODE_STRING;
   SoftwareKeyHandle: THandle;
   Status: ULONG;
   ObjAttr: OBJECT_ATTRIBUTES;
   Buffer: array of WideChar;
   Key:widestring;
   ValueKey:WideString;
   err:cardinal;
   Data:^KEY_VALUE_PARTIAL_INFORMATION;
   ValueString:UNICODE_STRING;
   DataSize:ULONG;
begin
  Key:=sid; // путь с SID-ом текущего пользователя
  RtlInitUnicodeString(@KeyName,@key[1]);
  RtlInitUnicodeString(@ValueName,'App');
  InitializeObjectAttributes(@ObjAttr, @KeyName, OBJ_CASE_INSENSITIVE,0, nil);
  Status := NtOpenKey(@SoftwareKeyHandle,KEY_QUERY_VALUE,@ObjAttr);
  if not NT_SUCCESS(Status) then
   raise Exception.Create('Error: Couldn''t open registry tree')
   else
    begin
     Status:=NtQueryValueKey(SoftwareKeyHandle,@ValueName, KeyValuePartialInformation,nil,0,@DataSize); // получаем размер данных
     if DataSize <> 0 then
       begin
         data:=AllocMem(sizeof(KEY_VALUE_PARTIAL_INFORMATION));
         Status:=NtQueryValueKey(SoftwareKeyHandle,@ValueName, KeyValuePartialInformation,Data,DataSize,@DataSize); //пытаемся получить значение
         if NT_SUCCESS(status) then
          begin
            if PKEY_VALUE_PARTIAL_INFORMATION(data).Type_ = REG_SZ then
              ShowMessage('ok'); //  <--- Здесь возникает исключение Debugger Fail Notification
          end;
       end;
    end;

  NtClose(SoftwareKeyHandle )
end;



При работе возникает исключение, что-то я неправильно делаю и скорее что-то с выделением памяти, но где не могу понять. smile  Пмогите кодом или советом.

PM MAIL   Вверх
Riply
Дата 31.10.2008, 08:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Комодератор
Сообщений: 572
Регистрация: 27.3.2007
Где: St. Petersburg

Репутация: 21
Всего: 32



Цитата(TeX @  30.10.2008,  10:29 Найти цитируемый пост)
В зависимости  KeyValueInformationClass должны использоваться разные структуры, описания которых в интерфейсном модуле нет


Если мне не изменяет память они все (структуры) есть в MSDN



Цитата(TeX @  30.10.2008,  10:29 Найти цитируемый пост)
Пришлось самому сделать эту структуру


При использовании "системных" функций, отсебятина в определении структур недопустима
(за исключением очень редких случаев)
При переводе структур с С на Delphi, внимательно следи не тлько за размером всей
стр-ры, но и каждого поля в отдельности.

Это было вступление, теперь бегло взглянем на код и ужаснемся smile

Код

Status:=NtQueryValueKey(SoftwareKeyHandle,@ValueName, yValuePartialInformation,nil,0,@DataSize); 
if DataSize <> 0 then


1. Для чего в данной строчке определяется Status ?
2. С чего ты взял, что если NtQueryValueKey отработает с ошибкой, то будет произведена запись
    в DataSize (которая, меду прочим, не инициализирована, но это "к слову") ?
3. Зачем вообще ты пытался получить  DataSize, если после этого выделяешь память
    таким образом data:=AllocMem(sizeof(KEY_VALUE_PARTIAL_INFORMATION)); ?
4. Почему в память размера sizeof(KEY_VALUE_PARTIAL_INFORMATION)
    ты пишешь DataSize байт, а потом еще удивляешся на AV ?
5. Где освобождение памяти ?
6. Почему не используются try/finally ?

Мое IMHO: рановато тебе еще работать с Native-функциями.
Просто приведенный кусок кода показывает полное непонимание его автором
того что в нем (коде) происходит.
Дружеский совет: почитай книжки (акцентируй внимание на работе с памятью и с ошибками). 

PM MAIL   Вверх
TeX
Дата 31.10.2008, 09:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 16
Регистрация: 23.12.2007

Репутация: нет
Всего: нет



Цитата
Мое IMHO: рановато тебе еще работать с Native-функциями.
Просто приведенный кусок кода показывает полное непонимание его автором
того что в нем (коде) происходит.
Дружеский совет: почитай книжки (акцентируй внимание на работе с памятью и с ошибками). 

Спасибо за критику. Я действительно с Native и API столкнулся недавно, поэтому такой сумбур, но я учусь, а это немаловажно. поэтому и задаю вопросы, чтобы объяснили, а не отсылали к книжкам.
А теперь по существу.
Цитата
1. Для чего в данной строчке определяется Status ?
2. С чего ты взял, что если NtQueryValueKey отработает с ошибкой, то будет произведена запись
    в DataSize (которая, меду прочим, не инициализирована, но это "к слову") ?

Он, Status, в этой строке впринципе и не нужен, просто copy/paste. Функция действительно отрабатывает с ошибкой, но размер структуры в DataSize выдает, проверено. Не инициализирована переменная, потому что это просто наброск, черновик.
Цитата
3. Зачем вообще ты пытался получить  DataSize, если после этого выделяешь память
    таким образом data:=AllocMem(sizeof(KEY_VALUE_PARTIAL_INFORMATION)); ?
4. Почему в память размера sizeof(KEY_VALUE_PARTIAL_INFORMATION)
    ты пишешь DataSize байт, а потом еще удивляешся на AV ?
5. Где освобождение памяти ?

После долго перелопачивания MSDN и кучи кода на С, просто запутался. Но Я с этим разобрался, код переписал, см. ниже.
Цитата
6. Почему не используются try/finally ?

Я говорил, это только черновик.
А теперь далее.
Немного подправил код:
Описание структуры, которой нехватало в заголовочном файле, взял из MSDN, получилось вот так: 
Код

PKEY_VALUE_PARTIAL_INFORMATION=^KEY_VALUE_PARTIAL_INFORMATION;
  KEY_VALUE_PARTIAL_INFORMATION=packed record
    TitleIndex: ULONG;
    Type_: ULONG;
    DataLength: ULONG;
    Data:array[0..0] of UCHAR; 
  end;


Код

procedure TForm1.SpeedButton1Click(Sender: TObject);
var
   _as:ANSI_STRING;
   us:UNICODE_STRING;
   KeyName: UNICODE_STRING;
   ValueName: UNICODE_STRING;
   SoftwareKeyHandle: THandle;
   Status: ULONG;
   ObjAttr: OBJECT_ATTRIBUTES;
   Key:widestring;
   Data:PKEY_VALUE_PARTIAL_INFORMATION;
   DataSize:ULONG;
begin
  Key:=sid;
  RtlInitUnicodeString(@KeyName,@key[1]);
  RtlInitUnicodeString(@ValueName,'Infium');
  InitializeObjectAttributes(@ObjAttr, @KeyName, OBJ_CASE_INSENSITIVE,0, nil);
  Status := NtOpenKey(@SoftwareKeyHandle,KEY_QUERY_VALUE,@ObjAttr);
  if not NT_SUCCESS(Status) then
   raise Exception.Create('Error: Couldn''t open registry tree')
   else
    begin
     NtQueryValueKey(SoftwareKeyHandle,@ValueName,KeyValuePartialInformation,nil,0,@DataSize);
     if DataSize <> 0 then
      begin
       Data := AllocMem(DataSize);
       GetMem(Data,DataSize);
       ZeroMemory(Data,DataSize);
      if Data <> nil then
       begin
        Status := NtQueryValueKey(SoftwareKeyHandle,@ValueName,KeyValuePartialInformation,Data, DataSize,@dataSize);
        if (NT_SUCCESS(Status)) and ( DataSize <> 0) then
         begin
          if Data^.Type_ = REG_SZ then
           begin
            RtlInitUnicodeString(@us, @data^.Data);
            Status:=RtlUnicodeStringToAnsiString(@_as,@us, true);
            if  NT_SUCCESS(status) then
              begin
                ShowMessage(_as.Buffer);
                RtlFreeAnsiString(@_as);
              end;
           end;
         end
      end
    end;
   end;
  NtClose(SoftwareKeyHandle );
  FreeMem(Data);


Все заработало, единственное, может какие будут замечания по поводу, кода.
Готов принять конструктивную критику.

Это сообщение отредактировал(а) TeX - 31.10.2008, 10:06
PM MAIL   Вверх
Riply
Дата 31.10.2008, 18:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Комодератор
Сообщений: 572
Регистрация: 27.3.2007
Где: St. Petersburg

Репутация: 21
Всего: 32



Цитата(TeX @  31.10.2008,  09:01 Найти цитируемый пост)
но я учусь, а это немаловажно. поэтому и задаю вопросы, чтобы объяснили, а не отсылали к книжкам.


Мне казалось, что перед тем, как послать smile к книжкам,
я довольно подробно расписала ошибки, которые бросаются в глаза smile

Цитата(TeX @  31.10.2008,  09:01 Найти цитируемый пост)
Он, Status, в этой строке впринципе и не нужен, просто copy/paste


Еще как нужен smile
Более того, все дальнейшие шаги по чтению возможны только при
определенных его значениях (см MSDN) и они (шаги) зависят от этого значения.
(Например нет такого ValueName)

Цитата(TeX @  31.10.2008,  09:01 Найти цитируемый пост)
но размер структуры в DataSize выдает, проверено


То что десять раз выдало, вовсе не означает, что выдаст и на следующий.
Доказательством "выдавания" может служить только документация или исходный код
процедуры NtQueryValueKey

Цитата(TeX @  31.10.2008,  09:01 Найти цитируемый пост)
 Не инициализирована переменная, потому что это просто наброск, черновик.


Нет в программировании такого понятия как черновик. 
Или ты тестируешь один код (черновой),
оттестировал, а использовать будешь совсем другой (чистовой).
Зачем тогда было тестировать черновой вариант ? smile
Это раз.
Второе: 
ты привел код с просьбой найти ошибку. Я и ищу ошибку в приведенном коде,
а не телепатирую, что ты собираешся исправить в чистовом варианте smile

Теперь по коду:

Код

NtQueryValueKey(SoftwareKeyHandle,@ValueName,KeyValuePartialInformation,nil,0,@DataSize);
     if DataSize <> 0 then
      begin
       Data := AllocMem(DataSize);
       GetMem(Data,DataSize);


Я уж молчу про то что NtQueryValueKey может отработать с ошибкой
Следующие за ней две строчки показывают, что я не ошиблась отсылая тебя к книжкам:
ты действительно совершенно не понимаешь как работают с памятью.
Дальше смотреть не стала, ибо пока ты не прочитаешь книжку (на чем ставить акцент я уже говорила) дальнейшее обсуждение принципов работы Native-функций не имеет смысла.

 

Это сообщение отредактировал(а) Riply - 31.10.2008, 18:20
PM MAIL   Вверх
TeX
Дата 1.11.2008, 16:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 16
Регистрация: 23.12.2007

Репутация: нет
Всего: нет



Полностью соглашусь со всем вышенаписанным.
Тогда другой вопрос, какие книжки, по вашему мнению, стоит прочитать, чтоб разбираться, так же как и Вы ?
Цитата
   NtQueryValueKey(SoftwareKeyHandle,@ValueName,KeyValuePartialInformation,nil,0,@DataSize);
     if DataSize <> 0 then
      begin
       Data := AllocMem(DataSize);
       GetMem(Data,DataSize);
       ZeroMemory(Data,DataSize);
       if Data <> nil then

О ужас  smile , я только заметил это, какой непорядок, все это от перегрузки моска от такого количества инфы
Переделал так:
Код
 NtQueryValueKey(SoftwareKeyHandle,@ValueName,KeyValuePartialInformation,nil,0,@DataSize);
     if DataSize <> 0 then
      begin
       Data := AllocMem(DataSize);
       if Data <> nil then

Абосную выбор. AllocMem делает getMem и заполняет память нулями.

Это сообщение отредактировал(а) TeX - 1.11.2008, 16:52
PM MAIL   Вверх
Riply
Дата 1.11.2008, 20:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Комодератор
Сообщений: 572
Регистрация: 27.3.2007
Где: St. Petersburg

Репутация: 21
Всего: 32



Цитата(TeX @  1.11.2008,  16:24 Найти цитируемый пост)
Тогда другой вопрос, какие книжки, по вашему мнению, стоит прочитать


Пройдись поиском по форуму.
Здесь не только давали голые ссылки на литературу, 
но и сопровождали их своими отзывами. 
IMHO - это помогает выбрать нужную исходя из своего уровня подготовки.
Я же конкретную книгу посоветовать не могу, т.к. не знаю этого уровня.
Но лично мне очень помог Рихтер. Он у меня и сейчас - "настольная книга"
в прямом и переносном смысле smile

По коду: настоятельно рекомендую не опираться на возвращаемое значение DataSize,
а анализировать код возврата  NtQueryValueKey (возможные коды должны быть в MSDN).
Насчет памяти, пока можно(нужно) и так. А когда научишся правильно обрабатывать
возвращаемое значение ф-ии, то затирание памяти станет избыточным
и его можно будет убрать.
Незачем загружать процессор излишней работой. Ему тоже отдохнуть хочется smile


Это сообщение отредактировал(а) Riply - 1.11.2008, 20:23
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: WinAPI и системное программирование"
Snowybartram
MetalFanbems
PoseidonRrader
Riply

Запрещено:

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Delphi обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи
  • 99% ответов по WinAPI можно найти в MSDN Library, оставшиеся 1% здесь

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, bartram, MetalFan, bems, Poseidon, Rrader, Riply.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: WinAPI и системное программирование | Следующая тема »


 




[ Время генерации скрипта: 0.0578 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.