RtlQueryRegistryValues

From
Genadi Zawidowski (2:5020/175.2)
To
Ilya Rudakov
Date
2002-11-17T20:55:13Z
Area
SU.WINDOWS.NT.PROG
From: "Genadi Zawidowski" <dolphin@infopro.spb.su>

Sun Nov 17 2002 18:29, Ilya Rudakov wrote to Arthur Vartanov:

Позвольте вставить пару цитат не от себя - от Walter Oney:

1) errata -----------------------

p. 120-Don't call RtlQueryRegistryValues [01/09/01]
The RtlQueryRegistryValues function is part of the Win2K kernel's
initialization section. It's therefore not available by the time a typical WDM
driver would like to call it.



2) book -----------------------

Getting and Setting Values
Usually, you open a registry key because you want to retrieve a value from the
database. The basic function you use for that purpose is ZwQueryValueKey. For
example, to retrieve the ImagePath value in the driver's service key-I don't
actually know why you'd want to know this, but that's not my department-you
could use the following code:

UNICODE_STRING valname;
RtlInitUnicodeString(&valname, L"ImagePath");
size = 0;
status = ZwQueryValueKey(hkey, &valname, KeyValuePartialInformation, 
  NULL, 0, &size);
if (status == STATUS_OBJECT_NOT_FOUND || size == 0)
  <handle error>;
PKEY_VALUE_PARTIAL_INFORMATION vpip = (PKEY_VALUE_PARTIAL_INFORMATION)
  ExAllocatePool(PagedPool, size);
if (!vpip)
  <handle error>;
status = ZwQueryValueKey(hkey, &valname, KeyValuePartialInformation,
  vpip, size, &size);
if (!NT_SUCCESS(status))
  <handle error>;
<do something with vpip->Data>
ExFreePool(vpip);

 


Here, we make two calls to ZwQueryValueKey. The purpose of the first call is
to determine how much space we need to allocate for the
KEY_VALUE_PARTIAL_INFORMATION structure we're trying to retrieve. The second
call retrieves the information. I left the error checking in this code
fragment because the errors didn't work out in practice the way I expected
them to. In particular, I initially guessed that the first call to
ZwQueryValueKey would return STATUS_BUFFER_TOO_SMALL if I passed it a NULL
buffer pointer. It didn't do that, though. The important failure code is
STATUS_OBJECT_NAME_NOT_FOUND, which indicates that the value doesn't actually
exist. Hence, I test for that value only. If there's some other error that
prevents ZwQueryValueKey from working, the second call will uncover it.

The so-called "partial" information structure you retrieve in this way
contains the value's data and a description of its data type:

typedef struct _KEY_VALUE_PARTIAL_INFORMATION {
    ULONG   TitleIndex;
    ULONG   Type;
    ULONG   DataLength;
    UCHAR   Data[1];
} KEY_VALUE_PARTIAL_INFORMATION,
  *PKEY_VALUE_PARTIAL_INFORMATION;

 


Type is one of the registry data types listed in Table 3-11. (Additional data
types are possible but not interesting to device drivers.) DataLength is the
length of the data value, and Data is the data itself. TitleIndex has no
relevance to drivers. Here are some useful facts to know about the various
data types:


REG_DWORD is a 32-bit unsigned integer in whatever format (big-endian or
little-endian) is natural for the platform.


REG_SZ describes a null-terminated Unicode string value. The null terminator
is included in the DataLength count.


To expand a REG_EXPAND_SZ value by substituting environment variables, you
should use RtlQueryRegistryValues as your method of interrogating the
registry. The internal routines for accessing environment variables aren't
documented or exposed for use by drivers.


RtlQueryRegistryValues is also a good way to interrogate REG_MULTI_SZ values,
in that it will call your designated callback routine once for each of the
potentially many strings.


 IR> Наукой доказано, что 17 оя 02, Arthur Vartanov говорил Ilya Rudakov по
 IR> поводу "Re: RtlQueryRegistryValues" следующее:


 IR>>>  Я читал все кроме binary (не получилось) и multi_sz (не было
 IR>>> необходимости пока). Все на ура.

 AV>> С binary не все так просто. Там в начало буфер надо класть структуру
 AV>> из двух DWORD. Чего они означают уже не помню, но если сильно надо,
 AV>> могу посмотреть в исходниках. Да, и размер буфера нужно указывать на
 AV>> эти 8 байт больше.

 IR>  Я подозревал нечто подобное, но разбираться не было времени, сделал все
 IR> через Zw. Судя по моим наблюдениям первый DWORD содержит размер
 IR> binary-данных, а второй в моем случае содержал 0x3 (REG_BINARY?). Загадка
 IR> заключалась в том, что в debug-версии без обнуления входного буфера (т.е.
 IR> буфер заполнен 0xCC) все читается  замечательно, т.е. буфер содержит
 IR> именно требуемое значение, безо всяких дополнений. После того, как я
 IR> наткнулся на такой эффект, я прекратил экперименты:)
 IR>  Обидно, что в ДДК на этот счет нет никаких замечаний:( Или может я плохо
 IR> искал? Если будет время, то уточни пожалуйста, предназначение этих
 IR> дополнительных параметров. Мне в принципе не к спеху.

 IR>      С уважением, Илья.                       
 IR> <mailto:mr_wiseman@mail.ru>

 IR>         [Depeche Mode] [Роджер Желязны] [F1_McLaren] [WinNT] [MSVC++]
 IR>                 [Delphi - гадость] [Задолбали слюниксоиды!!!]
 IR> ... np: silence (Winamp is not active)

Генка - mgs2001 at pochramt dot ru

--- ifmail v.2.15dev5
 * Origin: FidoNet Online - http://www.fido-online.com (2:5020/175.2)