implemented GDB stub for remote debugging
[reactos.git] / reactos / subsys / system / explorer / explorer.cpp
1 /*
2 * Copyright 2003 Martin Fuchs
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18
19
20 //
21 // Explorer clone
22 //
23 // explorer.cpp
24 //
25 // Martin Fuchs, 23.07.2003
26 //
27 // Credits: Thanks to Leon Finker for his explorer window example
28 //
29
30
31 #include "utility/utility.h"
32
33 #include "explorer.h"
34 #include "desktop/desktop.h"
35
36 #include "globals.h"
37 #include "externals.h"
38
39 #include "explorer_intres.h"
40
41 #include <locale.h> // for setlocale()
42
43 #ifndef __WINE__
44 #include <io.h> // for dup2()
45 #include <fcntl.h> // for _O_RDONLY
46 #endif
47
48
49 extern "C" int initialize_gdb_stub(); // start up GDB stub
50
51
52 ExplorerGlobals g_Globals;
53
54
55 ExplorerGlobals::ExplorerGlobals()
56 {
57 _hInstance = 0;
58 _hframeClass = 0;
59 _cfStrFName = 0;
60 _hMainWnd = 0;
61 _prescan_nodes = false;
62 _desktop_mode = false;
63 _log = NULL;
64 #ifndef __MINGW32__ // SHRestricted() missing in MinGW (as of 29.10.2003)
65 _SHRestricted = 0;
66 #endif
67 }
68
69
70 void _log_(LPCTSTR txt)
71 {
72 FmtString msg(TEXT("%s\n"), txt);
73
74 if (g_Globals._log)
75 _fputts(msg, g_Globals._log);
76
77 OutputDebugString(msg);
78 }
79
80
81 ResString::ResString(UINT nid)
82 {
83 TCHAR buffer[BUFFER_LEN];
84
85 int len = LoadString(g_Globals._hInstance, nid, buffer, sizeof(buffer)/sizeof(TCHAR));
86
87 super::assign(buffer, len);
88 }
89
90
91 ResIcon::ResIcon(UINT nid)
92 {
93 _hIcon = LoadIcon(g_Globals._hInstance, MAKEINTRESOURCE(nid));
94 }
95
96 SmallIcon::SmallIcon(UINT nid)
97 {
98 _hIcon = (HICON)LoadImage(g_Globals._hInstance, MAKEINTRESOURCE(nid), IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_SHARED);
99 }
100
101 ResIconEx::ResIconEx(UINT nid, int w, int h)
102 {
103 _hIcon = (HICON)LoadImage(g_Globals._hInstance, MAKEINTRESOURCE(nid), IMAGE_ICON, w, h, LR_SHARED);
104 }
105
106
107 void SetWindowIcon(HWND hwnd, UINT nid)
108 {
109 HICON hIcon = ResIcon(nid);
110 Window_SetIcon(hwnd, ICON_BIG, hIcon);
111
112 HICON hIconSmall = SmallIcon(nid);
113 Window_SetIcon(hwnd, ICON_SMALL, hIconSmall);
114 }
115
116
117 ResBitmap::ResBitmap(UINT nid)
118 {
119 _hBmp = LoadBitmap(g_Globals._hInstance, MAKEINTRESOURCE(nid));
120 }
121
122
123 void explorer_show_frame(HWND hwndDesktop, int cmdshow)
124 {
125 if (g_Globals._hMainWnd)
126 return;
127
128 g_Globals._prescan_nodes = false;
129
130 // create main window
131 HWND hMainFrame = MainFrame::Create();
132
133 if (hMainFrame) {
134 g_Globals._hMainWnd = hMainFrame;
135
136 ShowWindow(hMainFrame, cmdshow);
137 UpdateWindow(hMainFrame);
138
139 // Open the first child window after initializing the whole application
140 PostMessage(hMainFrame, PM_OPEN_WINDOW, OWM_EXPLORE|OWM_DETAILS, 0);
141 }
142 }
143
144
145 static void InitInstance(HINSTANCE hInstance)
146 {
147 CONTEXT("InitInstance");
148
149 setlocale(LC_COLLATE, ""); // set collating rules to local settings for compareName
150
151 // register frame window class
152 g_Globals._hframeClass = IconWindowClass(CLASSNAME_FRAME,IDI_EXPLORER);
153
154 // register child windows class
155 WindowClass(CLASSNAME_CHILDWND, CS_CLASSDC|CS_DBLCLKS|CS_VREDRAW).Register();
156
157 // register tree windows class
158 WindowClass(CLASSNAME_WINEFILETREE, CS_CLASSDC|CS_DBLCLKS|CS_VREDRAW).Register();
159
160 g_Globals._cfStrFName = RegisterClipboardFormat(CFSTR_FILENAME);
161 }
162
163
164 int explorer_main(HINSTANCE hInstance, HWND hwndDesktop, int cmdshow)
165 {
166 CONTEXT("explorer_main");
167
168 // initialize COM and OLE
169 OleInit usingCOM;
170
171 // initialize Common Controls library
172 CommonControlInit usingCmnCtrl;
173
174 try {
175 InitInstance(hInstance);
176 } catch(COMException& e) {
177 HandleException(e, hwndDesktop);
178 return -1;
179 }
180
181 if (hwndDesktop)
182 g_Globals._desktop_mode = true;
183
184 if (cmdshow != SW_HIDE) {
185 /* // don't maximize if being called from the ROS desktop
186 if (cmdshow == SW_SHOWNORMAL)
187 ///@todo read window placement from registry
188 cmdshow = SW_MAXIMIZE;
189 */
190
191 explorer_show_frame(hwndDesktop, cmdshow);
192 }
193
194 return Window::MessageLoop();
195 }
196
197
198 // MinGW does not provide a Unicode startup routine, so we have to implement an own.
199 #if defined(__MINGW32__) && defined(UNICODE)
200
201 #define _tWinMain wWinMain
202 int WINAPI wWinMain(HINSTANCE, HINSTANCE, LPWSTR, int);
203
204 int main(int argc, char* argv[])
205 {
206 CONTEXT("main");
207
208 STARTUPINFO startupinfo;
209 int nShowCmd = SW_SHOWNORMAL;
210
211 GetStartupInfo(&startupinfo);
212
213 if (startupinfo.dwFlags & STARTF_USESHOWWINDOW)
214 nShowCmd = startupinfo.wShowWindow;
215
216 return wWinMain(GetModuleHandle(NULL), 0, GetCommandLine(), nShowCmd);
217 }
218
219 #endif // __MINGW && UNICODE
220
221
222 int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nShowCmd)
223 {
224 CONTEXT("WinMain()");
225
226 // create desktop window and task bar only, if there is no other shell and we are
227 // the first explorer instance
228 BOOL startup_desktop = !IsAnyDesktopRunning();
229
230 bool autostart = true;
231
232 #ifdef _DEBUG //MF: disabled for debugging
233 autostart = false;
234 #endif
235
236 // If there is given the command line option "-desktop", create desktop window anyways
237 if (_tcsstr(lpCmdLine,TEXT("-desktop")))
238 startup_desktop = TRUE;
239
240 if (_tcsstr(lpCmdLine,TEXT("-nodesktop")))
241 startup_desktop = FALSE;
242
243 if (_tcsstr(lpCmdLine,TEXT("-noexplorer"))) {
244 nShowCmd = SW_HIDE;
245 startup_desktop = TRUE;
246 }
247
248 if (_tcsstr(lpCmdLine,TEXT("-noautostart")))
249 autostart = false;
250
251 #ifndef __WINE__
252 if (_tcsstr(lpCmdLine,TEXT("-console"))) {
253 AllocConsole();
254
255 _dup2(_open_osfhandle((long)GetStdHandle(STD_INPUT_HANDLE), _O_RDONLY), 0);
256 _dup2(_open_osfhandle((long)GetStdHandle(STD_OUTPUT_HANDLE), 0), 1);
257 _dup2(_open_osfhandle((long)GetStdHandle(STD_ERROR_HANDLE), 0), 2);
258
259 g_Globals._log = fdopen(1, "w");
260 setvbuf(g_Globals._log, 0, _IONBF, 0);
261
262 LOG(TEXT("starting explorer debug log\n"));
263 }
264 #endif
265
266 bool use_gdb_stub = false; // !IsDebuggerPresent();
267
268 if (_tcsstr(lpCmdLine,TEXT("-debug")))
269 use_gdb_stub = true;
270
271 // activate GDB remote debugging stub if no other debugger is running
272 if (use_gdb_stub) {
273 LOG(TEXT("waiting for debugger connection...\n"));
274
275 initialize_gdb_stub();
276 }
277
278 g_Globals._hInstance = hInstance;
279 #ifndef __MINGW32__ // SHRestricted() missing in MinGW (as of 29.10.2003)
280 g_Globals._SHRestricted = (DWORD(STDAPICALLTYPE*)(RESTRICTIONS)) GetProcAddress(GetModuleHandle(TEXT("SHELL32")), "SHRestricted");
281 #endif
282
283 HWND hwndDesktop = 0;
284
285 if (startup_desktop)
286 {
287 hwndDesktop = DesktopWindow::Create();
288
289 if (autostart)
290 {
291 char* argv[] = {"", "s"}; // call startup routine in SESSION_START mode
292 startup(2, argv);
293 }
294 }
295
296 int ret = explorer_main(hInstance, hwndDesktop, nShowCmd);
297
298 return ret;
299 }