nechai
3rd July 2005 22:38 UTC
System::Call kernel32::GetPrivateProfileSectionNamesA
Hi,
I try to call 'kernel32::GetPrivateProfileSectionNamesA' with
'System::Call' to get all section names from an Inifile.
The API function returns a buffer with null-terminated strings.
I use the following code:
StrCpy $2 ${NSIS_MAX_STRLEN}
StrCpy $3 "Test.ini"
System::Call "kernel32::GetPrivateProfileSectionNamesA(t, i, t) i(.r1, r2, r3) .r4"
MessageBox MB_ICONEXCLAMATION|MB_OK "$1 $4"
$1 contains only the first section name. Is it possible to use something like shift on $1 to get the other parameters or does System::Call cut off itself the string at first nullchar.
Is there a way to use GetPrivateProfileSectionNamesA in NSIS or should I better use FileOpen, FileRead?
thx
nethai
Joel
3rd July 2005 23:47 UTC
You'll have to parse the return buffer so you can extract eache section name... remember, the delimiter is the null string (\0)
nechai
4th July 2005 19:35 UTC
Originally posted by Joel
You'll have to parse the return buffer so you can extract eache section name... remember, the delimiter is the null string (\0)
That was my problem: how to parse the buffer. I have found a pattern in GetDrives in NSIS Wiki and adapted it for GetPrivateProfileSectionNamesA.
I am not sure what I should free with System::Free.
The buffer pointer $2 in the original GetDrives is increased by each length of null-terminated string and finally freed with 'System::Free $2' ($2 pointed to the last /0 in buffer), but this itn't the alloced memory at the beginning 'System::Alloc 1024'. Is it a bug in GetDrives or do I misinterpret the use of System::Alloc / System::Free.
Function GetSectionNames
; Based on the method to loop over an array of
; null-terminated strings in function "GetDrives"
;
; Syntax:
; ${GetSectionNames} "File" "Function"
;
; "File" ; name of the initialization file
; "Function" ; Callback function then found
;
; Function "Function"
; ; $9 "section name"
;
; ; $R0-$R9 are not used (save data in them).
; ; ...
;
; Push $var ; If $var="GetSectionNames" Then exit from function
; FunctionEnd
!define GetSectionNames `!insertmacro GetSectionNamesCall`
!macro GetSectionNamesCall _FILE _FUNC
Push $0
Push `${_FILE}`
GetFunctionAddress $0 `${_FUNC}`
Push `$0`
Call GetSectionNames
Pop $0
!macroend
Exch $1
Exch
Exch $0
Exch
Push $2
Push $3
Push $4
Push $5
Push $8
Push $9
System::Alloc 1024
Pop $2
StrCpy $3 $2
System::Call "kernel32::GetPrivateProfileSectionNamesA(i, i, t) i(r3, 1024, r0) .r4"
enumok:
System::Call 'kernel32::lstrlenA(t) i(i r3) .r5'
StrCmp $5 '0' enumex
System::Call '*$3(&t1024 .r9)'
Push $0
Push $1
Push $2
Push $3
Push $4
Push $5
Push $8
Call $1
Pop $9
Pop $8
Pop $5
Pop $4
Pop $3
Pop $2
Pop $1
Pop $0
StrCmp $9 'GetSectionNames' enumex
enumnext:
IntOp $3 $3 + $5
IntOp $3 $3 + 1
goto enumok
enumex:
System::Free $2
Pop $9
Pop $8
Pop $5
Pop $4
Pop $3
Pop $2
Pop $1
Pop $0
FunctionEnd
nechai
4th July 2005 21:20 UTC
Originally posted by nechai
Function GetSectionNames
; Based on the method to loop over an array of
; null-terminated strings in function "GetDrives"
;
; Syntax:
; ${GetSectionNames} "File" "Function"
FunctionEnd [/B]
I have created two entries in the wiki.
Get all entries in section of INI fileGet all section names of INI fileInstructor
4th July 2005 23:54 UTC
Is it a bug in GetDrives or do I misinterpret the use of System::Alloc / System::Free.
You are right.
Fixed: "GetDrives" Alloc/Free. Thanks!
brainsucker
5th July 2005 08:57 UTC
Hey guys, haven't you got tired of all this endless pops pushes and exchanges? If you are using System::Alloc/Free/Call, then why don't use System::Store?
Strange for me :) You scripts will become much more beautiful and smaller.
Instructor
5th July 2005 10:22 UTC
I think it's not very good idea to use /NOUNLOAD flag in function. For example:
System::Store /NOUNLOAD "s"
quit
System::Store "l"
Not delete temp folder with system.dll
Will be interesting :) if it will be able to use something like:
System::Push "s"
Pop $0 #Pointer to stack
System::Pop "$0"
deguix
10th July 2005 07:48 UTC
Hey guys, haven't you got tired of all this endless pops pushes and exchanges? If you are using System::Alloc/Free/Call, then why don't use System::Store?
It can pop and push, but it can't exch. This complicates a little bit the clarity of functions.