AppendMenu(m, MF_ENABLED, IDM_FULLSCREEN, "&Full Screen"); AppendMenu(m, MF_SEPARATOR, 0, 0);
int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show){    static char appname[] = "PuTTY";    WORD winsock_ver;    WSADATA wsadata;    WNDCLASS wndclass;    MSG msg;    int guess_width, guess_height;    hinst = inst;    flags = FLAG_VERBOSE | FLAG_INTERACTIVE;    winsock_ver = MAKEWORD(1, 1);    if (WSAStartup(winsock_ver, &wsadata)) {	MessageBox(NULL, "Unable to initialise WinSock", "WinSock Error",		   MB_OK | MB_ICONEXCLAMATION);	return 1;    }    if (LOBYTE(wsadata.wVersion) != 1 || HIBYTE(wsadata.wVersion) != 1) {	MessageBox(NULL, "WinSock version is incompatible with 1.1",		   "WinSock Error", MB_OK | MB_ICONEXCLAMATION);	WSACleanup();	return 1;    }    /* WISHLIST: maybe allow config tweaking even if winsock not present? */    sk_init();    InitCommonControls();    /* Ensure a Maximize setting in Explorer doesn't maximise the     * config box. */    defuse_showwindow();    {	ZeroMemory(&osVersion, sizeof(osVersion));	osVersion.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);	if (!GetVersionEx ( (OSVERSIONINFO *) &osVersion)) {            MessageBox(NULL, "Windows refuses to report a version",                       "PuTTY Fatal Error", MB_OK | MB_ICONEXCLAMATION);	    return 1;        }    }    /*     * Process the command line.     */    {	char *p;	default_protocol = DEFAULT_PROTOCOL;	default_port = DEFAULT_PORT;	cfg.logtype = LGTYP_NONE;	do_defaults(NULL, &cfg);	p = cmdline;	while (*p && isspace(*p))	    p++;	/*	 * Process command line options first. Yes, this can be	 * done better, and it will be as soon as I have the	 * energy...	 */	while (*p == '-') {	    char *q = p + strcspn(p, " \t");	    p++;	    if (q == p + 3 &&		tolower(p[0]) == 's' &&		tolower(p[1]) == 's' && tolower(p[2]) == 'h') {		default_protocol = cfg.protocol = PROT_SSH;		default_port = cfg.port = 22;	    } else if (q == p + 7 &&		       tolower(p[0]) == 'c' &&		       tolower(p[1]) == 'l' &&		       tolower(p[2]) == 'e' &&		       tolower(p[3]) == 'a' &&		       tolower(p[4]) == 'n' &&		       tolower(p[5]) == 'u' && tolower(p[6]) == 'p') {		/*		 * `putty -cleanup'. Remove all registry entries		 * associated with PuTTY, and also find and delete		 * the random seed file.		 */		if (MessageBox(NULL,			       "This procedure will remove ALL Registry\n"			       "entries associated with PuTTY, and will\n"			       "also remove the PuTTY random seed file.\n"			       "\n"			       "THIS PROCESS WILL DESTROY YOUR SAVED\n"			       "SESSIONS. Are you really sure you want\n"			       "to continue?",			       "PuTTY Warning",			       MB_YESNO | MB_ICONWARNING) == IDYES) {		    cleanup_all();		}		exit(0);	    }	    p = q + strspn(q, " \t");	}	/*	 * An initial @ means to activate a saved session.	 */	if (*p == '@') {	    int i = strlen(p);	    while (i > 1 && isspace(p[i - 1]))		i--;	    p[i] = '\0';	    do_defaults(p + 1, &cfg);	    if (!*cfg.host && !do_config()) {		WSACleanup();		return 0;	    }	} else if (*p == '&') {	    /*	     * An initial & means we've been given a command line	     * containing the hex value of a HANDLE for a file	     * mapping object, which we must then extract as a	     * config.	     */	    HANDLE filemap;	    Config *cp;	    if (sscanf(p + 1, "%p", &filemap) == 1 &&		(cp = MapViewOfFile(filemap, FILE_MAP_READ,				    0, 0, sizeof(Config))) != NULL) {		cfg = *cp;		UnmapViewOfFile(cp);		CloseHandle(filemap);	    } else if (!do_config()) {		WSACleanup();		return 0;	    }	} else if (*p) {	    char *q = p;	    /*	     * If the hostname starts with "telnet:", set the	     * protocol to Telnet and process the string as a	     * Telnet URL.	     */	    if (!strncmp(q, "telnet:", 7)) {		char c;		q += 7;		if (q[0] == '/' && q[1] == '/')		    q += 2;		cfg.protocol = PROT_TELNET;		p = q;		while (*p && *p != ':' && *p != '/')		    p++;		c = *p;		if (*p)		    *p++ = '\0';		if (c == ':')		    cfg.port = atoi(p);		else		    cfg.port = -1;		strncpy(cfg.host, q, sizeof(cfg.host) - 1);		cfg.host[sizeof(cfg.host) - 1] = '\0';	    } else {		while (*p && !isspace(*p))		    p++;		if (*p)		    *p++ = '\0';		strncpy(cfg.host, q, sizeof(cfg.host) - 1);		cfg.host[sizeof(cfg.host) - 1] = '\0';		while (*p && isspace(*p))		    p++;		if (*p)		    cfg.port = atoi(p);		else		    cfg.port = -1;	    }	} else {	    if (!do_config()) {		WSACleanup();		return 0;	    }	}	/*	 * Trim leading whitespace off the hostname if it's there.	 */	{	    int space = strspn(cfg.host, " \t");	    memmove(cfg.host, cfg.host+space, 1+strlen(cfg.host)-space);	}	/* See if host is of the form user@host */	if (cfg.host[0] != '\0') {	    char *atsign = strchr(cfg.host, '@');	    /* Make sure we're not overflowing the user field */	    if (atsign) {		if (atsign - cfg.host < sizeof cfg.username) {		    strncpy(cfg.username, cfg.host, atsign - cfg.host);		    cfg.username[atsign - cfg.host] = '\0';		}		memmove(cfg.host, atsign + 1, 1 + strlen(atsign + 1));	    }	}	/*	 * Trim a colon suffix off the hostname if it's there.	 */	cfg.host[strcspn(cfg.host, ":")] = '\0';    }    /*     * Select protocol. This is farmed out into a table in a     * separate file to enable an ssh-free variant.     */    {	int i;	back = NULL;	for (i = 0; backends[i].backend != NULL; i++)	    if (backends[i].protocol == cfg.protocol) {		back = backends[i].backend;		break;	    }	if (back == NULL) {	    MessageBox(NULL, "Unsupported protocol number found",		       "PuTTY Internal Error", MB_OK | MB_ICONEXCLAMATION);	    WSACleanup();	    return 1;	}    }    /* Check for invalid Port number (i.e. zero) */    if (cfg.port == 0) {	MessageBox(NULL, "Invalid Port Number",		   "PuTTY Internal Error", MB_OK | MB_ICONEXCLAMATION);	WSACleanup();	return 1;    }    if (!prev) {	wndclass.style = 0;	wndclass.lpfnWndProc = WndProc;	wndclass.cbClsExtra = 0;	wndclass.cbWndExtra = 0;	wndclass.hInstance = inst;	wndclass.hIcon = LoadIcon(inst, MAKEINTRESOURCE(IDI_MAINICON));	wndclass.hCursor = LoadCursor(NULL, IDC_IBEAM);	wndclass.hbrBackground = NULL;	wndclass.lpszMenuName = NULL;	wndclass.lpszClassName = appname;	RegisterClass(&wndclass);    }    hwnd = NULL;    savelines = cfg.savelines;    term_init();    cfgtopalette();    /*     * Guess some defaults for the window size. This all gets     * updated later, so we don't really care too much. However, we     * do want the font width/height guesses to correspond to a     * large font rather than a small one...     */    font_width = 10;    font_height = 20;    extra_width = 25;    extra_height = 28;    term_size(cfg.height, cfg.width, cfg.savelines);    guess_width = extra_width + font_width * cols;    guess_height = extra_height + font_height * rows;    {	RECT r;	HWND w = GetDesktopWindow();	GetWindowRect(w, &r);	if (guess_width > r.right - r.left)	    guess_width = r.right - r.left;	if (guess_height > r.bottom - r.top)	    guess_height = r.bottom - r.top;    }    {	int winmode = WS_OVERLAPPEDWINDOW | WS_VSCROLL;	int exwinmode = 0;	if (!cfg.scrollbar)	    winmode &= ~(WS_VSCROLL);	if (cfg.resize_action == RESIZE_DISABLED)	    winmode &= ~(WS_THICKFRAME | WS_MAXIMIZEBOX);	if (cfg.alwaysontop)	    exwinmode |= WS_EX_TOPMOST;	if (cfg.sunken_edge)	    exwinmode |= WS_EX_CLIENTEDGE;	hwnd = CreateWindowEx(exwinmode, appname, appname,			      winmode, CW_USEDEFAULT, CW_USEDEFAULT,			      guess_width, guess_height,			      NULL, NULL, inst, NULL);    }    /*     * Initialise the fonts, simultaneously correcting the guesses     * for font_{width,height}.     */    init_fonts(0,0);    /*     * Correct the guesses for extra_{width,height}.     */    {	RECT cr, wr;	GetWindowRect(hwnd, &wr);	GetClientRect(hwnd, &cr);	offset_width = offset_height = cfg.window_border;	extra_width = wr.right - wr.left - cr.right + cr.left + offset_width*2;	extra_height = wr.bottom - wr.top - cr.bottom + cr.top +offset_height*2;    }    /*     * Resize the window, now we know what size we _really_ want it     * to be.     */    guess_width = extra_width + font_width * cols;    guess_height = extra_height + font_height * rows;    SetWindowPos(hwnd, NULL, 0, 0, guess_width, guess_height,		 SWP_NOMOVE | SWP_NOREDRAW | SWP_NOZORDER);    /*     * Set up a caret bitmap, with no content.     */    {	char *bits;	int size = (font_width + 15) / 16 * 2 * font_height;	bits = smalloc(size);	memset(bits, 0, size);	caretbm = CreateBitmap(font_width, font_height, 1, 1, bits);	sfree(bits);    }    CreateCaret(hwnd, caretbm, font_width, font_height);    /*     * Initialise the scroll bar.     */    {	SCROLLINFO si;	si.cbSize = sizeof(si);	si.fMask = SIF_ALL | SIF_DISABLENOSCROLL;	si.nMin = 0;	si.nMax = rows - 1;	si.nPage = rows;	si.nPos = 0;	SetScrollInfo(hwnd, SB_VERT, &si, FALSE);    }    /*     * Start up the telnet connection.     */    {	char *error;	char msg[1024], *title;	char *realhost;	error = back->init(cfg.host, cfg.port, &realhost);	if (error) {	    sprintf(msg, "Unable to open connection to\n"		    "%.800s\n" "%s", cfg.host, error);	    MessageBox(NULL, msg, "PuTTY Error", MB_ICONERROR | MB_OK);	    return 0;	}	window_name = icon_name = NULL;	if (*cfg.wintitle) {	    title = cfg.wintitle;	} else {	    sprintf(msg, "%s - PuTTY", realhost);	    title = msg;	}	sfree(realhost);	set_title(title);	set_icon(title);    }    session_closed = FALSE;    /*     * Prepare the mouse handler.     */    lastact = MA_NOTHING;    lastbtn = MBT_NOTHING;    dbltime = GetDoubleClickTime();    /*     * Set up the session-control options on the system menu.     */    {	HMENU m = GetSystemMenu(hwnd, FALSE);	HMENU p, s;	int i;	AppendMenu(m, MF_SEPARATOR, 0, 0);	if (cfg.protocol == PROT_TELNET) {	    p = CreateMenu();	    AppendMenu(p, MF_ENABLED, IDM_TEL_AYT, "Are You There");	    AppendMenu(p, MF_ENABLED, IDM_TEL_BRK, "Break");	    AppendMenu(p, MF_ENABLED, IDM_TEL_SYNCH, "Synch");	    AppendMenu(p, MF_SEPARATOR, 0, 0);	    AppendMenu(p, MF_ENABLED, IDM_TEL_EC, "Erase Character");	    AppendMenu(p, MF_ENABLED, IDM_TEL_EL, "Erase Line");	    AppendMenu(p, MF_ENABLED, IDM_TEL_GA, "Go Ahead");	    AppendMenu(p, MF_ENABLED, IDM_TEL_NOP, "No Operation");	    AppendMenu(p, MF_SEPARATOR, 0, 0);	    AppendMenu(p, MF_ENABLED, IDM_TEL_ABORT, "Abort Process");	    AppendMenu(p, MF_ENABLED, IDM_TEL_AO, "Abort Output");	    AppendMenu(p, MF_ENABLED, IDM_TEL_IP, "Interrupt Process");	    AppendMenu(p, MF_ENABLED, IDM_TEL_SUSP, "Suspend Process");	    AppendMenu(p, MF_SEPARATOR, 0, 0);	    AppendMenu(p, MF_ENABLED, IDM_TEL_EOR, "End Of Record");	    AppendMenu(p, MF_ENABLED, IDM_TEL_EOF, "End Of File");	    AppendMenu(m, MF_POPUP | MF_ENABLED, (UINT) p,		       "Telnet Command");	    AppendMenu(m, MF_SEPARATOR, 0, 0);	}	AppendMenu(m, MF_ENABLED, IDM_SHOWLOG, "&Event Log");	AppendMenu(m, MF_SEPARATOR, 0, 0);	AppendMenu(m, MF_ENABLED, IDM_NEWSESS, "Ne&w Session...");	AppendMenu(m, MF_ENABLED, IDM_DUPSESS, "&Duplicate Session");	s = CreateMenu();	get_sesslist(TRUE);	for (i = 1; i < ((nsessions < 256) ? nsessions : 256); i++)	    AppendMenu(s, MF_ENABLED, IDM_SAVED_MIN + (16 * i),		       sessions[i]);	AppendMenu(m, MF_POPUP | MF_ENABLED, (UINT) s, "Sa&ved Sessions");	AppendMenu(m, MF_ENABLED, IDM_RECONF, "Chan&ge Settings...");	AppendMenu(m, MF_SEPARATOR, 0, 0);	AppendMenu(m, MF_ENABLED, IDM_COPYALL, "C&opy All to Clipboard");	AppendMenu(m, MF_ENABLED, IDM_CLRSB, "C&lear Scrollback");	AppendMenu(m, MF_ENABLED, IDM_RESET, "Rese&t Terminal");	AppendMenu(m, MF_SEPARATOR, 0, 0);	AppendMenu(m, MF_ENABLED, IDM_ABOUT, "&About PuTTY");    }    /*     * Finally show the window!     */    ShowWindow(hwnd, show);    SetForegroundWindow(hwnd);    /*     * Open the initial log file if there is one.     */    logfopen();    /*     * Set the palette up.     */    pal = NULL;    logpal = NULL;    init_palette();    has_focus = (GetForegroundWindow() == hwnd);    UpdateWindow(hwnd);    if (GetMessage(&msg, NULL, 0, 0) == 1) {	int timer_id = 0, long_timer = 0;	while (msg.message != WM_QUIT) {	    /* Sometimes DispatchMessage calls routines that use their own	     * GetMessage loop, setup this timer so we get some control back.	     *	     * Also call term_update() from the timer so that if the host	     * is sending data flat out we still do redraws.	     */	    if (timer_id && long_timer) {		KillTimer(hwnd, timer_id);		long_timer = timer_id = 0;	    }	    if (!timer_id)		timer_id = SetTimer(hwnd, 1, 20, NULL);	    if (!(IsWindow(logbox) && IsDialogMessage(logbox, &msg)))		DispatchMessage(&msg);	    /* Make sure we blink everything that needs it. */	    term_blink(0);	    /* Send the paste buffer if there's anything to send */	    term_paste();	    /* If there's nothing new in the queue then we can do everything	     * we've delayed, reading the socket, writing, and repainting	     * the window.	     */	    if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))		continue;	    if (pending_netevent) {		enact_pending_netevent();		/* Force the cursor blink on */		term_blink(1);		if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))		    continue;	    }	    /* Okay there is now nothing to do so we make sure the screen is	     * completely up to date then tell windows to call us in a little 	     * while.	     */	    if (timer_id) {		KillTimer(hwnd, timer_id);		timer_id = 0;	    }	    HideCaret(hwnd);	    term_out();	    term_update();	    ShowCaret(hwnd);	    flash_window(1);	       /* maintain */	    if (in_vbell)		/* Hmm, term_update didn't want to do an update too soon ... */		timer_id = SetTimer(hwnd, 1, 50, NULL);	    else if (!has_focus)		timer_id = SetTimer(hwnd, 1, 500, NULL);	    else		timer_id = SetTimer(hwnd, 1, 100, NULL);	    long_timer = 1;	    /* There's no point rescanning everything in the message queue	     * so we do an apparently unnecessary wait here	     */	    WaitMessage();	    if (GetMessage(&msg, NULL, 0, 0) != 1)		break;	}    }    /*     * Clean up.     */    deinit_fonts();    sfree(logpal);    if (pal)	DeleteObject(pal);    WSACleanup();    if (cfg.protocol == PROT_SSH) {	random_save_seed();#ifdef MSCRYPTOAPI	crypto_wrapup();#endif    }    return msg.wParam;}