We now use a hack on Win32 that redirects stderr to a GUI thread that
[olsrd.git] / gui / win32 / Main / Frontend.cpp
1 /*\r
2  * The olsr.org Optimized Link-State Routing daemon (olsrd)\r
3  * Copyright (c) 2004, Thomas Lopatic (thomas@lopatic.de)\r
4  * All rights reserved.\r
5  *\r
6  * Redistribution and use in source and binary forms, with or without \r
7  * modification, are permitted provided that the following conditions \r
8  * are met:\r
9  *\r
10  * * Redistributions of source code must retain the above copyright \r
11  *   notice, this list of conditions and the following disclaimer.\r
12  * * Redistributions in binary form must reproduce the above copyright \r
13  *   notice, this list of conditions and the following disclaimer in \r
14  *   the documentation and/or other materials provided with the \r
15  *   distribution.\r
16  * * Neither the name of olsr.org, olsrd nor the names of its \r
17  *   contributors may be used to endorse or promote products derived \r
18  *   from this software without specific prior written permission.\r
19  *\r
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \r
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT \r
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS \r
23  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE \r
24  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, \r
25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, \r
26  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; \r
27  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER \r
28  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT \r
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN \r
30  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE \r
31  * POSSIBILITY OF SUCH DAMAGE.\r
32  *\r
33  * Visit http://www.olsr.org for more information.\r
34  *\r
35  * If you find this software useful feel free to make a donation\r
36  * to the project. For more information see the website or contact\r
37  * the copyright holders.\r
38  *\r
39  * $Id: Frontend.cpp,v 1.6 2004/11/21 17:10:27 tlopatic Exp $\r
40  */\r
41 \r
42 #include "stdafx.h"\r
43 #include "Frontend.h"\r
44 #include "FrontendDlg.h"\r
45 \r
46 #ifdef _DEBUG\r
47 #define new DEBUG_NEW\r
48 #undef THIS_FILE\r
49 static char THIS_FILE[] = __FILE__;\r
50 #endif\r
51 \r
52 BEGIN_MESSAGE_MAP(CFrontendApp, CWinApp)\r
53         //{{AFX_MSG_MAP(CFrontendApp)\r
54         //}}AFX_MSG\r
55         ON_COMMAND(ID_HELP, CWinApp::OnHelp)\r
56 END_MESSAGE_MAP()\r
57 \r
58 CFrontendApp::CFrontendApp()\r
59 {\r
60 }\r
61 \r
62 CFrontendApp theApp;\r
63 \r
64 static int SetEnableRedirKey(unsigned long New)\r
65 {\r
66         HKEY Key;\r
67         unsigned long Type;\r
68         unsigned long Len;\r
69         unsigned long Old;\r
70         \r
71         if (::RegOpenKeyEx(HKEY_LOCAL_MACHINE,\r
72                 "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters",\r
73                 0, KEY_READ | KEY_WRITE, &Key) != ERROR_SUCCESS)\r
74                 return -1;\r
75         \r
76         Len = sizeof (Old);\r
77         \r
78         if (::RegQueryValueEx(Key, "EnableICMPRedirect", NULL, &Type,\r
79                 (unsigned char *)&Old, &Len) != ERROR_SUCCESS ||\r
80                 Type != REG_DWORD)\r
81                 Old = 1;\r
82         \r
83         if (::RegSetValueEx(Key, "EnableICMPRedirect", 0, REG_DWORD,\r
84                 (unsigned char *)&New, sizeof (New)))\r
85         {\r
86                 ::RegCloseKey(Key);\r
87                 return -1;\r
88         }\r
89         \r
90         ::RegCloseKey(Key);\r
91         return Old;\r
92 }\r
93 \r
94 BOOL CFrontendApp::InitInstance()\r
95 {\r
96         int Res;\r
97 \r
98 #ifdef _AFXDLL\r
99         Enable3dControls();\r
100 #else\r
101         Enable3dControlsStatic();\r
102 #endif\r
103 \r
104         CCommandLineInfo CmdLineInfo;\r
105         ParseCommandLine(CmdLineInfo);\r
106 \r
107         CFrontendDlg dlg;\r
108 \r
109         dlg.ConfigFile = CmdLineInfo.m_strFileName;\r
110 \r
111         m_pMainWnd = &dlg;\r
112 \r
113         Res = SetEnableRedirKey(0);\r
114 \r
115         if (Res == 1)\r
116         {\r
117                 Res = AfxMessageBox("- WARNING -\n\n"\r
118                         "The OLSR software has just switched off the processing of incoming ICMP "\r
119                         " redirect messages in your registry.\n\n"\r
120                         " Please REBOOT your computer for this change to take effect.\n\n"\r
121                         " Do you want to allow the OLSR software to reboot your computer now?\n\n"\r
122                         " (Please say \"Yes\".)", MB_YESNO | MB_ICONEXCLAMATION);\r
123 \r
124                 if (Res == IDYES)\r
125                 {\r
126                         HANDLE Proc;\r
127                         HMODULE Lib;\r
128                         BOOL (*Open)(HANDLE, DWORD, HANDLE *);\r
129                         BOOL (*Lookup)(char *, char *, LUID *);\r
130                         BOOL (*Adjust)(HANDLE, BOOL, TOKEN_PRIVILEGES *, DWORD,\r
131                                 TOKEN_PRIVILEGES *, DWORD *);\r
132                         HANDLE Token;\r
133 \r
134                         Proc = ::GetCurrentProcess();\r
135 \r
136                         Lib = ::LoadLibrary("advapi32.dll");\r
137 \r
138                         if (Lib != NULL)\r
139                         {\r
140                                 Open = (BOOL (*)(HANDLE, DWORD, HANDLE *))\r
141                                         ::GetProcAddress(Lib, "OpenProcessToken");\r
142 \r
143                                 Lookup = (BOOL (*)(char *, char *, LUID *))\r
144                                         ::GetProcAddress(Lib, "LookupPrivilegeValueA");\r
145 \r
146                                 Adjust = (BOOL (*)(HANDLE, BOOL, TOKEN_PRIVILEGES *, DWORD,\r
147                                         TOKEN_PRIVILEGES *, DWORD *))\r
148                                         ::GetProcAddress(Lib, "AdjustTokenPrivileges");\r
149 \r
150                                 if (Open != NULL && Lookup != NULL && Adjust != NULL)\r
151                                 {\r
152                                         struct\r
153                                         {\r
154                                                 DWORD Count;\r
155                                                 LUID_AND_ATTRIBUTES Priv;\r
156                                         }\r
157                                         TokPriv;\r
158 \r
159                                         Proc = ::GetCurrentProcess();\r
160 \r
161                                         if (!Open(Proc, TOKEN_ALL_ACCESS, &Token))\r
162                                                 AfxMessageBox("OpenProcessToken() failed.");\r
163 \r
164                                         else if (!Lookup("", "SeShutdownPrivilege", &TokPriv.Priv.Luid))\r
165                                                 AfxMessageBox("LookupPrivilegeValue() failed.");\r
166 \r
167                                         else\r
168                                         {\r
169                                                 TokPriv.Count = 1;\r
170                                                 TokPriv.Priv.Attributes = SE_PRIVILEGE_ENABLED;\r
171 \r
172                                                 if (!Adjust(Token, FALSE, (TOKEN_PRIVILEGES *)&TokPriv,\r
173                                                         0, NULL, NULL))\r
174                                                         AfxMessageBox("AdjustTokenPrivilege() failed.");\r
175                                         }\r
176                                 }\r
177 \r
178                                 ::FreeLibrary(Lib);\r
179                         }\r
180 \r
181                         ::ExitWindowsEx(EWX_REBOOT, 0);\r
182                         ::TerminateProcess(Proc, 0);\r
183                 }\r
184         }\r
185 \r
186         RedirectStdHandles();\r
187 \r
188         dlg.DoModal();\r
189 \r
190         return FALSE;\r
191 }\r
192 \r
193 unsigned int CFrontendApp::RedirectThreadFunc(void)\r
194 {\r
195         char Buff[1000];\r
196         int Len;\r
197         int Left, Right;\r
198         CString Line;\r
199         CString Int;\r
200 \r
201         while (::ReadFile(OutRead, Buff, sizeof (Buff) - 1, (unsigned long *)&Len, NULL))\r
202         {\r
203                 if (Len == 0)\r
204                         break;\r
205 \r
206                 Left = 0;\r
207 \r
208                 for (Right = 0; Right < Len; Right++)\r
209                 {\r
210                         if (Buff[Right] != 13)\r
211                                 Buff[Left++] = Buff[Right];\r
212                 }\r
213 \r
214                 Len = Left;\r
215 \r
216                 Left = 0;\r
217 \r
218                 for (Right = 0; Right < Len; Right++)\r
219                 {\r
220                         if (Buff[Right] == 10)\r
221                         {\r
222                                 Buff[Right] = 0;\r
223                                 Line += (Buff + Left);\r
224 \r
225                                 AfxMessageBox(Line);\r
226 \r
227                                 Line.Empty();\r
228 \r
229                                 Left = Right + 1;\r
230                         }\r
231                 }\r
232 \r
233                 Buff[Right] = 0;\r
234                 Line += (Buff + Left);\r
235         }\r
236 \r
237         AfxEndThread(0);\r
238         return 0;\r
239 }\r
240 \r
241 static unsigned int RedirectThreadStub(void *Arg)\r
242 {\r
243         class CFrontendApp *This;\r
244 \r
245         This = (class CFrontendApp *)Arg;\r
246 \r
247         return This->RedirectThreadFunc();\r
248 }\r
249 \r
250 struct IoInfo\r
251 {\r
252         HANDLE Hand;\r
253         unsigned char Attr;\r
254         char Buff;\r
255 #if defined _MT\r
256         int Flag;\r
257         CRITICAL_SECTION Lock;\r
258 #endif\r
259 };\r
260 \r
261 extern "C" struct IoInfo *__pioinfo[];\r
262 \r
263 extern "C" void win32_stdio_hack(unsigned int handle);\r
264 \r
265 int CFrontendApp::RedirectStdHandles(void)\r
266 {\r
267         SECURITY_ATTRIBUTES SecAttr;\r
268         HANDLE OutWrite;\r
269         struct IoInfo *Info;\r
270 \r
271         SecAttr.nLength = sizeof (SECURITY_ATTRIBUTES);\r
272         SecAttr.lpSecurityDescriptor = NULL;\r
273         SecAttr.bInheritHandle = TRUE;\r
274 \r
275         if (!::CreatePipe(&OutRead, &OutWrite, &SecAttr, 0))\r
276         {\r
277                 AfxMessageBox("Cannot create stdout pipe.");\r
278                 return -1;\r
279         }\r
280 \r
281         AfxBeginThread(RedirectThreadStub, (void *)this);\r
282 \r
283         Info = __pioinfo[0];\r
284 \r
285         // Info[1].Hand = OutWrite;\r
286         // Info[1].Attr = 0x89; // FOPEN | FTEXT | FPIPE;\r
287 \r
288         Info[2].Hand = OutWrite;\r
289         Info[2].Attr = 0x89;\r
290 \r
291         // stdout->_file = 1;\r
292         stderr->_file = 2;\r
293 \r
294         win32_stdio_hack((unsigned int)OutWrite);\r
295 \r
296         return 0;\r
297 }\r