News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Write a section to the registry

Started by skywalker, March 10, 2006, 06:39:37 PM

Previous topic - Next topic

skywalker

I appreciate all the help I have gotten. I looked around and pasted some of the help.

I would like to write my own section to the registry and then put some values in.

(I found a GetProfileInt API, but none with the A on the end.)

Thanks.


BOOL WritePrivateProfileString(

    LPCTSTR lpAppName,   // pointer to section name
    LPCTSTR lpKeyName,   // pointer to key name
    LPCTSTR lpString,   // pointer to string to add
    LPCTSTR lpFileName    // pointer to initialization filename
   );

;local   @szBuffer[512]:byte
;
;invoke  WritePrivateProfileString,addr szSec,addr szKey,addr @szBuffer,addr szProfileName

Code:
invoke GetProfileIntA,"MyApp","Counter",1
inc eax ; add 1 to the counter
mov [count],eax
invoke dw2a,offset counter,[count]
invoke WriteProfileStringA,"MyApp","Counter",offset counter
If the section and key do not exist they will be created.

Tedd

QuoteThe WriteProfileString function copies a string into the specified section of the WIN.INI file.

This function is provided for compatibility with 16-bit Windows-based applications. Win32-based applications should store initialization information in the registry.

You'll want RegCreateKey instead :wink


most of the functions you use end with an 'A' (Ansi) - but it's only to distinguish them internally from the ones ending with 'W' (Wide - sort of not unicode) -- the number of parameters and use is the same for both versions, so the help file simply lists them without the A or W.
..meaning GetProfileInt is the same as GetProfileIntA :wink (and same for WriteProfileString)
No snowflake in an avalanche feels responsible.

skywalker

Quote from: Tedd on March 10, 2006, 06:50:37 PM
QuoteThe WriteProfileString function copies a string into the specified section of the WIN.INI file.

This function is provided for compatibility with 16-bit Windows-based applications. Win32-based applications should store initialization information in the registry.

You'll want RegCreateKey instead :wink

Thanks. This is what I have been able to come up with so far. I am thinking I need the A ones.

most of the functions you use end with an 'A' (Ansi) - but it's only to distinguish them internally from the ones ending with 'W' (Wide - sort of not unicode) -- the number of parameters and use is the same for both versions, so the help file simply lists them without the A or W.
..meaning GetProfileInt is the same as GetProfileIntA :wink (and same for WriteProfileString)

: The best source of information is MSDN:
:
: From here:
:
: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winprog/winprog/functions_by_category.asp
:
: click on 'Registry'.
:
: To do it in ASM simply PUSH all parameters in opposite order and CALL the function. Keep in mind that this function has two names:
:
: RegCreateKeyExW - for UNICODE build
: RegCreateKeyExA - for ANSI build
:
:

Thanks.

I found this at their site, it is the same as is in the Win32.hlp file
that I referece first for API calls. The info MS provides assumes the reader has a lot more knowledge and a level of previous programming ability that I don't have yet. I am learning and practicing though.

I'd like to create a key in HKEY_CURRENT_USER.


LONG RegCreateKeyEx(
HKEY hKey,
LPCTSTR lpSubKey,
DWORD Reserved,
LPTSTR lpClass,
DWORD dwOptions,
REGSAM samDesired,
LPSECURITY_ATTRIBUTES lpSecurityAttributes,
PHKEY phkResult,
LPDWORD lpdwDisposition
);

Parameters

hKey
[in] Handle to an open key. The calling process must have KEY_CREATE_SUB_KEY access to the key. For more information, see Registry Key Security and Access Rights.

This handle is returned by the RegCreateKeyEx or RegOpenKeyEx function, or it can be one of the following predefined keys:

HKEY_CLASSES_ROOT
HKEY_CURRENT_CONFIG
HKEY_CURRENT_USER
HKEY_LOCAL_MACHINE
HKEY_USERS

Pawel Blaszczyk

Hi Everybody!

I wrote following code especially for you :wink:

.386
.MODEL FLAT, STDCALL
OPTION CASEMAP: NONE

Include windows.inc

Include user32.inc
includelib user32.lib

include kernel32.inc
includelib kernel32.lib

include advapi32.inc
includelib advapi32.lib

.DATA
SubKey BYTE "MyAppKey",0 ;name of sub key in HKEY_CURRENT_USER
CreateOK BYTE "Reg key creating OK",0 ; for report
ValueOK BYTE "Adding registry val. OK",0 ; -||-
Sample BYTE "Sample",0 ; -||-
NewRegValue BYTE "My App's Digit",0 ; Value name
Digit DWORD 1234 ; This variable will be put to the registry

.DATA?
RegH PHKEY ? ; Handle for reg. key

.CODE
Start:

invoke RegCreateKey, HKEY_CURRENT_USER, ADDR SubKey, ADDR RegH ;Create key
.IF EAX == ERROR_SUCCESS ; Error checking
; Code executed, if function succeeds
invoke MessageBox, 0, ADDR CreateOK, ADDR Sample, MB_ICONINFORMATION
invoke RegSetValueEx, RegH, ADDR NewRegValue, 0, REG_DWORD, ADDR Digit, 4
.IF EAX == ERROR_SUCCESS
invoke MessageBox, 0, ADDR ValueOK, ADDR Sample,MB_ICONINFORMATION
.ENDIF
.ELSE
; Code if create function fails
.ENDIF

invoke RegCloseKey, ADDR RegH

invoke ExitProcess, 0

END Start


I hope it is what you wanted to do. :U

donkey

If you only want to write a value to the registry there are simple wrapper functions in SHLWAPI that make the job pretty easy...

Write key - SHSetValue

mov cbData, SIZEOF Data
invoke SHSetValue,HKEY_CURRENT_USER,OFFSET SubKey,offset value,REG_SZ,offset Data,cbData


Read key - SHGetValue

invoke SHGetValue,HKEY_CURRENT_USER,OFFSET SubKey,offset value,offset dwType,offset Data,offset cbData

For simple registry reads (ie one value) and writes these are more than adequate, however if you are reading multiple values from the same key then it is preferable to open a key and read the values.
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable

skywalker

Quote from: programmer1989 on March 11, 2006, 01:01:30 PM
Hi Everybody!

I wrote following code especially for you :wink:

.386
.MODEL FLAT, STDCALL
OPTION CASEMAP: NONE

Include windows.inc

Include user32.inc
includelib user32.lib

include kernel32.inc
includelib kernel32.lib

include advapi32.inc
includelib advapi32.lib

.DATA
SubKey BYTE "MyAppKey",0 ;name of sub key in HKEY_CURRENT_USER
CreateOK BYTE "Reg key creating OK",0 ; for report
ValueOK BYTE "Adding registry val. OK",0 ; -||-
Sample BYTE "Sample",0 ; -||-
NewRegValue BYTE "My App's Digit",0 ; Value name
Digit DWORD 1234 ; This variable will be put to the registry

.DATA?
RegH PHKEY ? ; Handle for reg. key

.CODE
Start:

invoke RegCreateKey, HKEY_CURRENT_USER, ADDR SubKey, ADDR RegH ;Create key
.IF EAX == ERROR_SUCCESS ; Error checking
; Code executed, if function succeeds
invoke MessageBox, 0, ADDR CreateOK, ADDR Sample, MB_ICONINFORMATION
invoke RegSetValueEx, RegH, ADDR NewRegValue, 0, REG_DWORD, ADDR Digit, 4
.IF EAX == ERROR_SUCCESS
invoke MessageBox, 0, ADDR ValueOK, ADDR Sample,MB_ICONINFORMATION
.ENDIF
.ELSE
; Code if create function fails
.ENDIF

invoke RegCloseKey, ADDR RegH

invoke ExitProcess, 0

END Start


I hope it is what you wanted to do. :U

Thanks, I'll compile it and let you know how it went.


AsmER

Hi Everybody!

Pawel your code work correct, but you forgot tell Skywalker, about some things that are important (I think):

1.)   4th parameter of RegSetValueEx depends from what programmer want to store in registry.
For other data types this argument should be like follows:
REG_BINARY   Binary data in any form.

REG_DWORD   A 32-bit number.

REG_DWORD_LITTLE_ENDIAN   A 32-bit number in little-endian format (same as REG_DWORD). In little-endian format, the most significant byte of a word is the high-order byte. This is the most common format for computers running Windows NT and Windows 95.

REG_DWORD_BIG_ENDIAN   A 32-bit number in big-endian format. In big-endian format, the most significant byte of a word is the low-order byte.

REG_EXPAND_SZ   A null-terminated string that contains unexpanded references to environment variables (for example, "%PATH%"). It will be a Unicode or ANSI string depending on whether you use the Unicode or ANSI functions.

REG_LINK   A Unicode symbolic link.

REG_MULTI_SZ   An array of null-terminated strings, terminated by two null characters.

REG_NONE   No defined value type.

REG_RESOURCE_LIST   A device-driver resource list.

REG_SZ   A null-terminated string. It will be a Unicode or ANSI string depending on whether you use the Unicode or ANSI functions.

2.)   To read previously saved data from the registry we can use RegQueryValueEx:
LONG RegQueryValueEx(

    HKEY hKey,   // handle of key to query
    LPTSTR lpValueName,   // address of name of value to query
    LPDWORD lpReserved,   // reserved (must be zero )
    LPDWORD lpType,   // address of buffer for value type.
    LPBYTE lpData,   // address of data buffer, which will contain read data
    LPDWORD lpcbData    // address of data buffer size
   );

Regards, AsmER

skywalker

Quote from: programmer1989 on March 11, 2006, 01:01:30 PM
Hi Everybody!

I wrote following code especially for you :wink:

.386
.MODEL FLAT, STDCALL
OPTION CASEMAP: NONE

Include windows.inc

Include user32.inc
includelib user32.lib

include kernel32.inc
includelib kernel32.lib

include advapi32.inc
includelib advapi32.lib

.DATA
SubKey BYTE "MyAppKey",0 ;name of sub key in HKEY_CURRENT_USER
CreateOK BYTE "Reg key creating OK",0 ; for report
ValueOK BYTE "Adding registry val. OK",0 ; -||-
Sample BYTE "Sample",0 ; -||-
NewRegValue BYTE "My App's Digit",0 ; Value name
Digit DWORD 1234 ; This variable will be put to the registry

.DATA?
RegH PHKEY ? ; Handle for reg. key

.CODE
Start:

invoke RegCreateKey, HKEY_CURRENT_USER, ADDR SubKey, ADDR RegH ;Create key
.IF EAX == ERROR_SUCCESS ; Error checking
; Code executed, if function succeeds
invoke MessageBox, 0, ADDR CreateOK, ADDR Sample, MB_ICONINFORMATION
invoke RegSetValueEx, RegH, ADDR NewRegValue, 0, REG_DWORD, ADDR Digit, 4
.IF EAX == ERROR_SUCCESS
invoke MessageBox, 0, ADDR ValueOK, ADDR Sample,MB_ICONINFORMATION
.ENDIF
.ELSE
; Code if create function fails
.ENDIF

invoke RegCloseKey, ADDR RegH

invoke ExitProcess, 0

END Start


I hope it is what you wanted to do. :U

Thanks.

Your code worked fine. Here is some code that is supposed to delete the key that I created from a modification
of your code. I am getting an error saying that some function is supposed to be in block 1 or something like that.



; delkey.asm Delete a registry key
;            Help from Programmer 1989,
.386
.MODEL FLAT, STDCALL
OPTION CASEMAP: NONE


    include \masm32\include\windows.inc
    include \masm32\include\user32.inc
    include \masm32\include\kernel32.inc
    include \masm32\include\advapi32.inc

    include \masm32\macros\macros.asm

    includelib  \masm32\lib\kernel32.lib
    includelib  \masm32\lib\user32.lib
    includelib  \masm32\lib\advapi32.lib


.DATA

SubKey BYTE "Marzipan",0 ;name of sub key in HKEY_CURRENT_USER
Key_Deleted BYTE "Register key sucessfully deleted.",0

.DATA?

RegH PHKEY ? ; Handle for reg. key

.CODE

Start:

jmp begin ; temporary Cliff notes

invoke RegCreateKey, HKEY_CURRENT_USER, ADDR SubKey, ADDR RegH ;Create key
.IF EAX == ERROR_SUCCESS ; Error checking
; Code executed, if function succeeds
invoke MessageBox, 0, ADDR CreateOK, ADDR Sample, MB_ICONINFORMATION

invoke RegSetValueEx, RegH, ADDR NewRegValue, 0, REG_DWORD, ADDR Digit, 4
.IF EAX == ERROR_SUCCESS
invoke MessageBox, 0, ADDR ValueOK, ADDR Sample,MB_ICONINFORMATION
.ENDIF
.ELSE
; Code if create function fails
.ENDIF

begin:

; Open the key we want to delete

invoke RegOpenKey,RegH,ADDR SubKey,ADDR RegH

invoke RegDeleteKey,HKEY_CURRENT_USER, ADDR SubKey

; Sucess or failure section
;
.IF EAX == ERROR_SUCCESS
invoke MessageBox, 0, ADDR Key_Deleted, ADDR Sample,MB_ICONINFORMATION
.ENDIF
.ELSE
; Code if function fails
.ENDIF

invoke RegCloseKey, ADDR RegH ; close handle for reg. key


invoke ExitProcess, 0

END Start


skywalker

Quote from: AsmER on March 11, 2006, 02:48:51 PM
Hi Everybody!

Pawel your code work correct, but you forgot tell Skywalker, about some things that are important (I think):

1.)   4th parameter of RegSetValueEx depends from what programmer want to store in registry.
For other data types this argument should be like follows:
REG_BINARY   Binary data in any form.

REG_DWORD   A 32-bit number.

REG_DWORD_LITTLE_ENDIAN   A 32-bit number in little-endian format (same as REG_DWORD). In little-endian format, the most significant byte of a word is the high-order byte. This is the most common format for computers running Windows NT and Windows 95.

REG_DWORD_BIG_ENDIAN   A 32-bit number in big-endian format. In big-endian format, the most significant byte of a word is the low-order byte.

REG_EXPAND_SZ   A null-terminated string that contains unexpanded references to environment variables (for example, "%PATH%"). It will be a Unicode or ANSI string depending on whether you use the Unicode or ANSI functions.

REG_LINK   A Unicode symbolic link.

REG_MULTI_SZ   An array of null-terminated strings, terminated by two null characters.

REG_NONE   No defined value type.

REG_RESOURCE_LIST   A device-driver resource list.

REG_SZ   A null-terminated string. It will be a Unicode or ANSI string depending on whether you use the Unicode or ANSI functions.

2.)   To read previously saved data from the registry we can use RegQueryValueEx:
LONG RegQueryValueEx(

    HKEY hKey,   // handle of key to query
    LPTSTR lpValueName,   // address of name of value to query
    LPDWORD lpReserved,   // reserved (must be zero )
    LPDWORD lpType,   // address of buffer for value type.
    LPBYTE lpData,   // address of data buffer, which will contain read data
    LPDWORD lpcbData    // address of data buffer size
   );

Regards, AsmER


Thanks for all the extra info.

So if I understand part of what you've listed , I can also use RegSetValueEx to store strings as well in the registry?

Eventually I would like to learn to modify what's already in the created key.

Can the string contain all available characters? (i.e. control chars as well meaning all 256 characters that were
available under DOS)




Mincho Georgiev

Hi!
I have write several examples in this forum related to the registry. skywalker, if you like, you can use my registry_access module. This is an updated version since i had last post it.



[attachment deleted by admin]

AsmER

Hi!

Yes Skywalker, you can store text, binary and other data types and use all available characters.
There is anwser for question: 'How to delete reg. key':


; delkey.asm Delete a registry key
;            Help from Programmer 1989,
.386
.MODEL FLAT, STDCALL
OPTION CASEMAP: NONE


    include \masm32\include\windows.inc
    include \masm32\include\user32.inc
    include \masm32\include\kernel32.inc
    include \masm32\include\advapi32.inc

    include \masm32\macros\macros.asm

    includelib  \masm32\lib\kernel32.lib
    includelib  \masm32\lib\user32.lib
    includelib  \masm32\lib\advapi32.lib


.DATA

SubKey BYTE "Marzipan",0 ;name of sub key in HKEY_CURRENT_USER
Key_Deleted BYTE "Register key sucessfully deleted.",0

.DATA?

RegH PHKEY ? ; Handle for reg. key

.CODE

Start:
jmp begin:
...
begin:
; Open the key we want to delete

;invoke RegOpenKey,HKEY_CURRENT_USER,ADDR SubKey,ADDR RegH          ; actually this instruction is NOT required
invoke RegDeleteKey,HKEY_CURRENT_USER, ADDR SubKey

; Sucess or failure section
;
.IF EAX == ERROR_SUCCESS
invoke MessageBox, 0, ADDR Key_Deleted, ADDR Sample,MB_ICONINFORMATION
.ELSE
; if failed
.ENDIF

invoke RegCloseKey, ADDR RegH ; close handle for reg. key


invoke ExitProcess, 0

END Start

That is it :dance: But you must remember that registry key which you deleting CAN NOT contain any subkeys. :wink

Regards, AsmER.

Mark Jones

Skywalker, please don't quote everything a previous poster has said every time. It is very easy for all of us to just scroll up and re-read something if needed. We'll know what you're talking about without the quotes. And quoting entire posts is redundant and wasteful of system resources. :wink
"To deny our impulses... foolish; to revel in them, chaos." MCJ 2003.08

PBrennick

AsmER

Start:
jmp begin:     ; <===   The colon needs to be removed and there should be a semicolon at the start of the next line
...
begin:


Also, in the data section, Sample is no declared.

Paul
The GeneSys Project is available from:
The Repository or My crappy website

skywalker

Quote from: Mark Jones on March 11, 2006, 07:51:08 PM
Skywalker, please don't quote everything a previous poster has said every time. It is very easy for all of us to just scroll up and re-read something if needed. We'll know what you're talking about without the quotes. And quoting entire posts is redundant and wasteful of system resources. :wink

Sorry.


skywalker

Quote
That is it :dance: But you must remember that registry key which you deleting CAN NOT contain any subkeys. :wink

Regards, AsmER.

From what I understand, I can delete nested keys 3 or 4 levels deep as long as I delete them one at a time.
I can't figure out how to add another sub-directory  to my code.