Compile PuTTY on your own

The beginning: Source Code

Find the original source archive at https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html or get the Windows-Archive directly here: https://the.earth.li/~sgtatham/putty/latest/putty-src.zip

Modify the Source Code

For example: Tweak the modal „Fatal Connection Error“ Dialog: Relax PuTTY: Suppress „Fatal Error“ Dialog

Next step: GCC-Compiler

I’d chose MinGW to compile native Windows Applications: MinGW as build-environment for native Windows Applications

Compile it

Using MinGw:

run MinGw

In PuTTY it’s all prepared for us – go to the „windows“ subdirectory:

  • mingw32-make -f Makefile.mgw
C:\Program Files\mingw-w64\x86_64-8.1.0-win32-seh-rt_v6-rev0>echo off
Microsoft Windows [Version 10.0.19042.1110]
(c) Microsoft Corporation. Alle Rechte vorbehalten.

C:\> cd C:\\Users\\user\\Downloads\\putty-src_0-76\

C:\Users\user\Downloads\putty-src_0-76> cd windows

C:\Users\user\Downloads\putty-src_0-76\windows> mingw32-make -f Makefile.mgw
gcc  -Wall -O2 -std=gnu99 -Wvla -D_WINDOWS -DWIN32S_COMPAT -D_NO_OLDNAMES -D__USE_MINGW_ANSI_STDIO=1 -I.././ -I../charset/ -I../windows/ -I../unix/ -D_WIN32_IE=0x0500 -DWINVER=0x0500 -D_WIN32_WINDOWS=0x0410 -D_WIN32_WINNT=0x0500  -c ../ssh2userauth.c
gcc -s -o plink.exe -Wl,-Map,plink.map agentf.o aqsync.o \
        be_all_s.o be_misc.o callback.o clicons.o cmdline.o conf.o \
        console.o cproxy.o ecc.o errsock.o ldisc.o logging.o \
        mainchan.o marshal.o memory.o misc.o miscucs.o mpint.o \
        noterm.o nullplug.o pgssapi.o pinger.o plink.res.o portfwd.o \
        proxy.o raw.o rlogin.o sessprep.o settings.o ssh.o ssh1bpp.o \
        ssh1censor.o ssh1connection.o ssh1connection-client.o \
        ssh1login.o ssh2bpp.o ssh2bpp-bare.o ssh2censor.o \
        ssh2connection.o ssh2connection-client.o ssh2kex-client.o \
        ssh2transhk.o ssh2transport.o ssh2userauth.o sshaes.o \
        ssharcf.o sshargon2.o sshauxcrypt.o sshblake2.o sshblowf.o \
        sshccp.o sshcommon.o sshcrc.o sshcrcda.o sshdes.o sshdh.o \
        sshdss.o sshecc.o sshgssc.o sshhmac.o sshmac.o sshmd5.o \
        sshprng.o sshpubk.o sshrand.o sshrsa.o sshsh256.o sshsh512.o \
        sshsha.o sshsha3.o sshshare.o sshutils.o sshverstring.o \
        sshzlib.o stripctrl.o supdup.o telnet.o timing.o tree234.o \
        utils.o version.o wcwidth.o wildcard.o wincapi.o \
        wincliloop.o wincons.o windefs.o wingss.o winhandl.o \
        winhsock.o winmisc.o winmiscs.o winnet.o winnohlp.o \
        winnoise.o winnojmp.o winnpc.o winnps.o winpgntc.o \
        winplink.o winproxy.o winsecur.o winselcli.o winser.o \
        winshare.o winstore.o wintime.o winucs.o winx11.o x11fwd.o \
        -ladvapi32 -lcomdlg32 -lgdi32 -limm32 -lole32 -lshell32 \
        -luser32
gcc -s -o pscp.exe -Wl,-Map,pscp.map agentf.o aqsync.o be_misc.o \
        be_ssh.o callback.o clicons.o cmdline.o conf.o console.o \
        cproxy.o ecc.o errsock.o logging.o mainchan.o marshal.o \
        memory.o misc.o miscucs.o mpint.o nullplug.o pgssapi.o \
        pinger.o portfwd.o proxy.o pscp.o pscp.res.o psftpcommon.o \
        settings.o sftp.o sftpcommon.o ssh.o ssh1bpp.o ssh1censor.o \
        ssh1connection.o ssh1connection-client.o ssh1login.o \
        ssh2bpp.o ssh2bpp-bare.o ssh2censor.o ssh2connection.o \
        ssh2connection-client.o ssh2kex-client.o ssh2transhk.o \
        ssh2transport.o ssh2userauth.o sshaes.o ssharcf.o \
        sshargon2.o sshauxcrypt.o sshblake2.o sshblowf.o sshccp.o \
        sshcommon.o sshcrc.o sshcrcda.o sshdes.o sshdh.o sshdss.o \
        sshecc.o sshgssc.o sshhmac.o sshmac.o sshmd5.o sshprng.o \
        sshpubk.o sshrand.o sshrsa.o sshsh256.o sshsh512.o sshsha.o \
        sshsha3.o sshshare.o sshutils.o sshverstring.o sshzlib.o \
        stripctrl.o timing.o tree234.o utils.o version.o wcwidth.o \
        wildcard.o wincapi.o wincliloop.o wincons.o windefs.o \
        wingss.o winhandl.o winhsock.o winmisc.o winmiscs.o winnet.o \
        winnohlp.o winnoise.o winnojmp.o winnpc.o winnps.o \
        winpgntc.o winproxy.o winsecur.o winselcli.o winsftp.o \
        winshare.o winstore.o wintime.o winucs.o x11fwd.o -ladvapi32 \
        -lcomdlg32 -lgdi32 -limm32 -lole32 -lshell32 -luser32
gcc -s -o psftp.exe -Wl,-Map,psftp.map agentf.o aqsync.o \
        be_misc.o be_ssh.o callback.o clicons.o cmdline.o conf.o \
        console.o cproxy.o ecc.o errsock.o logging.o mainchan.o \
        marshal.o memory.o misc.o miscucs.o mpint.o nullplug.o \
        pgssapi.o pinger.o portfwd.o proxy.o psftp.o psftp.res.o \
        psftpcommon.o settings.o sftp.o sftpcommon.o ssh.o ssh1bpp.o \
        ssh1censor.o ssh1connection.o ssh1connection-client.o \
        ssh1login.o ssh2bpp.o ssh2bpp-bare.o ssh2censor.o \
        ssh2connection.o ssh2connection-client.o ssh2kex-client.o \
        ssh2transhk.o ssh2transport.o ssh2userauth.o sshaes.o \
        ssharcf.o sshargon2.o sshauxcrypt.o sshblake2.o sshblowf.o \
        sshccp.o sshcommon.o sshcrc.o sshcrcda.o sshdes.o sshdh.o \
        sshdss.o sshecc.o sshgssc.o sshhmac.o sshmac.o sshmd5.o \
        sshprng.o sshpubk.o sshrand.o sshrsa.o sshsh256.o sshsh512.o \
        sshsha.o sshsha3.o sshshare.o sshutils.o sshverstring.o \
        sshzlib.o stripctrl.o timing.o tree234.o utils.o version.o \
        wcwidth.o wildcard.o wincapi.o wincliloop.o wincons.o \
        windefs.o wingss.o winhandl.o winhsock.o winmisc.o \
        winmiscs.o winnet.o winnohlp.o winnoise.o winnojmp.o \
        winnpc.o winnps.o winpgntc.o winproxy.o winsecur.o \
        winselcli.o winsftp.o winshare.o winstore.o wintime.o \
        winucs.o x11fwd.o -ladvapi32 -lcomdlg32 -lgdi32 -limm32 \
        -lole32 -lshell32 -luser32
gcc -mwindows -s -o putty.exe -Wl,-Map,putty.map agentf.o \
        aqsync.o be_all_s.o be_misc.o callback.o cmdline.o conf.o \
        config.o cproxy.o dialog.o ecc.o errsock.o ldisc.o logging.o \
        mainchan.o marshal.o memory.o minibidi.o misc.o miscucs.o \
        mpint.o nullplug.o pgssapi.o pinger.o portfwd.o proxy.o \
        putty.res.o raw.o rlogin.o sessprep.o settings.o sizetip.o \
        ssh.o ssh1bpp.o ssh1censor.o ssh1connection.o \
        ssh1connection-client.o ssh1login.o ssh2bpp.o ssh2bpp-bare.o \
        ssh2censor.o ssh2connection.o ssh2connection-client.o \
        ssh2kex-client.o ssh2transhk.o ssh2transport.o \
        ssh2userauth.o sshaes.o ssharcf.o sshargon2.o sshauxcrypt.o \
        sshblake2.o sshblowf.o sshccp.o sshcommon.o sshcrc.o \
        sshcrcda.o sshdes.o sshdh.o sshdss.o sshecc.o sshgssc.o \
        sshhmac.o sshmac.o sshmd5.o sshprng.o sshpubk.o sshrand.o \
        sshrsa.o sshsh256.o sshsh512.o sshsha.o sshsha3.o sshshare.o \
        sshutils.o sshverstring.o sshzlib.o stripctrl.o supdup.o \
        telnet.o terminal.o timing.o tree234.o utils.o version.o \
        wcwidth.o wildcard.o wincapi.o wincfg.o winctrls.o windefs.o \
        windlg.o window.o wingss.o winhandl.o winhelp.o winhsock.o \
        winjump.o winmisc.o winmiscs.o winnet.o winnoise.o winnpc.o \
        winnps.o winpgntc.o winprint.o winproxy.o winsecur.o \
        winselgui.o winser.o winshare.o winstore.o wintime.o \
        winucs.o winutils.o winx11.o x11fwd.o -ladvapi32 -lcomdlg32 \
        -lgdi32 -limm32 -lole32 -lshell32 -luser32

C:\Users\user\Downloads\putty-src_0-76\windows>

Check the result

C:\Users\user\Downloads\putty-src_0-76\windows> dir putty.exe
 Datenträger in Laufwerk C: ist Windows
 Volumeseriennummer: 1E1B-0142

 Verzeichnis von C:\Users\user\Downloads\putty-src_0-76\windows

16.08.2021  20:16           981.504 putty.exe
               1 Datei(en),        981.504 Bytes
               0 Verzeichnis(se), 265.798.283.264 Bytes frei

C:\Users\user\Downloads\putty-src_0-76\windows>

EXEcute it

C:\Users\user\Downloads\putty-src_0-76\windows> putty.exe
Putty 0.76 – compiled on my own using „gcc 8.1.0“

Final thought: Donate PuTTY

It is possible 😉 to donate to the original PuTTY developers – look here: https://www.chiark.greenend.org.uk/~sgtatham/putty/faq.html#faq-donations

Relax PuTTY: Suppress „Fatal Error“ Dialog

When using PuTTY in „Multi-Tabbed“-Wrapper-Applications like MRemote-NG, Super-Putty, Putty-Connection-Manager, you name it, it’s absolute annoying that every connection-timeout pushes a modal pop-up window to the front (for every opened connection!) like this:

Since in those Applications the PuTTY-Window/Tab won’t get closed, or with „only on clean exit“

putty: close window only on clean exit

these modal alerts are absolutely pointless – when:

  1. PuTTY is running as standalone application
  2. the config-parameters set to „close window“ the original implemtation makes sense indeed.

So there is some code required, to distinguish between:

  • a quiet (Text-)Message, inline within the PuTTY-Screen when the window wont get closed
  • an modal alert before closing the putty window.

Original Code

Find it in „/windows/window.c“ – notice, that the modal popup will appear even when the PuTTY-Window won’t get closed.

/*
 * Print a message box and close the connection.
 */
static void win_seat_connection_fatal(Seat *seat, const char *msg)
{
    char *title = dupprintf("%s Fatal Error", appname);
    show_mouseptr(true);
    MessageBox(wgs.term_hwnd, msg, title, MB_ICONERROR | MB_OK);
    sfree(title);

    if (conf_get_int(conf, CONF_close_on_exit) == FORCE_ON)
        PostQuitMessage(1);
    else {
        queue_toplevel_callback(close_session, NULL);
    }
}

Improvement: Show the Dialog only, when PuTTY-Window will get closed

Much better for daily use – no annoyance anymore:

/*
 * Print a message box and close the connection.
 */
static void win_seat_connection_fatal(Seat *seat, const char *msg)
{
    char *title = dupprintf("%s Fatal Error", appname);

    if (conf_get_int(conf, CONF_close_on_exit) == FORCE_ON) {
        //show MessageBox before closing the PuTTY-Window
        show_mouseptr(true);
        MessageBox(wgs.term_hwnd, msg, title, MB_ICONERROR | MB_OK);

        PostQuitMessage(1);
    } else {
        //print message into the PuTTY-Console
        win_seat_output(seat,true,"\r\n\r\n",4);
        win_seat_output(seat,0,"------------------- ",20);
        win_seat_output(seat,0,title,strlen(title));
        win_seat_output(seat,0," ------------------\r\n",22);
        win_seat_output(seat,0,"- ",2);
        win_seat_output(seat,0,msg,strlen(msg));
        win_seat_output(seat,0,"\r\n\r\n",4);

        queue_toplevel_callback(close_session, NULL);
    }

    sfree(title);
}

Result: Relaxed Putty

Take a deep breath 🙂

relaxed putty

isn’t it beautiful?

Donate PuTTY

It is possible 😉 to donate to the original PuTTY developers – look here: https://www.chiark.greenend.org.uk/~sgtatham/putty/faq.html#faq-donations