1 /*********************************************************************
3 * File : $Source: /cvsroot/ijbswa/current/win32.c,v $
5 * Purpose : Win32 User Interface initialization and message loop
7 * Copyright : Written by and Copyright (C) 2001-2002 members of
8 * the Privoxy team. https://www.privoxy.org/
10 * Written by and Copyright (C) 1999 Adam Lock
13 * This program is free software; you can redistribute it
14 * and/or modify it under the terms of the GNU General
15 * Public License as published by the Free Software
16 * Foundation; either version 2 of the License, or (at
17 * your option) any later version.
19 * This program is distributed in the hope that it will
20 * be useful, but WITHOUT ANY WARRANTY; without even the
21 * implied warranty of MERCHANTABILITY or FITNESS FOR A
22 * PARTICULAR PURPOSE. See the GNU General Public
23 * License for more details.
25 * The GNU General Public License should be included with
26 * this file. If not, you can view it at
27 * http://www.gnu.org/copyleft/gpl.html
28 * or write to the Free Software Foundation, Inc., 59
29 * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
31 *********************************************************************/
44 /* Uncomment this if you want to build Win32 as a console app */
45 /* #define _WIN_CONSOLE */
55 #if defined(_WIN32) && defined(_MSC_VER) && defined(_DEBUG)
56 /* Visual C++ Heap debugging */
58 #endif /* defined(_WIN32) && defined(_MSC_VER) && defined(_DEBUG) */
63 * A short introductory text about Privoxy. Used for the "About" box
64 * or the console startup message.
66 const char win32_blurb[] =
67 "Privoxy version " VERSION " for Windows\n"
68 "Copyright (C) 2000-2023 the Privoxy Team (" HOME_PAGE_URL ")\n"
69 "Based on the Internet Junkbuster by Junkbusters Corp.\n"
70 "This is free software; it may be used and copied under the\n"
71 "GNU General Public License, version 2: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html\n"
72 "This program comes with ABSOLUTELY NO WARRANTY OF ANY KIND.\n";
77 * Hide the console. If set, the program will disconnect from the
78 * console and run in the background. This allows the command-prompt
84 #else /* ndef _WIN_CONSOLE */
88 * The application instance handle.
90 HINSTANCE g_hInstance;
94 * The command to show the window that was specified at startup.
98 static void __cdecl UserInterfaceThread(void *);
101 #endif /* ndef _WIN_CONSOLE */
103 /*********************************************************************
107 * Description : M$ Windows "main" routine:
108 * parse the `lpCmdLine' param into main's argc and argv variables,
109 * start the user interface thread (for the systray window), and
110 * call main (i.e. patch execution into normal startup).
113 * 1 : hInstance = instance handle of this execution
114 * 2 : hPrevInstance = instance handle of previous execution
115 * 3 : lpCmdLine = command line string which started us
116 * 4 : nCmdShow = window show value (MIN, MAX, NORMAL, etc...)
118 * Returns : `main' never returns, so WinMain will also never return.
120 *********************************************************************/
121 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
123 #if 0 /* See comment about __argc & __argv below */
127 char szModule[MAX_PATH+1];
132 HANDLE hInitCompleteEvent = NULL;
136 #if defined(_WIN32) && defined(_MSC_VER) && defined(_DEBUG)
138 /* Visual C++ Heap debugging */
140 /* Get current flag*/
141 int tmpFlag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
143 /* Turn on leak-checking bit */
144 tmpFlag |= _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF | _CRTDBG_CHECK_ALWAYS_DF;
146 /* Turn off CRT block checking bit */
147 tmpFlag &= ~(_CRTDBG_CHECK_CRT_DF | _CRTDBG_DELAY_FREE_MEM_DF);
149 /* Set flag to the new value */
150 _CrtSetDbgFlag(tmpFlag);
152 #endif /* defined(_WIN32) && defined(_MSC_VER) && defined(_DEBUG) */
156 * I couldn't figure out why the command line was being sorta parsed here
157 * instead of using the __argc & __argv globals usually defined in stdlib.h
159 * From what I can tell by looking at the MinWG source, it supports these
160 * globals, so i'd hope that the other compilers do so as well.
161 * Obviously, if i'm wrong i'll find out soon enough! :)
165 * Cheat in parsing the command line. We only ever have at most one
166 * parameter, which may optionally be specified inside double quotes.
169 if (lpCmdLine != NULL)
171 /* Make writable copy */
172 lpCmdLine = strdup(lpCmdLine);
174 if (lpCmdLine != NULL)
177 i = strlen(lpCmdLine);
178 if ((i >= 2) && (lpCmdLine[0] == '\"') && (lpCmdLine[i - 1] == '\"'))
180 lpCmdLine[i - 1] = '\0';
183 if (lpCmdLine[0] == '\0')
189 GetModuleFileName(hInstance, szModule, MAX_PATH);
193 argc = ((lpCmdLine != NULL) ? 2 : 1);
198 /* Create a user-interface thread and wait for it to initialise */
199 hInitCompleteEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
200 g_hInstance = hInstance;
201 g_nCmdShow = nCmdShow;
202 _beginthread(UserInterfaceThread, 0, &hInitCompleteEvent);
203 WaitForSingleObject(hInitCompleteEvent, INFINITE);
204 CloseHandle(hInitCompleteEvent);
208 res = real_main(__argc, __argv);
210 res = main(__argc, __argv);
219 /*********************************************************************
221 * Function : InitWin32
223 * Description : Initialise windows, setting up the console or windows as appropriate.
229 *********************************************************************/
232 WORD wVersionRequested;
236 SetProcessShutdownParameters(0x100, SHUTDOWN_NORETRY);
242 wVersionRequested = MAKEWORD(2, 0);
243 if (WSAStartup(wVersionRequested, &wsaData) != 0)
246 MessageBox(NULL, "Cannot initialize WinSock library", "Privoxy Error",
247 MB_OK | MB_ICONERROR | MB_TASKMODAL | MB_SETFOREGROUND | MB_TOPMOST);
263 /*********************************************************************
265 * Function : UserInterfaceThread
267 * Description : User interface thread. WinMain will wait for us to set
268 * the hInitCompleteEvent before patching over to `main'.
269 * This ensures the systray window is active before beginning
273 * 1 : pData = pointer to `hInitCompleteEvent'.
277 *********************************************************************/
278 static void __cdecl UserInterfaceThread(void *pData)
281 HANDLE hInitCompleteEvent = *((HANDLE *) pData);
285 SetEvent(hInitCompleteEvent);
287 /* Enter a message processing loop */
288 while (GetMessage(&msg, (HWND) NULL, 0, 0))
290 TranslateMessage(&msg);
291 DispatchMessage(&msg);
303 #endif /* ndef _WIN_CONSOLE */