1 /* w32main.c - W32 main entry pint and taskbar support for the GnuPG Agent
2 * Copyright (C) 2007 Free Software Foundation, Inc.
3 * Copyright 1996, 1998 Alexandre Julliard
5 * This file is part of GnuPG.
7 * GnuPG is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
12 * GnuPG is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, see <http://www.gnu.org/licenses/>.
22 #ifndef HAVE_W32_SYSTEM
23 #error This module is only useful for the W32 version of gpg-agent
34 /* The instance handle has received by WinMain. */
35 static HINSTANCE glob_hinst
;
36 static HWND glob_hwnd
;
39 /* Build an argv array from the command in CMDLINE. RESERVED is the
40 number of args to reserve before the first one. This code is based
41 on Alexandre Julliard's LGPLed wine-0.9.34/dlls/kernel32/process.c
42 and modified to fit into our framework. The function returns NULL
43 on error; on success an arry with the argiments is returned. This
44 array has been allocaqted using a plain malloc (and not the usual
47 build_argv (char *cmdline_arg
, int reserved
)
51 char *cmdline
, *s
, *arg
, *d
;
52 int in_quotes
, bs_count
;
54 cmdline
= malloc (strlen (cmdline_arg
) + 1);
57 strcpy (cmdline
, cmdline_arg
);
59 /* First determine the required size of the array. */
66 if ( !*s
|| ((*s
==' ' || *s
=='\t') && !in_quotes
)) /* A space. */
69 /* Skip the remaining spaces. */
70 while (*s
==' ' || *s
=='\t')
81 else if ( (*s
== '\"') && !(bs_count
& 1))
84 in_quotes
= !in_quotes
;
88 else /* A regular character. */
95 argv
= xtrymalloc (argc
* sizeof *argv
);
102 /* Now actually parse the command line. */
106 arg
= d
= s
= cmdline
;
109 if ((*s
==' ' || *s
=='\t') && !in_quotes
)
111 /* Close the argument and copy it. */
115 /* Skip the remaining spaces. */
118 while (*s
==' ' || *s
=='\t');
120 /* Start with a new argument */
131 if ( !(bs_count
& 1) )
133 /* Preceded by an even number of backslashes, this is
134 half that number of backslashes, plus a '\"' which we
138 in_quotes
= !in_quotes
;
142 /* Preceded by an odd number of backslashes, this is
143 half that number of backslashes followed by a '\"'. */
144 d
= d
- bs_count
/2 - 1;
150 else /* A regular character. */
169 /* Our window message processing function. */
170 static LRESULT CALLBACK
171 wndw_proc (HWND hwnd
, UINT msg
, WPARAM wparam
, LPARAM lparam
)
177 fprintf (stderr
,"%s: received WM_%s\n", __func__
, "USER" );
182 return DefWindowProc (hwnd
, msg
, wparam
, lparam
);
186 /* This function is called to do some fast event polling and
189 w32_poll_events (void)
193 /* fprintf (stderr,"%s: enter\n", __func__); */
194 /* while (PeekMessage (&msg, glob_hwnd, 0, 0, PM_REMOVE)) */
196 /* DispatchMessage (&msg); */
198 /* fprintf (stderr,"%s: leave\n", __func__); */
204 handle_taskbar (void *ctx
)
206 WNDCLASS wndwclass
= {0, wndw_proc
, 0, 0, glob_hinst
,
207 0, 0, 0, 0, "gpg-agent"};
213 if (!RegisterClass (&wndwclass
))
215 log_error ("error registering window class\n");
218 hwnd
= CreateWindow ("gpg-agent", "gpg-agent",
220 NULL
, NULL
, glob_hinst
, NULL
);
223 log_error ("error creating main window\n");
229 memset (&nid
, 0, sizeof nid
);
230 nid
.cbSize
= sizeof (nid
);
231 nid
.uFlags
= NIF_MESSAGE
| NIF_ICON
| NIF_TIP
;
232 nid
.uCallbackMessage
= WM_USER
;
233 nid
.hWnd
= glob_hwnd
;
235 nid
.hIcon
= LoadIcon (glob_hinst
, MAKEINTRESOURCE (1));
236 mem2str (nid
.szTip
, "GnuPG Agent version "PACKAGE_VERSION
,
238 Shell_NotifyIcon (NIM_ADD
, &nid
);
239 DestroyIcon (nid
.hIcon
);
241 fprintf (stderr
, "%s: enter\n", __func__
);
242 while ( (rc
=GetMessage (&msg
, hwnd
, 0, 0)) )
246 log_error ("getMessage failed: %s\n", w32_strerror (-1));
249 TranslateMessage (&msg
);
250 DispatchMessage (&msg
);
252 fprintf (stderr
,"%s: leave\n", __func__
);
259 /* This function initializes the Window system and sets up the taskbar
260 icon. We only have very limited GUI support just to give the
261 taskbar icon a little bit of life. This fucntion is called once to
264 w32_setup_taskbar (void)
266 SECURITY_ATTRIBUTES sa
;
270 memset (&sa
, 0, sizeof sa
);
271 sa
.nLength
= sizeof sa
;
272 sa
.bInheritHandle
= FALSE
;
274 fprintf (stderr
,"creating thread for the taskbar_event_loop...\n");
275 th
= CreateThread (&sa
, 128*1024,
276 (LPTHREAD_START_ROUTINE
)handle_taskbar
,
278 fprintf (stderr
,"created thread %p tid=%d\n", th
, (int)tid
);
286 /* The main entry point for the Windows version. We save away all GUI
287 related stuff, parse the command line and finally call the real
290 WinMain (HINSTANCE hinst
, HINSTANCE hprev
, LPSTR cmdline
, int showcmd
)
295 /* We use the GetCommandLine function because that also includes the
296 program name in contrast to the CMDLINE arg. */
297 argv
= build_argv (GetCommandLineA (), 0);
299 return 2; /* Can't do much about a malloc failure. */
300 for (argc
=0; argv
[argc
]; argc
++)
305 return w32_main (argc
, argv
);