s@©@(c)@
[privoxy.git] / win32.c
1 const char win32_rcs[] = "$Id: win32.c,v 1.12 2006/08/12 03:54:37 david__schmidt Exp $";
2 /*********************************************************************
3  *
4  * File        :  $Source: /cvsroot/ijbswa/current/win32.c,v $
5  *
6  * Purpose     :  Win32 User Interface initialization and message loop
7  *
8  * Copyright   :  Written by and Copyright (C) 2001-2002 members of
9  *                the Privoxy team.  http://www.privoxy.org/
10  *
11  *                Written by and Copyright (C) 1999 Adam Lock
12  *                <locka@iol.ie>
13  *
14  *                This program is free software; you can redistribute it 
15  *                and/or modify it under the terms of the GNU General
16  *                Public License as published by the Free Software
17  *                Foundation; either version 2 of the License, or (at
18  *                your option) any later version.
19  *
20  *                This program is distributed in the hope that it will
21  *                be useful, but WITHOUT ANY WARRANTY; without even the
22  *                implied warranty of MERCHANTABILITY or FITNESS FOR A
23  *                PARTICULAR PURPOSE.  See the GNU General Public
24  *                License for more details.
25  *
26  *                The GNU General Public License should be included with
27  *                this file.  If not, you can view it at
28  *                http://www.gnu.org/copyleft/gpl.html
29  *                or write to the Free Software Foundation, Inc., 59
30  *                Temple Place - Suite 330, Boston, MA  02111-1307, USA.
31  *
32  * Revisions   :
33  *    $Log: win32.c,v $
34  *    Revision 1.12  2006/08/12 03:54:37  david__schmidt
35  *    Windows service integration
36  *
37  *    Revision 1.11  2006/07/18 14:48:48  david__schmidt
38  *    Reorganizing the repository: swapping out what was HEAD (the old 3.1 branch)
39  *    with what was really the latest development (the v_3_0_branch branch)
40  *
41  *    Revision 1.9.2.2  2002/08/27 18:03:40  oes
42  *    Fixed stupid typo
43  *
44  *    Revision 1.9.2.1  2002/08/21 17:59:27  oes
45  *    Sync win32_blurb[] with our standard blurb
46  *
47  *    Revision 1.9  2002/03/31 17:19:00  jongfoster
48  *    Win32 only: Enabling STRICT to fix a VC++ compile warning.
49  *
50  *    Revision 1.8  2002/03/26 22:57:10  jongfoster
51  *    Web server name should begin www.
52  *
53  *    Revision 1.7  2002/03/24 12:03:47  jongfoster
54  *    Name change
55  *
56  *    Revision 1.6  2002/03/16 21:53:28  jongfoster
57  *    VC++ Heap debug option
58  *
59  *    Revision 1.5  2002/03/04 23:47:30  jongfoster
60  *    - Rewritten, simpler command-line pre-parser
61  *    - not using raise(SIGINT) any more
62  *
63  *    Revision 1.4  2001/11/30 21:29:33  jongfoster
64  *    Fixing a warning
65  *
66  *    Revision 1.3  2001/11/16 00:46:31  jongfoster
67  *    Fixing compiler warnings
68  *
69  *    Revision 1.2  2001/07/29 19:32:00  jongfoster
70  *    Renaming _main() [mingw32 only] to real_main(), for ANSI compliance.
71  *
72  *    Revision 1.1.1.1  2001/05/15 13:59:08  oes
73  *    Initial import of version 2.9.3 source tree
74  *
75  *
76  *********************************************************************/
77 \f
78
79 #include "config.h"
80
81 #ifdef _WIN32
82
83 #include <stdio.h>
84
85 #include "project.h"
86 #include "jcc.h"
87 #include "miscutil.h"
88
89 /* Uncomment this if you want to build Win32 as a console app */
90 /* #define _WIN_CONSOLE */
91
92 #ifndef STRICT
93 #define STRICT
94 #endif
95 #include <windows.h>
96
97 #include <stdarg.h>
98 #include <process.h>
99
100 #if defined(_WIN32) && defined(_MSC_VER) && defined(_DEBUG)
101 /* Visual C++ Heap debugging */
102 #include <crtdbg.h>
103 #endif /* defined(_WIN32) && defined(_MSC_VER) && defined(_DEBUG) */
104
105 #include "win32.h"
106
107 const char win32_h_rcs[] = WIN32_H_VERSION;
108
109 /**
110  * A short introductory text about Privoxy.  Used for the "About" box
111  * or the console startup message.
112  */
113 const char win32_blurb[] =
114 "Privoxy version " VERSION " for Windows\n"
115 "Copyright (C) 2000-2007 the Privoxy Team (" HOME_PAGE_URL ")\n"
116 "Based on the Internet Junkbuster by Junkbusters Corp.\n"
117 "This is free software; it may be used and copied under the\n"
118 "GNU General Public License: http://www.gnu.org/copyleft/gpl.html .\n"
119 "This program comes with ABSOLUTELY NO WARRANTY OF ANY KIND.\n";
120
121 #ifdef _WIN_CONSOLE
122
123 /**
124  * Hide the console.  If set, the program will disconnect from the 
125  * console and run in the background.  This allows the command-prompt
126  * window to close.
127  */
128 int hideConsole     = 0;
129
130
131 #else /* ndef _WIN_CONSOLE */
132
133
134 /**
135  * The application instance handle.
136  */
137 HINSTANCE g_hInstance;
138
139
140 /**
141  * The command to show the window that was specified at startup.
142  */
143 int g_nCmdShow;
144
145 static void  __cdecl UserInterfaceThread(void *);
146
147
148 #endif /* ndef _WIN_CONSOLE */
149
150 /*********************************************************************
151  *
152  * Function    :  WinMain
153  *
154  * Description :  M$ Windows "main" routine:
155  *                parse the `lpCmdLine' param into main's argc and argv variables,
156  *                start the user interface thread (for the systray window), and
157  *                call main (i.e. patch execution into normal startup).
158  *
159  * Parameters  :
160  *          1  :  hInstance = instance handle of this execution
161  *          2  :  hPrevInstance = instance handle of previous execution
162  *          3  :  lpCmdLine = command line string which started us
163  *          4  :  nCmdShow = window show value (MIN, MAX, NORMAL, etc...)
164  *
165  * Returns     :  `main' never returns, so WinMain will also never return.
166  *
167  *********************************************************************/
168 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
169 {
170 #if 0   /* See comment about __argc & __argv below */
171    int i;
172    int argc = 1;
173    const char *argv[3];
174    char szModule[MAX_PATH+1];
175 #endif
176
177    int res;
178 #ifndef _WIN_CONSOLE
179    HANDLE hInitCompleteEvent = NULL;
180 #endif
181
182
183 #if defined(_WIN32) && defined(_MSC_VER) && defined(_DEBUG)
184 #if 0
185    /* Visual C++ Heap debugging */
186
187    /* Get current flag*/
188    int tmpFlag = _CrtSetDbgFlag( _CRTDBG_REPORT_FLAG );
189
190    /* Turn on leak-checking bit */
191    tmpFlag |= _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF | _CRTDBG_CHECK_ALWAYS_DF;
192
193    /* Turn off CRT block checking bit */
194    tmpFlag &= ~(_CRTDBG_CHECK_CRT_DF | _CRTDBG_DELAY_FREE_MEM_DF);
195
196    /* Set flag to the new value */
197    _CrtSetDbgFlag( tmpFlag );
198 #endif
199 #endif /* defined(_WIN32) && defined(_MSC_VER) && defined(_DEBUG) */
200
201
202 /************
203  * I couldn't figure out why the command line was being sorta parsed here
204  * instead of using the __argc & __argv globals usually defined in stdlib.h
205  *
206  * From what I can tell by looking at the MinWG source, it supports these
207  * globals, so i'd hope that the other compilers do so as well.
208  * Obviously, if i'm wrong i'll find out soon enough!  :)
209  ************/
210 #if 0
211    /*
212     * Cheat in parsing the command line.  We only ever have at most one
213     * paramater, which may optionally be specified inside double quotes.
214     */
215
216    if (lpCmdLine != NULL)
217    {
218       /* Make writable copy */
219       lpCmdLine = strdup(lpCmdLine);
220    }
221    if (lpCmdLine != NULL)
222    {
223       chomp(lpCmdLine);
224       i = strlen(lpCmdLine);
225       if ((i >= 2) && (lpCmdLine[0] == '\"') && (lpCmdLine[i - 1] == '\"'))
226       {
227          lpCmdLine[i - 1] = '\0';
228          lpCmdLine++;
229       }
230       if (lpCmdLine[0] == '\0')
231       {
232          lpCmdLine = NULL;
233       }
234    }
235
236    GetModuleFileName(hInstance, szModule, MAX_PATH);
237    argv[0] = szModule;
238    argv[1] = lpCmdLine;
239    argv[2] = NULL;
240    argc = ((lpCmdLine != NULL) ? 2 : 1);
241 #endif /* -END- 0 */
242
243
244 #ifndef _WIN_CONSOLE
245    /* Create a user-interface thread and wait for it to initialise */
246    hInitCompleteEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
247    g_hInstance = hInstance;
248    g_nCmdShow = nCmdShow;
249    _beginthread(UserInterfaceThread, 0, &hInitCompleteEvent);
250    WaitForSingleObject(hInitCompleteEvent, INFINITE);
251    DeleteObject(hInitCompleteEvent);
252 #endif
253
254 #ifdef __MINGW32__
255    res = real_main( __argc, __argv );
256 #else
257    res = main( __argc, __argv );
258 #endif
259
260    return res;
261
262 }
263
264 #endif
265
266 /*********************************************************************
267  *
268  * Function    :  InitWin32
269  *
270  * Description :  Initialise windows, setting up the console or windows as appropriate.
271  *
272  * Parameters  :  None
273  *
274  * Returns     :  N/A
275  *
276  *********************************************************************/
277 void InitWin32(void)
278 {
279    WORD wVersionRequested;
280    WSADATA wsaData;
281
282 #ifdef _WIN_CONSOLE
283    SetProcessShutdownParameters(0x100, SHUTDOWN_NORETRY);
284    if (hideConsole)
285    {
286       FreeConsole();
287    }
288 #endif
289    wVersionRequested = MAKEWORD(2, 0);
290    if (WSAStartup(wVersionRequested, &wsaData) != 0)
291    {
292 #ifndef _WIN_CONSOLE
293       MessageBox(NULL, "Cannot initialize WinSock library", "Privoxy Error", 
294          MB_OK | MB_ICONERROR | MB_TASKMODAL | MB_SETFOREGROUND | MB_TOPMOST);  
295 #endif
296       exit(1);
297    }
298
299 }
300
301
302 #ifndef _WIN_CONSOLE
303 #include <signal.h>
304 #include <assert.h>
305
306 #include "win32.h"
307 #include "w32log.h"
308
309
310 /*********************************************************************
311  *
312  * Function    :  UserInterfaceThread
313  *
314  * Description :  User interface thread.  WinMain will wait for us to set
315  *                the hInitCompleteEvent before patching over to `main'.
316  *                This ensures the systray window is active before beginning
317  *                operations.
318  *
319  * Parameters  :
320  *          1  :  pData = pointer to `hInitCompleteEvent'.
321  *
322  * Returns     :  N/A
323  *
324  *********************************************************************/
325 static void __cdecl UserInterfaceThread(void *pData)
326 {
327    MSG msg;
328    HANDLE hInitCompleteEvent = *((HANDLE *) pData);
329
330    /* Initialise */
331    InitLogWindow();
332    SetEvent(hInitCompleteEvent);
333
334    /* Enter a message processing loop */
335    while (GetMessage(&msg, (HWND) NULL, 0, 0))
336    {
337       TranslateMessage(&msg);
338       DispatchMessage(&msg);
339    }
340
341    /* Cleanup */
342    TermLogWindow();
343
344    /* Time to die... */
345    exit(0);
346
347 }
348
349
350 #endif /* ndef _WIN_CONSOLE */
351
352
353 /*
354   Local Variables:
355   tab-width: 3
356   end:
357 */