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