Issue with automated installation of Gpg4win 5.0.1

Still broken in 5.1.1 (I also checked 5.1.0). I tracked it down to the
return path of config_fetch_bool, not the ini parsing itself.

Setup: gpg4win-5.1.1.exe /S /C=C:\temp\gpg4win.ini with inst_gpgol,
inst_gpgoljs, inst_okular = false and inst_desktop = false. Result:
GpgOL, GpgOL/Web, Okular and the desktop shortcut are installed anyway.

What happens:

  • config_init() reads the ini correctly. I compiled that function from
    the 5.1.0 tag and ran it against my file: all 10 keys and values come
    out right.

  • config_fetch_bool() then returns the result with SetUserVariableA(),
    and that function in src/exdll.c computes the variable address in bytes
    instead of WCHARs:

    LPWSTR wideStr = (LPWSTR)((char*)g_variables + varnum * g_stringsize);

    With g_stringsize = 1024, $R0 (index 10) ends up at WCHAR offset 5120,
    which is $5. So the “0”/“1” goes into $5, $R0 keeps its old value, and
    CalcDefaults never selects or unselects anything.

  • setuservariable() in the same file does it right
    ((wchar_t*)g_variables + varnum*g_stringsize), which is why the empty
    result (missing key) works and true/false does not.

  • I confirmed the same thing in the shipped 5.1.1 binary: in
    $PLUGINSDIR\g4wihelp.dll the SetUserVariableA code does
    imul/add without the 2, while setuservariable uses [edx+eax2].

Suggested fix (src/exdll.c, SetUserVariableA):

  •  LPWSTR wideStr = (LPWSTR)((char*)g_variables + varnum * g_stringsize);
    
  •  LPWSTR wideStr = (LPWSTR)g_variables + varnum * g_stringsize;
    

Side note in config_init() (src/g4wihelp.c): cmdline is advanced while
parsing and later passed to free(cmdline), so it frees a pointer that
was not returned by malloc. Keeping the original pointer for free()
would fix it.

Workaround until it is fixed: the installer restores the previous
component selection (NSIS Memento) before reading the ini. Writing it
beforehand in the 64-bit registry view works for a silent install:

HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Gpg4win
MementoSectionUsed REG_SZ “”
MementoSection_SEC_kleopatra REG_DWORD 1
MementoSection_SEC_gpgex REG_DWORD 1
MementoSection_SEC_gpgol REG_DWORD 0
MementoSection_SEC_gpgoljs REG_DWORD 0
MementoSection_SEC_okular REG_DWORD 0
MementoSection_SEC_gpgpass REG_DWORD 0
MementoSection_SEC_gpgme_browser REG_DWORD 0

With that, 5.1.1 /S installs only Kleopatra, GpgEX and GnuPG (Paperkey
still gets installed, it is a hidden section). The start menu entry is
created and there is no desktop shortcut.