Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Help with RtlQueryRegistryValues

252 views
Skip to first unread message

Al Harper

unread,
Nov 6, 1998, 3:00:00 AM11/6/98
to
The following call to RtlQueryRegistryValues() is returning good
status but no serial device names are showing up anywhere.
Can anyone tell me where my problem is?

Thanks Al Harper

NTSTATUS GetDeviceNames(IN PDEVICE_OBJECT DeviceObject)
{
RTL_QUERY_REGISTRY_TABLE Table[6];
NTSTATUS status;
HANDLE hKey;
WCHAR PathNameBuffer[ 40 ];
UNICODE_STRING SubPath;
UNICODE_STRING Name1;
UNICODE_STRING Name2;
UNICODE_STRING Name3;


PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
RtlZeroMemory( Table, sizeof(Table));

RtlInitUnicodeString(&SubPath, L"\\SERIALCOMM");

Table[0].Name = PathNameBuffer;
Table[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
Table[1].EntryContext = &Name1;

Table[1].Name = PathNameBuffer; // I/O port addr
Table[1].Flags = RTL_QUERY_REGISTRY_DIRECT;
Table[1].EntryContext = &Name2;

Table[2].Name = PathNameBuffer; // Number of ports
Table[2].Flags = RTL_QUERY_REGISTRY_DIRECT;
Table[2].EntryContext = &Name3;

status = RtlQueryRegistryValues(
RTL_REGISTRY_DEVICEMAP,
L"SERIALCOMM",
Table,
NULL, NULL );

return status;
}

crick_lin

unread,
Nov 7, 1998, 3:00:00 AM11/7/98
to
The serial device name on DEVICEMAP of NT registry is created by
SERIAL driver. It'll be cleared every time when NT boot.
If your driver is called before SERIAL driver DriverEntry routine.
You'll got nothing.
You can start your driver via NET START command rather than
NT BOOT time. If you can get serial device name correctly. I think your
problem is that your driver be called too early.
If you can't get serial device name correctly, debug your deiver via
NET START/STOP command rather than reboot NT every time.
It'll save much of time on debugging.
And if you still can't find the problem, establish a NT driver debugging
environment. The KdPrint() function will do lots of help.

Good Luck.
Crick.

Al Harper 撰寫於文章 <01be09a9$91632730$270cf390@harpersnt>...


>The following call to RtlQueryRegistryValues() is returning good
>status but no serial device names are showing up anywhere.
>Can anyone tell me where my problem is?
>

......

Al Harper

unread,
Nov 7, 1998, 3:00:00 AM11/7/98
to
I am making the call after serial.sys is started. I've run WINOBJ to make
sure the
device names are present.

crick_lin <cric...@moxa.com.tw> wrote in article
<7205pg$e9k$1...@news.seed.net.tw>...

crick_lin

unread,
Nov 7, 1998, 3:00:00 AM11/7/98
to
The following is parts of my driver source code about RtlQuery....
Hope it's helpful for you.

Good Luck. Crick.

paramTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
paramTable[0].Name = RegPorts;
paramTable[0].EntryContext = &DevNo;
paramTable[0].DefaultType = REG_DWORD;
paramTable[0].DefaultData = &DefaultValue;
paramTable[0].DefaultLength = sizeof(ULONG);
paramTable[1].Flags = RTL_QUERY_REGISTRY_DIRECT;
paramTable[1].Name = RegServers;
paramTable[1].EntryContext = &ServerNo;
paramTable[1].DefaultType = REG_DWORD;
paramTable[1].DefaultData = &DefaultValue;
paramTable[1].DefaultLength = sizeof(ULONG);
status = RtlQueryRegistryValues(
RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL,
path.Buffer,
&paramTable[0],
NULL,
NULL
);

Al Harper 撰寫於文章 <01be09f1$c98c0e40$927e02d0@harpersnt>...


>I am making the call after serial.sys is started. I've run WINOBJ to make
>sure the
>device names are present.
>

.......

crick_lin

unread,
Nov 7, 1998, 3:00:00 AM11/7/98
to
I forget to tell you one thing.
I think there is one bug on your codes.
You allocate 3 UNICODE_STRING :
UNICODE_STRING Name1,Name2,Name3.
But don't allocate any buffer for it.
Check the UNICODE_STRING structure on ntddk.h.
You can see the structure contains no buffer for UNICODE_STRING.
It's only a pointer.

The SubPath varible is ok because you call
RtlInitUnicodeString(&SubPath,L"\\SERIALCOMM");
This function do the following :
1. Set maximum buffer size of SubPath to SIZEOF(L"\\SERIALCOMM")
2. Set string size = sizeof(L"\\SERIALCOMM");
3. The string buffer pointer set to L"\\SERIALCOMM"

But where are the buffer of Name1,Name2,Name3 ?
There is no buffer to save the serial com device name.

Good Luck. Crick.

Al Harper

unread,
Nov 7, 1998, 3:00:00 AM11/7/98
to
Crick,
Thanks for your response. I am aware that the buffer in the unicode
struc is a pointer. What you saw in my sample is one of many variations
trying to get this to work. The call to retrieve the names is returning
with a
good return code, just NO DATA in any buffer. I'm attaching the routine
which I finally got going, but I had to use a callback routine to get it to
work. I would really like this to work without a callback. If you feel
ambitious
I would appreciate it if you could show me how to implement theis without a
callback.

Remember, this is not a complete routine. I have not added the code yet to
copy the name strings out of the returned buffer yet. This is just where I
left off
before I left work for the day. I just threw this together really quick
just to
see if callbacks would work.
Al


NTSTATUS GetDeviceNames(IN PDEVICE_OBJECT DeviceObject)
{
RTL_QUERY_REGISTRY_TABLE Table[6];
NTSTATUS status;
HANDLE hKey;
WCHAR PathNameBuffer[ 40 ];
UNICODE_STRING SubPath;
UNICODE_STRING Name1;
UNICODE_STRING Name2;
UNICODE_STRING Name3;

ULONG count = 0;

PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
RtlZeroMemory( Table, sizeof(Table));

RtlInitUnicodeString(&SubPath, L"\\SERIALCOMM");

Table[0].Name = 0;
Table[0].Flags = RTL_QUERY_REGISTRY_REQUIRED;
Table[0].EntryContext = &count;
Table[0].QueryRoutine = myCallback;

status = RtlQueryRegistryValues(
RTL_REGISTRY_DEVICEMAP|RTL_REGISTRY_OPTIONAL,


L"SERIALCOMM",
Table,
NULL, NULL );

return status;
}

/***************************************************************************
**/
NTSTATUS myCallback(
IN PWSTR ValueName,
IN ULONG ValueType,
IN PVOID ValueData,
IN ULONG ValueLength,
IN PVOID Context, // unused
IN PULONG Count // entry context = ptr count
)
{
if( ValueName != 0 && ValueLength != 0 )
{
*Count++; //bump count
}
return 0;
}


crick_lin

unread,
Nov 8, 1998, 3:00:00 AM11/8/98
to
I checked my driver, I didn't query an UNICODE_STRING via
RtlQuery.. function.
On my experience if the registry values type is DWORD the DIRECT
query will work smoothly. But won't work smoothly for BINARY type.
I also use a callback routine to query a BINARY value.

I guess if the length on registry tree is not fixed(BINARY and UNICODE
STRING are varible length but DWORD is fixed length) we had better
use a callback routine to process it.

I am not very sure about it. Just my personal though about this case.
Crick.

Al Harper 撰寫於文章 <01be0a7f$57c4eb40$bd7e02d0@harpersnt>...


>Crick,
>Thanks for your response. I am aware that the buffer in the unicode
>struc is a pointer. What you saw in my sample is one of many variations
>trying to get this to work. The call to retrieve the names is returning
>with a

[snip]
.....

mst...@fh-landshut.de

unread,
Nov 8, 1998, 3:00:00 AM11/8/98
to
Al Harper wrote:
>
> The following call to RtlQueryRegistryValues() is returning good
> status but no serial device names are showing up anywhere.
> Can anyone tell me where my problem is?
>
> Thanks Al Harper

>
> NTSTATUS GetDeviceNames(IN PDEVICE_OBJECT DeviceObject)
> {
> RTL_QUERY_REGISTRY_TABLE Table[6];
> NTSTATUS status;
> HANDLE hKey;
> WCHAR PathNameBuffer[ 40 ];
> UNICODE_STRING SubPath;
> UNICODE_STRING Name1;
> UNICODE_STRING Name2;
> UNICODE_STRING Name3;
>
> PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
> RtlZeroMemory( Table, sizeof(Table));
>
> RtlInitUnicodeString(&SubPath, L"\\SERIALCOMM");
>
> Table[0].Name = PathNameBuffer;
> Table[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
> Table[1].EntryContext = &Name1;
>
> Table[1].Name = PathNameBuffer; // I/O port addr
> Table[1].Flags = RTL_QUERY_REGISTRY_DIRECT;
> Table[1].EntryContext = &Name2;
>
> Table[2].Name = PathNameBuffer; // Number of ports
> Table[2].Flags = RTL_QUERY_REGISTRY_DIRECT;
> Table[2].EntryContext = &Name3;
>
> status = RtlQueryRegistryValues(
> RTL_REGISTRY_DEVICEMAP,
> L"SERIALCOMM",
> Table,
> NULL, NULL );
>
> return status;
> }

You don´t have to allocate buffers for the unicode strings, but
you have to initialize the buffers with NULL pointers, to
let RtlQueryRegistryValues(..) alocate the buffers for you.

Mike

Al Harper

unread,
Nov 9, 1998, 3:00:00 AM11/9/98
to
So what your saying is, if I set EntryContext to NULL, this will work? I do
not
have to do anything to pre-initialize any part of the unicode string?
I think I've already tries that, but am more than willing to try again. The
code you
see below is one of MANY attempts to get this working.

I'll try again.
Al

mst...@fh-landshut.de wrote in article <364594...@fh-landshut.de>...

mst...@fh-landshut.de

unread,
Nov 9, 1998, 3:00:00 AM11/9/98
to
Sorry if i was unclear on this, i meant you should try the following:

UNICODE_STRING Name1;
...
Name1.Buffer = NULL;
....
Table[0].EntryContext = &Name1;
....
RtlQueryRegistryValues(...)


Maby this is unnecessary, i am not quite sure if the
compiler initializes stack variables with NULL.

[.....]

Al Harper

unread,
Nov 10, 1998, 3:00:00 AM11/10/98
to
I did try this. Numerous times. If it was supposed to work, then maybe I've
over
looked some subtle parameter or option. I finally settled on using the
Query
call-back routine option. The DDK clearly states that callbacks are an
option,
but from my experiences and comments form other developers, that may not be
so
under certain circumstances.
Al

mst...@fh-landshut.de wrote in article <3646E6...@fh-landshut.de>...

Serial # 0

unread,
Nov 23, 1998, 3:00:00 AM11/23/98
to
Non-callbacks query is possible. Cant remember how I got it to work ;(

Let me check my \src\archive\ . . .
If I recall correctly, the problem was mishandling the default value.


ULONG level, def= . . .;
RTL_QUERY_REGISTRY_TABLE queries[2];
NTSTATUS status;

RtlZeroMemory (queries, sizeof(RTL_QUERY_REGISTRY_TABLE)*2);
queries[0].Flags=RTL_QUERY_REGISTRY_DIRECT;
queries[0].Name=L". . .";
queries[0].EntryContext=&level;
queries[0].DefaultType=REG_DWORD ;
queries[0].DefaultData=&def;
queries[0].DefaultLength=sizeof(ULONG) ;

status=RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
L"\\Registry\\Machine\\Software\\. . . ",
queries, NULL, NULL);

Hope this helps.
zo...@memco.co.il

0 new messages