News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

Read Registry keys

Started by Amadeus, April 06, 2022, 08:15:57 AM

Previous topic - Next topic

Amadeus

Hi guys,
i am trying to read two keys from registry, but i dunno why it reads only one the second gets not read, and no error is given.

Any help is appreciated.
Thanks in advance
Amadeus

PS: this is the code i use


buffsize    dd 256

subkey db "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0",0
ProcName      db 'ProcessorNameString',0

ProcID      db "Identifier",0

szREGSZ         db 'REG_SZ',0
szREGMULTISZ db 'REG_MULTI_SZ',0,0

.const
CR equ 13
LF equ 10

.data?

hKey        dd ?
buffer      db 256 dup(?)
szProcName db 256 dup(?)
szProcID db 256 dup(?)

.code

start:


invoke RtlZeroMemory,addr buffer,256

push offset buffer
call GetProcName

invoke crt_printf,chr$("ProcessorNameString is:  %s",CR,LF,CR,LF),addr buffer


;#########################################################################
invoke wait_key
    invoke ExitProcess, 0
   

.code

GetProcId proc _ProcBuffer:dword

    invoke RegOpenKeyEx,HKEY_LOCAL_MACHINE,addr subkey,0,KEY_READ,addr hKey
.if eax == ERROR_SUCCESS
invoke RegQueryValueEx,hKey,addr ProcID,0,addr szREGSZ, _ProcBuffer,addr buffsize
.endif
invoke  RegCloseKey,hKey

ret
GetProcId endp

GetProcName proc _ProcBuffer:dword

    invoke RegOpenKeyEx,HKEY_LOCAL_MACHINE,addr subkey,0,KEY_READ,addr hKey
.if eax == ERROR_SUCCESS
invoke RegQueryValueEx,hKey,addr ProcName,0,addr szREGSZ, _ProcBuffer,addr buffsize
.endif
invoke  RegCloseKey,hKey

ret
GetProcName endp


end start

jj2007

      push offset buffer
      call GetProcId
      invoke   crt_printf,chr$("ProcessorID is:          %s", CR,LF),addr buffer

      push offset buffer
      call GetProcName      
      invoke   crt_printf,chr$("ProcessorNameString is:  %s",CR,LF,CR,LF),addr buffer

Amadeus

Hello JJ2007, thanks for the answer.

Maybe i explained it wrong, what i want is to get the two keys in one run
but it returns only one key the Identifier from the first call

on the second call for get the ProcessorNameString the buffer stays empty, no error just empty

don't know why the second call don't populate the buffer.


jj2007

For me, adding the blue part above works perfectly. Check with regedit whether ProcessorNameString is present in your registry.

Note that your code above did not contain a second call. Just one... no wonder you won't see anything.

Amadeus

Sorry JJ, just a bloody C/P error
anyway as you can see fro picture above second call remain empty


.code

start:

push offset buffer
call GetProcId
invoke crt_printf,chr$("Identifier is:  %s",CR,LF),addr buffer




invoke RtlZeroMemory,addr buffer,256

push offset buffer
call GetProcName

invoke crt_printf,chr$("ProcessorNameString is:  %s",CR,LF),addr buffer



;#########################################################################
invoke wait_key
    invoke ExitProcess, 0

GetProcId proc _ProcBuffer:dword
LOCAL _hKey:dword

    invoke RegOpenKeyEx,HKEY_LOCAL_MACHINE,addr subkey,0,KEY_READ,addr hKey
.if eax == ERROR_SUCCESS
invoke MessageBox,0,chr$("ERROR_SUCCESS call1"),chr$("INFO"),MB_OK
invoke RegQueryValueEx,hKey,addr ProcID,0,addr szREGSZ, _ProcBuffer,addr buffsize
.endif
invoke  RegCloseKey,hKey

ret
GetProcId endp

GetProcName proc _ProcBuffer:dword
LOCAL _hKey:dword

    invoke RegOpenKeyEx,HKEY_LOCAL_MACHINE,addr subkey,0,KEY_READ,addr hKey
.if eax == ERROR_SUCCESS
invoke MessageBox,0,chr$("ERROR_SUCCESS call2"),chr$("INFO"),MB_OK
invoke RegQueryValueEx,hKey,addr ProcName,0,addr szREGSZ, _ProcBuffer,addr buffsize
.endif
invoke  RegCloseKey,hKey

ret
GetProcName endp


end start


jj2007

So what does GetLastError report, in both cases?

invoke SetLastError, 0  ; some API calls don't set error 0, so it's better to do that
... your call ...
.if rv(GetLastError)
   print str$(eax), " error", 13, 10
.endif

Amadeus


jj2007

Quote from: Amadeus on April 06, 2022, 10:51:49 PM
still no error

Please zip your complete source and executable and attach it to your next post.

Amadeus

Quote from: jj2007 on April 07, 2022, 12:14:33 AM

Please zip your complete source and executable and attach it to your next post.

here it is
thanks for your time JJ

jj2007

Ok... it fails in RegQueryValueEx with ERROR_MORE_DATA.

Problem solved (and it's not obvious from the doc - not your fault, it's lousy Micros**t documentation):
GetProcId proc _ProcBuffer:dword
LOCAL _hKey:dword
    invoke RegOpenKeyEx,HKEY_LOCAL_MACHINE,addr subkey,0,KEY_QUERY_VALUE,addr hKey
.if eax == ERROR_SUCCESS
invoke [url=https://docs.microsoft.com/en-us/windows/win32/api/winreg/nf-winreg-regqueryvalueexa]RegQueryValueEx[/url],hKey,addr ProcID,0,addr szREGSZ, _ProcBuffer, addr buffsize
.if eax!=ERROR_SUCCESS
invoke MessageBox,0,str$(eax),chr$("GetProcId: RegQueryValueEx error"),MB_OK
.endif
.else
invoke MessageBox,0,str$(rv(GetLastError)),chr$("GetProcID error"),MB_OK
.endif
invoke  RegCloseKey,hKey

ret
GetProcId endp

GetProcName proc _ProcBuffer:dword
LOCAL _hKey:dword
    invoke RegOpenKeyEx,HKEY_LOCAL_MACHINE,addr subkey,0,KEY_QUERY_VALUE,addr hKey
.if eax == ERROR_SUCCESS
mov buffsize, 256 ; *********** this solved the problem **************
invoke RegQueryValueEx,hKey,addr ProcName,0,addr szREGSZ, _ProcBuffer,addr buffsize
.if eax!=ERROR_SUCCESS
invoke MessageBox,0,str$(eax),chr$("GetProcName: RegQueryValueEx error"),MB_OK
.endif
.else
invoke MessageBox,0,str$(rv(GetLastError)),chr$("GetProcName error"),MB_OK
.endif
invoke  RegCloseKey,hKey
ret
GetProcName endp


What happens is that Windows sets the buffsize variable to the size of the buffer required for the first call. Which, at first sight, it should do only if the call fails:
QuoteIf the buffer specified by lpData parameter is not large enough to hold the data, the function returns ERROR_MORE_DATA and stores the required buffer size in the variable pointed to by lpcbData. In this case, the contents of the lpData buffer are undefined.

However, further up, and easy to overlook, this phrase:
Quote[in, out, optional] lpcbData

A pointer to a variable that specifies the size of the buffer pointed to by the lpData parameter, in bytes. When the function returns, this variable contains the size of the data copied to lpData.

The phrase and stores the required buffer size in the variable pointed to by lpcbData is misleading. It always stores the number of bytes copied there; and since the first string is shorter than the second one, you are in trouble...

Amadeus

ok changing the order works.
A tip how it can work the way i want would be appreciated
Prefer Identifer first, then Processorname

edit: Just foud it out

Many thanks @JJ2007

jj2007

Quote from: Amadeus on April 07, 2022, 03:43:34 AM
ok changing the order works.

Yes, because then the longer string comes first, so the bufsize is ok for the shorter one.

QuoteMany thanks @JJ2007

My pleasure, Amadeus :thup: