win32: use #ifdef _WIN32
[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 #ifdef _WIN32
42
43 #include "stdafx.h"
44 #include "Frontend.h"
45 #include "FrontendDlg.h"
46 #include "TrayIcon.h"
47
48 #ifdef _DEBUG
49 #define new DEBUG_NEW
50 #undef THIS_FILE
51 static char THIS_FILE[] = __FILE__;
52 #endif /* _DEBUG */
53
54 BEGIN_MESSAGE_MAP(CFrontendApp, CWinApp)
55         //{{AFX_MSG_MAP(CFrontendApp)
56         //}}AFX_MSG
57         ON_COMMAND(ID_HELP, CWinApp::OnHelp)
58 END_MESSAGE_MAP()
59
60 CFrontendApp::CFrontendApp()
61 {
62 }
63
64 CFrontendApp theApp;
65
66 static int SetEnableRedirKey(unsigned long New)
67 {
68         HKEY Key;
69         unsigned long Type;
70         unsigned long Len;
71         unsigned long Old;
72         
73         if (::RegOpenKeyEx(HKEY_LOCAL_MACHINE,
74                 "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters",
75                 0, KEY_READ | KEY_WRITE, &Key) != ERROR_SUCCESS)
76                 return -1;
77         
78         Len = sizeof (Old);
79         
80         if (::RegQueryValueEx(Key, "EnableICMPRedirect", NULL, &Type,
81                 (unsigned char *)&Old, &Len) != ERROR_SUCCESS ||
82                 Type != REG_DWORD)
83                 Old = 1;
84         
85         if (::RegSetValueEx(Key, "EnableICMPRedirect", 0, REG_DWORD,
86                 (unsigned char *)&New, sizeof (New)))
87         {
88                 ::RegCloseKey(Key);
89                 return -1;
90         }
91         
92         ::RegCloseKey(Key);
93         return Old;
94 }
95
96 BOOL CFrontendApp::InitInstance()
97 {
98         int Res;
99
100         CCommandLineInfo CmdLineInfo;
101         ParseCommandLine(CmdLineInfo);
102
103         CFrontendDlg dlg;
104
105         tray_icon = new TrayIcon( dlg, AfxGetInstanceHandle() );
106
107         dlg.ConfigFile = CmdLineInfo.m_strFileName;
108
109         m_pMainWnd = &dlg;
110
111         Res = SetEnableRedirKey(0);
112
113         if (Res == 1)
114         {
115                 Res = AfxMessageBox("- WARNING -\n\n"
116                         "The OLSR software has just switched off the processing of incoming ICMP "
117                         " redirect messages in your registry.\n\n"
118                         " Please REBOOT your computer for this change to take effect.\n\n"
119                         " Do you want to allow the OLSR software to reboot your computer now?\n\n"
120                         " (Please say \"Yes\".)", MB_YESNO | MB_ICONEXCLAMATION);
121
122                 if (Res == IDYES)
123                 {
124                         HANDLE Proc;
125                         HMODULE Lib;
126                         BOOL (*Open)(HANDLE, DWORD, HANDLE *);
127                         BOOL (*Lookup)(char *, char *, LUID *);
128                         BOOL (*Adjust)(HANDLE, BOOL, TOKEN_PRIVILEGES *, DWORD,
129                                 TOKEN_PRIVILEGES *, DWORD *);
130                         HANDLE Token;
131
132                         Proc = ::GetCurrentProcess();
133
134                         Lib = ::LoadLibrary("advapi32.dll");
135
136                         if (Lib != NULL)
137                         {
138                                 Open = (BOOL (*)(HANDLE, DWORD, HANDLE *))
139                                         ::GetProcAddress(Lib, "OpenProcessToken");
140
141                                 Lookup = (BOOL (*)(char *, char *, LUID *))
142                                         ::GetProcAddress(Lib, "LookupPrivilegeValueA");
143
144                                 Adjust = (BOOL (*)(HANDLE, BOOL, TOKEN_PRIVILEGES *, DWORD,
145                                         TOKEN_PRIVILEGES *, DWORD *))
146                                         ::GetProcAddress(Lib, "AdjustTokenPrivileges");
147
148                                 if (Open != NULL && Lookup != NULL && Adjust != NULL)
149                                 {
150                                         struct
151                                         {
152                                                 DWORD Count;
153                                                 LUID_AND_ATTRIBUTES Priv;
154                                         }
155                                         TokPriv;
156
157                                         Proc = ::GetCurrentProcess();
158
159                                         if (!Open(Proc, TOKEN_ALL_ACCESS, &Token))
160                                                 AfxMessageBox("OpenProcessToken() failed.");
161
162                                         else if (!Lookup("", "SeShutdownPrivilege", &TokPriv.Priv.Luid))
163                                                 AfxMessageBox("LookupPrivilegeValue() failed.");
164
165                                         else
166                                         {
167                                                 TokPriv.Count = 1;
168                                                 TokPriv.Priv.Attributes = SE_PRIVILEGE_ENABLED;
169
170                                                 if (!Adjust(Token, FALSE, (TOKEN_PRIVILEGES *)&TokPriv,
171                                                         0, NULL, NULL))
172                                                         AfxMessageBox("AdjustTokenPrivilege() failed.");
173                                         }
174                                 }
175
176                                 ::FreeLibrary(Lib);
177                         }
178
179                         ::ExitWindowsEx(EWX_REBOOT, 0);
180                         ::TerminateProcess(Proc, 0);
181                 }
182         }
183
184         RedirectStdHandles();
185
186         dlg.DoModal();
187
188         return FALSE;
189 }
190
191 unsigned int CFrontendApp::RedirectThreadFunc(void)
192 {
193         char Buff[1000];
194         int Len;
195         int Left, Right;
196         CString Line;
197         CString Int;
198
199         while (::ReadFile(OutRead, Buff, sizeof (Buff) - 1, (unsigned long *)&Len, NULL))
200         {
201                 if (Len == 0)
202                         break;
203
204                 Left = 0;
205
206                 for (Right = 0; Right < Len; Right++)
207                 {
208                         if (Buff[Right] != 13)
209                                 Buff[Left++] = Buff[Right];
210                 }
211
212                 Len = Left;
213
214                 Left = 0;
215
216                 for (Right = 0; Right < Len; Right++)
217                 {
218                         if (Buff[Right] == 10)
219                         {
220                                 Buff[Right] = 0;
221                                 Line += (Buff + Left);
222
223                                 AfxMessageBox(Line);
224
225                                 Line.Empty();
226
227                                 Left = Right + 1;
228                         }
229                 }
230
231                 Buff[Right] = 0;
232                 Line += (Buff + Left);
233         }
234
235         AfxEndThread(0);
236         return 0;
237 }
238
239 static unsigned int RedirectThreadStub(void *Arg)
240 {
241         class CFrontendApp *This;
242
243         This = (class CFrontendApp *)Arg;
244
245         return This->RedirectThreadFunc();
246 }
247
248 struct IoInfo
249 {
250         HANDLE Hand;
251         unsigned char Attr;
252         char Buff;
253 #if defined _MT
254         int Flag;
255         CRITICAL_SECTION Lock;
256 #endif
257 };
258
259 extern "C" struct IoInfo *__pioinfo[];
260
261 int CFrontendApp::RedirectStdHandles(void)
262 {
263         SECURITY_ATTRIBUTES SecAttr;
264         HANDLE OutWrite;
265         struct IoInfo *Info;
266
267         SecAttr.nLength = sizeof (SECURITY_ATTRIBUTES);
268         SecAttr.lpSecurityDescriptor = NULL;
269         SecAttr.bInheritHandle = TRUE;
270
271         if (!::CreatePipe(&OutRead, &OutWrite, &SecAttr, 0))
272         {
273                 AfxMessageBox("Cannot create stdout pipe.");
274                 return -1;
275         }
276
277         AfxBeginThread(RedirectThreadStub, (void *)this);
278
279         Info = __pioinfo[0];
280
281         // Info[1].Hand = OutWrite;
282         // Info[1].Attr = 0x89; // FOPEN | FTEXT | FPIPE;
283
284         Info[2].Hand = OutWrite;
285         Info[2].Attr = 0x89;
286
287         // stdout->_file = 1;
288         stderr->_file = 2;
289
290         win32_stdio_hack((unsigned int)OutWrite);
291
292         return 0;
293 }
294
295 #endif /* _WIN32 */