Discussion:
What is lpType
(too old to reply)
T
2020-01-02 17:30:18 UTC
Permalink
Hi All,

https://docs.microsoft.com/en-us/windows/win32/api/winreg/nf-winreg-regqueryvalueexw

I am confused as to what lpType is and does.

https://docs.microsoft.com/en-us/windows/win32/api/winreg/nf-winreg-regqueryvalueexw

LSTATUS RegQueryValueExW(
HKEY hKey,
LPCWSTR lpValueName,
LPDWORD lpReserved,
LPDWORD lpType,
LPBYTE lpData,
LPDWORD lpcbData
);

According to the link above:

lpType

A pointer to a variable that receives a code indicating
the type of data stored in the specified value. For a
list of the possible type codes, see Registry Value
Types. The lpType parameter can be NULL if the type
code is not required.

What exactly is lpType?

"Receives"? Them or me?

Is it incoming (I tell it something I want) or outgoing
(its tell me something) or both?

And if it is telling me something, what is it telling me?

Why does it only work if I "give" it a NULL? Give it
anything else and you get back "code 87 Invalid Parameter".

If I read it back after both a REG_SZ and REG_DWORD read,
I get a zero.

It would be nice if I got told what type of data I was reading back.

Your in confusion,
-T
R.Wieser
2020-01-02 18:19:31 UTC
Permalink
T,
Post by T
What exactly is lpType?
I've been trying to explain it to you. Have you read my previous reply ?
What didn't you understand from it ?

Strong suggestion:
Start with giving "lpType" a pointer to a variable just as you are doing it
for the the "lpcbData" argument.

Than, after you've called the function, take a peek at what gets written
into that variable.

Regards,
Rudy Wieser
T
2020-01-03 19:33:07 UTC
Permalink
Post by R.Wieser
T,
Post by T
What exactly is lpType?
I've been trying to explain it to you. Have you read my previous reply ?
What didn't you understand from it ?
It was not matching what I am seeing.
Post by R.Wieser
Start with giving "lpType" a pointer to a variable just as you are doing it
for the the "lpcbData" argument.
Than, after you've called the function, take a peek at what gets written
into that variable.
It is always 0. I did state that.
Post by R.Wieser
Regards,
Rudy Wieser
R.Wieser
2020-01-04 07:28:11 UTC
Permalink
T,
Post by T
It was not matching what I am seeing.
Thats not a problem. But without me (us) knowing /how/ it differs there is
no way I (we) can try to understand what happens and adjust our advice
accordingly.
Post by T
It is always 0. I did state that.
I'm sorry, but I have not seen you mention that you actually changed you
"just provide it a value" to a "lets try to receive a result". Hence, I
still assumed that you didn't.

If-and-when you have changed your code to actually receive a result than you
should get other values than Zero - as your posted link to the lpType
argument for thr RegQueryValueExW function shows. (do try to read other
registry keys with different data types !).

Suggestion: Initialize the variable with -1 (minus one) before calling the
function (its a value that should never be returned). If you than, after
calling it, still see that -1 you know that the function did not write
anything into that variable ...

If you than still see a Zero in that variable than that is what the function
returns, and you just need to figure out why (it /is/ a possible result).
But than do try to read other registry keys too (to see if they perhaps
return other values).

FWI: I just tried to run the first RegQueryValueEx( ) from the example code,
with its second NULL replaced by "&lpType" (after declaring the variable
ofcourse). I got the expected ERROR_MORE_DATA as a result code and the
lpType variable filled with a 3 (REG_BINARY) - which matches the returned
data (the first bytes of data are 'P' 0x00 'E' 0x00 'R' 0x00 'F' 0x00 - or
'PERF' in wide-string format).

One caveat though: I used Assembly instead of C{something}. /Should/ not
make a difference, but /could/ nevertheless.

Regards,
Rudy Wieser
T
2020-01-03 20:08:26 UTC
Permalink
Post by R.Wieser
T,
Post by T
What exactly is lpType?
I've been trying to explain it to you. Have you read my previous reply ?
What didn't you understand from it ?
Start with giving "lpType" a pointer to a variable just as you are doing it
for the the "lpcbData" argument.
Than, after you've called the function, take a peek at what gets written
into that variable.
Regards,
Rudy Wieser
Hi R.,

Figured it out. I forgot the "is rw" in the call.

-T
R.Wieser
2020-01-04 09:43:37 UTC
Permalink
T,
Post by T
Hi R.,
Figured it out. I forgot the "is rw" in the call.
:-| And I forgot to read all of your posts before writing my previous
reply. But, well done. :-)

Regards,
Rudy Wieser
T
2020-01-04 20:46:06 UTC
Permalink
Post by R.Wieser
T,
Post by T
Hi R.,
Figured it out. I forgot the "is rw" in the call.
:-| And I forgot to read all of your posts before writing my previous
reply. But, well done. :-)
Regards,
Rudy Wieser
Hi Rudy,

Is okay. I read every word and appreciated the help!
I am getting there slowly!

-T
JJ
2020-01-03 13:39:59 UTC
Permalink
Post by T
What exactly is lpType?
"l" is for "long". "p" is for "pointer". "Type" is the variable name which
represent the value it stores. So, it's a pointer to a variable of `long`
type.
Post by T
"Receives"? Them or me?
Is it incoming (I tell it something I want) or outgoing
(its tell me something) or both?
Remember that the function is an operation to query/read something. So, it
won't make sense if you're the one who give the information which you're
querying.
Post by T
And if it is telling me something, what is it telling me?
The documentation already describe it:
"... a code indicating the type of data stored in the specified value."
Post by T
Why does it only work if I "give" it a NULL? Give it
anything else and you get back "code 87 Invalid Parameter".
If I read it back after both a REG_SZ and REG_DWORD read,
I get a zero.
There's a high chance that the function fails. Thus the variable pointed by
`lpType` is irrelevant. The least chance is that the function succeeded, and
the registry value type is actually `REG_NONE`, but this is extremely rare.
T
2020-01-03 19:47:04 UTC
Permalink
Post by JJ
Post by T
What exactly is lpType?
"l" is for "long". "p" is for "pointer". "Type" is the variable name which
represent the value it stores. So, it's a pointer to a variable of `long`
type.
Hi JJ,

In Win API land, is that a 16, 32 or 64 bit variable?
Post by JJ
Post by T
"Receives"? Them or me?
Is it incoming (I tell it something I want) or outgoing
(its tell me something) or both?
Remember that the function is an operation to query/read something. So, it
won't make sense if you're the one who give the information which you're
querying.
Not to me. It is up in the air whether I am TELLING it
I want to read an REG_SZ or a REG_DWORD or it is telling
me what it did read. I presume from your answer that
receive means something is coming back to me.

By chance is the value coming back to me one of those
M$ special numbers where they reverse the bytes? 0xFF00 is
byte 1 = 0x55, byte 2 - 0x00? If I am only seeing the
leading byte, that would explain things
Post by JJ
Post by T
And if it is telling me something, what is it telling me?
"... a code indicating the type of data stored in the specified value."
I get a zero back, so I have no clue. I would adore
knowing if it was a REG_DWORD or a REG_SZ.
Post by JJ
Post by T
Why does it only work if I "give" it a NULL? Give it
anything else and you get back "code 87 Invalid Parameter".
If I read it back after both a REG_SZ and REG_DWORD read,
I get a zero.
There's a high chance that the function fails. Thus the variable pointed by
`lpType` is irrelevant. The least chance is that the function succeeded, and
the registry value type is actually `REG_NONE`, but this is extremely rare.
The function is return me back a zero (ERROR_SUCCESS)

:'(

Thank you for the help!

-T
JJ
2020-01-04 04:02:17 UTC
Permalink
Post by T
In Win API land, is that a 16, 32 or 64 bit variable?
32.
Post by T
Not to me. It is up in the air whether I am TELLING it
I want to read an REG_SZ or a REG_DWORD or it is telling
me what it did read. I presume from your answer that
receive means something is coming back to me.
For registry query operation, you don't tell what value type you want to
read.
Post by T
By chance is the value coming back to me one of those
M$ special numbers where they reverse the bytes? 0xFF00 is
byte 1 = 0x55, byte 2 - 0x00? If I am only seeing the
leading byte, that would explain things
I don't understand how 0xFF end up being 0x55 or vice versa. If you're
talking about endian, most registry value types uses little endian (i.e.
Intel format) except for one type which is specifically use big endian.
Post by T
I get a zero back, so I have no clue. I would adore
knowing if it was a REG_DWORD or a REG_SZ.
...
Post by T
The function is return me back a zero (ERROR_SUCCESS)
:'(
Check with Registry Editor. See what the actual value type is. FYI, only
shady softwares or incompetent software developers would store data using
REG_NONE type (I actually encountered such software, once).
T
2020-01-04 20:58:15 UTC
Permalink
Post by JJ
Post by T
In Win API land, is that a 16, 32 or 64 bit variable?
32.
Post by T
Not to me. It is up in the air whether I am TELLING it
I want to read an REG_SZ or a REG_DWORD or it is telling
me what it did read. I presume from your answer that
receive means something is coming back to me.
For registry query operation, you don't tell what value type you want to
read.
I am wring that one down. It was not clear if I was asking for
or receiving or both.
Post by JJ
Post by T
By chance is the value coming back to me one of those
M$ special numbers where they reverse the bytes? 0xFF00 is
byte 1 = 0x55, byte 2 - 0x00? If I am only seeing the
leading byte, that would explain things
I don't understand how 0xFF end up being 0x55 or vice versa. If you're
talking about endian, most registry value types uses little endian (i.e.
Intel format) except for one type which is specifically use big endian.
little-endian

Raku uses big-endian, so I have to convert them.

Apparently Registry UTF 16 "C" strings are also little-endian
Post by JJ
Post by T
I get a zero back, so I have no clue. I would adore
knowing if it was a REG_DWORD or a REG_SZ.
...
Post by T
The function is return me back a zero (ERROR_SUCCESS)
:'(
Check with Registry Editor. See what the actual value type is. FYI, only
shady softwares or incompetent software developers would store data using
REG_NONE type (I actually encountered such software, once).
REG_NONE. Yikes! I personally think the registry is a bad idea. I
think you should your settings in your own directory.
But, I don't get a vote on that one.

Thank you for all the tips!

-T
T
2020-01-03 20:07:49 UTC
Permalink
Post by JJ
Post by T
What exactly is lpType?
"l" is for "long". "p" is for "pointer". "Type" is the variable name which
represent the value it stores. So, it's a pointer to a variable of `long`
type.
Post by T
"Receives"? Them or me?
Is it incoming (I tell it something I want) or outgoing
(its tell me something) or both?
Remember that the function is an operation to query/read something. So, it
won't make sense if you're the one who give the information which you're
querying.
Post by T
And if it is telling me something, what is it telling me?
"... a code indicating the type of data stored in the specified value."
Post by T
Why does it only work if I "give" it a NULL? Give it
anything else and you get back "code 87 Invalid Parameter".
If I read it back after both a REG_SZ and REG_DWORD read,
I get a zero.
There's a high chance that the function fails. Thus the variable pointed by
`lpType` is irrelevant. The least chance is that the function succeeded, and
the registry value type is actually `REG_NONE`, but this is extremely rare.
Hi JJ,

Figured it out. I forgot the "is rw". Now I get back REG_SZ
and REG_DWORD as expected.

Thank you for the tips. I made me look at my call
with a different light and I found the error.

-T
JJ
2020-01-04 04:04:33 UTC
Permalink
Post by T
Hi JJ,
Figured it out. I forgot the "is rw". Now I get back REG_SZ
and REG_DWORD as expected.
Thank you for the tips. I made me look at my call
with a different light and I found the error.
-T
So? What was the error in the code?
T
2020-01-04 21:01:03 UTC
Permalink
Post by JJ
Post by T
Hi JJ,
Figured it out. I forgot the "is rw". Now I get back REG_SZ
and REG_DWORD as expected.
Thank you for the tips. I made me look at my call
with a different light and I found the error.
-T
So? What was the error in the code?
There was none. I forgot to tell the declaration
that the variable was read write, so I got back
whatever was in it to start with, which was a "C"
nul (a zero)

I am not writing this is C by the way, so it gets a
bit worky.
Kaz Kylheku
2020-01-04 21:07:30 UTC
Permalink
Post by JJ
Post by T
What exactly is lpType?
"l" is for "long". "p" is for "pointer". "Type" is the variable name which
represent the value it stores. So, it's a pointer to a variable of `long`
type.
That is incorrect!

The "long", believe it or not, refers to the pointer itself. It is a
"long pointer" to "Type".

For instance LPVOID is a "long pointer to void".

This dates back to 16 bit 8086 which supports pointers of different
sizes and ranges.

On 32 and 64 bit Windows, this has no meaning; all pointers are the
same.

LPVOID is just stands for "void *", for instance.

The source code is stuck with the naming convention, though.
--
TXR Programming Lanuage: http://nongnu.org/txr
Music DIY Mailing List: http://www.kylheku.com/diy
ADA MP-1 Mailing List: http://www.kylheku.com/mp1
Kaz Kylheku
2020-01-05 05:19:16 UTC
Permalink
Post by Kaz Kylheku
LPVOID is a "long pointer to void".
What is a "void"? A 0x0000 null?
void is a special type in C. It counts among the "incomplete types": a
category that includes structures/unions whose bodies have not been
declared, e.g. "struct foo;", and arrays of unknown length, e.g.
"extern int x[];".

Unlike incomplete arrays and structs, void cannot be completed.

When void is used as a function return type, it indicates that the
function returns nothing.

In C, the "void" keyword is used for prototyping an empty argument list,
as in "int main(void)", because the "()" declares a function without
any information about the arguments. C++ just makes that "int main()";
you can't declare a function in C++ without information about the
arguments.

When a pointer type is derived to void, as in "void *", that type has
certain mildly useful properties. It's used as a generic "pointer to any
object". C allows lax conversion rules: "void *" can be freely converted
to and from pointers to object types without casts (as long as
qualifiers (const, volatile) are not being stripped). C++ has slightly
stricter rules: it allows pointers to object types to convert to void *
without a cast, but not in the reverse direction.

ISO C requires that void * has the same representation as char *.
A void * pointer can point wherever a char * can point.

Moreover, a pointer to any object can convert to void *, and back to the
original type, such that it compares equal to the original value.

A number of standard library interfaces use void *, like the memcpy
function.

The void type has one traditional use: casting the value of a full
expression to void is used for indicating that its value is deliberately
being ignored. For instance:

(void) fclose(stream); /* close stream; don't care if it works */

And so that is void, in a nutshell.
T
2020-01-06 01:04:04 UTC
Permalink
Post by Kaz Kylheku
Post by Kaz Kylheku
LPVOID is a "long pointer to void".
What is a "void"? A 0x0000 null?
void is a special type in C. It counts among the "incomplete types": a
category that includes structures/unions whose bodies have not been
declared, e.g. "struct foo;", and arrays of unknown length, e.g.
"extern int x[];".
Unlike incomplete arrays and structs, void cannot be completed.
When void is used as a function return type, it indicates that the
function returns nothing.
In C, the "void" keyword is used for prototyping an empty argument list,
as in "int main(void)", because the "()" declares a function without
any information about the arguments. C++ just makes that "int main()";
you can't declare a function in C++ without information about the
arguments.
When a pointer type is derived to void, as in "void *", that type has
certain mildly useful properties. It's used as a generic "pointer to any
object". C allows lax conversion rules: "void *" can be freely converted
to and from pointers to object types without casts (as long as
qualifiers (const, volatile) are not being stripped). C++ has slightly
stricter rules: it allows pointers to object types to convert to void *
without a cast, but not in the reverse direction.
ISO C requires that void * has the same representation as char *.
A void * pointer can point wherever a char * can point.
Moreover, a pointer to any object can convert to void *, and back to the
original type, such that it compares equal to the original value.
A number of standard library interfaces use void *, like the memcpy
function.
The void type has one traditional use: casting the value of a full
expression to void is used for indicating that its value is deliberately
(void) fclose(stream); /* close stream; don't care if it works */
And so that is void, in a nutshell.
Hi Kaz,

Wow! Thank you!

I copied it down into my keepers file.

-T

Loading...