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