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
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
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.
(https://i.imgur.com/jOabwEX.jpg)
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.
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
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
still no error
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.
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
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...
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
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: