Pelles C forum

Assembly language => Assembly discussions => Topic started by: HellOfMice on December 15, 2024, 08:04:44 PM

Title: GetPrivateProfileString
Post by: HellOfMice on December 15, 2024, 08:04:44 PM
Hekko


I call GetPrivateProfileString and if the key is empty or not found it would return the default value.
In my case the default value is "0" define as a string
GetPrivateProfileString Returns 0 and GetLastError too


I join the file of my debugging session


Has someone an idea?
Title: Re: GetPrivateProfileString
Post by: HellOfMice on December 15, 2024, 08:11:06 PM
It would seem that if the key exist but has no value assigned to it the function returns a null string and GetPrivateProfileString returns 0. >:(
Title: Re: GetPrivateProfileString
Post by: John Z on December 15, 2024, 09:39:55 PM
Hi HellOfMice,

Not sure of the issue but here are examples of what I do

RetVal = GetPrivateProfileStringW(L"StartUp", L"ShowSplash", L"0", IniString, 254, p_inifile);
   StartUp.Show_Splash = _wtoi(IniString);

   RetVal = GetPrivateProfileStringW(L"StartUp", L"EscFileCnt", L"500", IniString, 254, p_inifile);
   StartUp.EscFileCnt = _wtoi(IniString);

The value that is returned, when no value is found, is the value in parameter 3, as a string...
There is also GetPrivateProfileIntW if you don't want to mess with _wtoi, it works the same way...
John Z
Title: Re: GetPrivateProfileString
Post by: HellOfMice on December 16, 2024, 02:26:44 AM
Hi John,

The case I found is an existing key with no value

                        mov     [rsp + 40],rsi
                            mov     DWORD PTR [rsp + 32],SIZEOF KID_WINDOW.Dlg_Style
                            lea     r9,[rbx].KID_WINDOW.Dlg_Style
                            lea     r8,szZeroString + rip
                            lea     rdx,szRC_Item_0020 + rip
                            mov     rcx,rdi
                            call    GetPrivateProfileString

                            test    eax,eax
                            jnz     @F

                            lea     rcx,[rbx].KID_WINDOW.Dlg_Style
                            lea     rdx,szZeroString + rip
                            call    lstrcpy
;-----------------------------------------------------------------------------------------------------
                            ALIGN   16
;-----------------------------------------------------------------------------------------------------
@@ :


The only way to solve this case is the one above.
Quote[Dialog Box #3]
ExStyle Present=0
Style Present=1
Caption Present=1
Menu Present=0
Class Present=1
Font Present=1
Number Of Controls=1
Dialog Font Name=MS Shell Dlg
Dialog Font Size=8
Dialog Font Weight=0
Dialog Font Italic=0
Dialog Font Charset=1
Dialog Window X=6
Dialog Window Y=18
Dialog Window Width=195
Dialog Window Height=195
Dialog Menu ID=
Dialog Id=DLG_MAIN
Dialog Style=DS_SHELLFONT|DS_MODALFRAME|DS_3DLOOK|WS_THICKFRAME|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX|WS_MAXIMIZEBOX|WS_VISIBLE
Dialog ExStyle=
Dialog Caption=Dialog Program
Dialog Class=DialogClass
Here there is no menu ID and no extended style
They are strings but th string is not found I want "0"
For having this result I must delete the key before or if the string is empty I sound not call WritePrivateProfileString

Thank You John for your help, remarks and ideas.

Philippe
Title: Re: GetPrivateProfileString
Post by: TimoVJL on December 16, 2024, 09:39:06 AM
check with GetLastError() if key exists ?
Title: Re: GetPrivateProfileString
Post by: John Z on December 16, 2024, 10:46:30 AM
Hi HellOfMice,

It is interesting:  I set edited my ini to be:
[Settings]
MaxCards=500
MainLeft=
MainTop=
MainWidth=727
MainHeight=526
DarkMode=0

[Display]
HideTools=
 
So three entries with no value. Then I just run the program - the window is drawn starting at 0,0.
Even though no value in the ini file. and the default values for the window as shown below are not 0,0

//size parameters from the ini
RetVal = GetPrivateProfileStringW(p_tmp, L"MainLeft", L"10",INIString,200, p_file);
MainForm.left= _wtoi(INIString);

RetVal = GetPrivateProfileStringW(p_tmp, L"MainTop", L"30",INIString,100, p_file);
MainForm.top= _wtoi(INIString);

RetVal = GetPrivateProfileStringW(p_tmp, L"HideTools", L"0", INIString,100,p_file);
StartUp.Hide_Toolbar = _wtoi(INIString);

So in C code it seems to be doing what you are wanting.  Key Found, but empty, return 0

Perhaps in C the values are all ZERO when the INIStart structure is created?

So loading a default 0 into the storage of each INI entry might get you where you want to be?
Then if it fails that entry will have the 0.

John Z
Title: Re: GetPrivateProfileString
Post by: HellOfMice on December 16, 2024, 10:48:49 AM
If the entry is deleted before, I get the default value.
Title: Re: GetPrivateProfileString
Post by: HellOfMice on December 16, 2024, 02:55:28 PM
John, you should check the RetVal value, must contain the number of characters returned
Title: Re: GetPrivateProfileString
Post by: Vortex on December 16, 2024, 03:20:26 PM
Hi Philippe,

Could you post the complete source code if possible?
Title: Re: GetPrivateProfileString
Post by: HellOfMice on December 16, 2024, 03:24:22 PM

Ok VortexThis is the current project
Title: Re: GetPrivateProfileString
Post by: John Z on December 16, 2024, 03:51:19 PM
Hi HellOfMice,

Quote from: HellOfMice on December 16, 2024, 02:55:28 PM
John, you should check the RetVal value, must contain the number of characters returned

It really is not useful, at least in my case.
Since I pre-allocate the return string space and set the max-chars equal to or less than that allocation there is no risk of overflow.  Tested with no value, tested with huge string - all ok :)
All critical parameters are either TRUE/FALSE or some number N.
NON-Critical text like the user language is limited by max-chars.


MS says -
"If neither lpAppName nor lpKeyName is NULL and the supplied destination buffer is too small to hold the requested string, the string is truncated and followed by a null character, and the return value is equal to nSize minus one."

Even Micro$oft example code ignores the return .... 


John Z


"Not everything worthwhile can be measured, and not everything that can be measured is worthwhile."
Steve Hargadon
Title: Re: GetPrivateProfileString
Post by: HellOfMice on December 16, 2024, 03:58:06 PM
Hi John,

QuoteRetVal = GetPrivateProfileStringW(p_tmp, L"MainLeft", L"10",INIString,200, p_file);

INIString should be equal to "10"
Is it right?
if no what is the RetVal value

Thank for your help

Philippe
Title: Re: GetPrivateProfileString
Post by: John Z on December 16, 2024, 04:09:12 PM
Hi Sir HelloOfMice,

Yes that is correct, If there is no entry in the in file then INIString will be "10",
if there is an entry INIString will be that entry value.

as in
[Settings]
MaxCards=500
MainLeft=503

Then INIString will be "503"

And if there is a MainLeft =  but no value the INIString will be "" and result in a 0 as far as I can tell.

John Z

Here is how I used GetPrivateProfileInt, maybe more suitable to your case?

   syntax.field1 = GetPrivateProfileInt(L"RenameOptions", L"Field1", Field1_Skip, p_inifile);
    if ((syntax.field1 < Field1_Skip) || (syntax.field1 > Field1_FN))
     {syntax.field1 = Field1_Skip;}
Title: Re: GetPrivateProfileString
Post by: HellOfMice on December 16, 2024, 04:13:50 PM
Hi Cowboy


In that case MainLeft should contain "10".
It should contain the Default Returned string.
This is what is done if the key does not exist
Windows thinks the key has an empty string as a value and returns it
Title: Re: GetPrivateProfileString
Post by: John Z on December 16, 2024, 04:23:29 PM
Hi HellOfMice,

I'm confused, what you are saying is what I wrote....so I'm not sure what you are pointing to as an issue??

Maybe I've not enough sleep...

Three cases
1) A specified Key does not exist                  - result will be the default value specified
2) A specified Key does exist and has a value - result will be that value
3) A specified Key exists but has no value      - result will be empty string which converts to 0

which one is in question?

John Z



John Z
Title: Re: GetPrivateProfileString
Post by: HellOfMice on December 16, 2024, 04:26:44 PM
Hi John,


I had a normal time in my bed but did not slept very much...


I am ok with all your sentences. I had not understood. Sorry.


Philippe
Title: Re: GetPrivateProfileString
Post by: HellOfMice on December 16, 2024, 04:31:26 PM
From Microsoft
Quote[in] lpDefault A default string. If the lpKeyName key cannot be found in the initialization file, GetPrivateProfileString copies the default string to the lpReturnedString buffer.If this parameter is NULL, the default is an empty string, "".Avoid specifying a default string with trailing blank characters. The function inserts a null character in the lpReturnedString buffer to strip any trailing blanks.


They don't say that the returned string has an empty string if lpKeyName has no value after '='
Title: Re: GetPrivateProfileString
Post by: John Z on December 16, 2024, 04:36:40 PM
We are in sync!  Too little sleep! :(

A default string. If the lpKeyName key cannot be found in the initialization file, GetPrivateProfileString copies the default string to the lpReturnedString buffer.If this parameter is NULL, the default is an empty string, Avoid specifying a default string with trailing blank characters. The function inserts a null character in the lpReturnedString buffer to strip any trailing blanks.


This is case #1 ....

Yes MS never clearly discusses case #3

Cheers,
John Z
Title: Re: GetPrivateProfileString
Post by: TimoVJL on December 16, 2024, 05:07:18 PM
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stdio.h>

int __cdecl main(void)
{
char szBuf[260];
DWORD rc = GetPrivateProfileString("Dialog Box #3", "Dialog Menu ID", "0", szBuf, sizeof(szBuf), "./GetPrivate.ini");
DWORD ec = GetLastError();
printf("%d, %d, '%s'\n", ec, rc, szBuf);
rc = GetPrivateProfileString("Dialog Box #3", "Dialog Menu IDs", NULL, szBuf, sizeof(szBuf), "./GetPrivate.ini");
ec = GetLastError();
printf("%d, %d, '%s'\n", ec, rc, szBuf);
return 0;
}
[Dialog Box #3]
Dialog Menu ID=
0, 0, ''
2, 0, ''
Title: Re: GetPrivateProfileString
Post by: John Z on December 16, 2024, 07:24:18 PM
Excellent as usual TimoVJL!

John Z