Install freeloader installer.
[reactos.git] / reactos / boot / freeldr / fdebug / fdebug.c
1 // fdebug.cpp : Defines the entry point for the application.
2 //
3
4 #include <windows.h>
5 #include <commdlg.h>
6 #include <process.h>
7 #include <stdio.h>
8 #include <tchar.h>
9
10 #include "resource.h"
11 #include "rs232.h"
12
13 #define MAX_LOADSTRING 100
14
15 // Global Variables:
16 HINSTANCE hInst; // current instance
17 TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
18 TCHAR szWindowClass[MAX_LOADSTRING]; // The title bar text
19 HWND hMainWnd; // The main window handle
20 HWND hDisplayWnd; // The window to display the incoming data
21 HWND hEditWnd; // The edit window to get input from the user
22 TCHAR strComPort[MAX_PATH] = TEXT("COM1"); // The COM port to use
23 TCHAR strBaudRate[MAX_PATH] = TEXT("115200"); // The baud rate to use
24 TCHAR strCaptureFileName[MAX_PATH] = TEXT(""); // The file name to capture to
25 BOOL bConnected = FALSE; // Tells us if we are currently connected
26 BOOL bCapturing = FALSE; // Tells us if we are currently capturing data
27 BOOL bLocalEcho = FALSE; // Tells us if local echo is currently enabled
28 HANDLE hCaptureFile; // Handle to the capture file
29 DWORD dwThreadId = 0; // Thread id of RS232 communication thread
30
31 // Foward declarations of functions included in this code module:
32 ATOM MyRegisterClass(HINSTANCE hInstance);
33 BOOL InitInstance(HINSTANCE, int);
34 LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
35 LRESULT CALLBACK About(HWND, UINT, WPARAM, LPARAM);
36 LRESULT CALLBACK ConnectionDialogProc(HWND, UINT, WPARAM, LPARAM);
37 LRESULT CALLBACK CaptureDialogProc(HWND, UINT, WPARAM, LPARAM);
38 VOID EnableConnectMenuItem(BOOL Enable);
39 VOID EnableDisconnectMenuItem(BOOL Enable);
40 VOID EnableStartCaptureMenuItem(BOOL Enable);
41 VOID EnableStopCaptureMenuItem(BOOL Enable);
42 VOID CheckLocalEchoMenuItem(BOOL Checked);
43 VOID Rs232Thread(VOID* Parameter);
44
45 int APIENTRY WinMain(HINSTANCE hInstance,
46 HINSTANCE hPrevInstance,
47 LPSTR lpCmdLine,
48 int nCmdShow)
49 {
50 // TODO: Place code here.
51 MSG msg;
52 HACCEL hAccelTable;
53
54 // Initialize global strings
55 LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
56 LoadString(hInstance, IDC_FDEBUG, szWindowClass, MAX_LOADSTRING);
57 MyRegisterClass(hInstance);
58
59 // Perform application initialization:
60 if (!InitInstance (hInstance, nCmdShow))
61 {
62 return FALSE;
63 }
64
65 hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_FDEBUG);
66
67 // Main message loop:
68 while (GetMessage(&msg, NULL, 0, 0))
69 {
70 if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
71 {
72 TranslateMessage(&msg);
73 DispatchMessage(&msg);
74 }
75 }
76
77 return msg.wParam;
78 }
79
80
81
82 //
83 // FUNCTION: MyRegisterClass()
84 //
85 // PURPOSE: Registers the window class.
86 //
87 // COMMENTS:
88 //
89 // This function and its usage is only necessary if you want this code
90 // to be compatible with Win32 systems prior to the 'RegisterClassEx'
91 // function that was added to Windows 95. It is important to call this function
92 // so that the application will get 'well formed' small icons associated
93 // with it.
94 //
95 ATOM MyRegisterClass(HINSTANCE hInstance)
96 {
97 WNDCLASSEX wcex;
98
99 wcex.cbSize = sizeof(WNDCLASSEX);
100
101 wcex.style = CS_HREDRAW | CS_VREDRAW;
102 wcex.lpfnWndProc = (WNDPROC)WndProc;
103 wcex.cbClsExtra = 0;
104 wcex.cbWndExtra = 0;
105 wcex.hInstance = hInstance;
106 wcex.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_FDEBUG);
107 wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
108 wcex.hbrBackground = NULL;//(HBRUSH)(COLOR_WINDOW+1);
109 wcex.lpszMenuName = (LPCSTR)IDC_FDEBUG;
110 wcex.lpszClassName = szWindowClass;
111 wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);
112
113 return RegisterClassEx(&wcex);
114 }
115
116 //
117 // FUNCTION: InitInstance(HANDLE, int)
118 //
119 // PURPOSE: Saves instance handle and creates main window
120 //
121 // COMMENTS:
122 //
123 // In this function, we save the instance handle in a global variable and
124 // create and display the main program window.
125 //
126 BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
127 {
128 HWND hWnd;
129
130 hInst = hInstance; // Store instance handle in our global variable
131
132 hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
133 CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
134
135 if (!hWnd)
136 {
137 return FALSE;
138 }
139
140 hMainWnd = hWnd;
141
142 ShowWindow(hWnd, nCmdShow);
143 UpdateWindow(hWnd);
144
145 return TRUE;
146 }
147
148 LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
149 {
150 int wmId, wmEvent;
151 PAINTSTRUCT ps;
152 HDC hdc;
153 RECT rc;
154 TCHAR WndText[MAX_PATH];
155 DWORD Index;
156 NONCLIENTMETRICS ncm;
157 HFONT hFont;
158
159 switch (message)
160 {
161 case WM_CREATE:
162
163 hEditWnd = CreateWindowEx(WS_EX_CLIENTEDGE, TEXT("EDIT"), "", WS_CHILD|WS_VISIBLE|WS_VSCROLL|ES_AUTOHSCROLL|ES_LEFT|ES_MULTILINE, 0, 0, 0, 0, hWnd, NULL, hInst, NULL);
164 hDisplayWnd = CreateWindowEx(WS_EX_CLIENTEDGE, TEXT("EDIT"), "", WS_CHILD|WS_VISIBLE|WS_HSCROLL|WS_VSCROLL|ES_MULTILINE, 0, 0, 0, 0, hWnd, NULL, hInst, NULL);
165
166 memset(&ncm, 0, sizeof(NONCLIENTMETRICS));
167 ncm.cbSize = sizeof(NONCLIENTMETRICS);
168 SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &ncm, 0);
169
170 hFont = CreateFontIndirect(&ncm.lfMessageFont);
171
172 SendMessage(hEditWnd, WM_SETFONT, (WPARAM)hFont, TRUE);
173 SendMessage(hDisplayWnd, WM_SETFONT, (WPARAM)hFont, TRUE);
174
175 break;
176 case WM_COMMAND:
177 wmId = LOWORD(wParam);
178 wmEvent = HIWORD(wParam);
179
180 if (lParam == (LPARAM)hEditWnd && wmEvent == EN_CHANGE)
181 {
182 GetWindowText(hEditWnd, WndText, MAX_PATH);
183
184 if (_tcslen(WndText) > 0)
185 {
186 SetWindowText(hEditWnd, TEXT(""));
187
188 if (!bConnected)
189 {
190 MessageBox(hWnd, TEXT("You are not currently connected!"), TEXT("Error"), MB_OK|MB_ICONSTOP);
191 break;
192 }
193
194 for (Index=0; Index<_tcslen(WndText); Index++)
195 {
196 if (dwThreadId != 0)
197 {
198 PostThreadMessage(dwThreadId, WM_CHAR, (WPARAM)WndText[Index], (LPARAM)0);
199 }
200 }
201 }
202 }
203
204 // Parse the menu selections:
205 switch (wmId)
206 {
207 case IDM_ABOUT:
208 DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
209 break;
210 case IDM_EXIT:
211 DestroyWindow(hWnd);
212 break;
213 case ID_FILE_CONNECT:
214 if (bConnected)
215 {
216 MessageBox(hWnd, TEXT("You are already connected!"), TEXT("Error"), MB_OK|MB_ICONSTOP);
217 }
218 else
219 {
220 if (DialogBox(hInst, (LPCTSTR)IDD_CONNECTION, hWnd, (DLGPROC)ConnectionDialogProc) == IDOK)
221 {
222 bConnected = TRUE;
223 EnableDisconnectMenuItem(TRUE);
224 EnableConnectMenuItem(FALSE);
225 _beginthread(Rs232Thread, 0, NULL);
226 }
227 }
228 break;
229 case ID_FILE_DISCONNECT:
230 if (bConnected)
231 {
232 bConnected = FALSE;
233 EnableDisconnectMenuItem(FALSE);
234 EnableConnectMenuItem(TRUE);
235 }
236 else
237 {
238 MessageBox(hWnd, TEXT("You are not currently connected!"), TEXT("Error"), MB_OK|MB_ICONSTOP);
239 }
240 break;
241 case ID_FILE_STARTCAPTURE:
242 if (DialogBox(hInst, (LPCTSTR)IDD_CAPTURE, hWnd, (DLGPROC)CaptureDialogProc) == IDOK)
243 {
244 bCapturing = TRUE;
245 EnableStopCaptureMenuItem(TRUE);
246 EnableStartCaptureMenuItem(FALSE);
247 hCaptureFile = CreateFile(strCaptureFileName, FILE_APPEND_DATA, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
248 }
249 break;
250 case ID_FILE_STOPCAPTURE:
251 if (bCapturing)
252 {
253 bCapturing = FALSE;
254 EnableStopCaptureMenuItem(FALSE);
255 EnableStartCaptureMenuItem(TRUE);
256 CloseHandle(hCaptureFile);
257 hCaptureFile = NULL;
258 }
259 break;
260 case ID_FILE_LOCALECHO:
261 if (bLocalEcho)
262 {
263 bLocalEcho = FALSE;
264 CheckLocalEchoMenuItem(bLocalEcho);
265 }
266 else
267 {
268 bLocalEcho = TRUE;
269 CheckLocalEchoMenuItem(bLocalEcho);
270 }
271 break;
272 default:
273 return DefWindowProc(hWnd, message, wParam, lParam);
274 }
275 break;
276 case WM_PAINT:
277 hdc = BeginPaint(hWnd, &ps);
278 EndPaint(hWnd, &ps);
279 break;
280 case WM_SIZE:
281
282 GetClientRect(hWnd, &rc);
283
284 MoveWindow(hDisplayWnd, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top - 20, TRUE);
285 MoveWindow(hEditWnd, rc.left, rc.bottom - 20, rc.right - rc.left, 20, TRUE);
286
287 break;
288 case WM_DESTROY:
289 PostQuitMessage(0);
290 break;
291 default:
292 return DefWindowProc(hWnd, message, wParam, lParam);
293 }
294 return 0;
295 }
296
297 LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
298 {
299 HWND hLicenseEditWnd;
300 TCHAR strLicense[0x1000];
301
302 switch (message)
303 {
304 case WM_INITDIALOG:
305
306 hLicenseEditWnd = GetDlgItem(hDlg, IDC_LICENSE_EDIT);
307
308 LoadString(hInst, IDS_LICENSE, strLicense, 0x1000);
309
310 SetWindowText(hLicenseEditWnd, strLicense);
311
312 return TRUE;
313
314 case WM_COMMAND:
315 if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
316 {
317 EndDialog(hDlg, LOWORD(wParam));
318 return TRUE;
319 }
320 break;
321 }
322 return FALSE;
323 }
324
325 LRESULT CALLBACK ConnectionDialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
326 {
327 switch (message)
328 {
329 case WM_INITDIALOG:
330
331 SetWindowText(GetDlgItem(hDlg, IDC_COMPORT), strComPort);
332 SetWindowText(GetDlgItem(hDlg, IDC_BAUTRATE), strBaudRate);
333
334 return TRUE;
335
336 case WM_COMMAND:
337 if (LOWORD(wParam) == IDOK)
338 {
339 GetWindowText(GetDlgItem(hDlg, IDC_COMPORT), strComPort, MAX_PATH);
340 GetWindowText(GetDlgItem(hDlg, IDC_BAUTRATE), strBaudRate, MAX_PATH);
341 }
342
343 if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
344 {
345 EndDialog(hDlg, LOWORD(wParam));
346 return TRUE;
347 }
348 break;
349 }
350 return FALSE;
351 }
352
353 LRESULT CALLBACK CaptureDialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
354 {
355 OPENFILENAME ofn;
356
357 switch (message)
358 {
359 case WM_INITDIALOG:
360
361 SetWindowText(GetDlgItem(hDlg, IDC_CAPTUREFILENAME), strCaptureFileName);
362
363 return TRUE;
364
365 case WM_COMMAND:
366 if (LOWORD(wParam) == IDC_BROWSE)
367 {
368 memset(&ofn, 0, sizeof(OPENFILENAME));
369 ofn.lStructSize = sizeof(OPENFILENAME);
370 ofn.hwndOwner = hDlg;
371 ofn.hInstance = hInst;
372 ofn.lpstrFilter = NULL;
373 ofn.lpstrCustomFilter = NULL;
374 ofn.nMaxCustFilter = 0;
375 ofn.nFilterIndex = 0;
376 ofn.lpstrFile = strCaptureFileName;
377 ofn.nMaxFile = MAX_PATH;
378 ofn.lpstrFileTitle = NULL;
379 ofn.nMaxFileTitle = 0;
380 ofn.lpstrInitialDir = NULL;
381 ofn.lpstrTitle = NULL;
382 ofn.Flags = OFN_HIDEREADONLY|OFN_NOREADONLYRETURN;
383
384 if (GetOpenFileName(&ofn))
385 {
386 SetWindowText(GetDlgItem(hDlg, IDC_CAPTUREFILENAME), strCaptureFileName);
387 }
388 }
389
390 if (LOWORD(wParam) == IDOK)
391 {
392 GetWindowText(GetDlgItem(hDlg, IDC_CAPTUREFILENAME), strCaptureFileName, MAX_PATH);
393 }
394
395 if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
396 {
397 EndDialog(hDlg, LOWORD(wParam));
398 return TRUE;
399 }
400 break;
401 }
402 return FALSE;
403 }
404
405 VOID EnableConnectMenuItem(BOOL Enable)
406 {
407 HMENU hMenuBar;
408 HMENU hFileMenu;
409
410 hMenuBar = GetMenu(hMainWnd);
411 hFileMenu = GetSubMenu(hMenuBar, 0);
412
413 if (Enable)
414 {
415 EnableMenuItem(hFileMenu, ID_FILE_CONNECT, MF_BYCOMMAND|MF_ENABLED);
416 }
417 else
418 {
419 EnableMenuItem(hFileMenu, ID_FILE_CONNECT, MF_BYCOMMAND|MF_GRAYED);
420 }
421 }
422
423 VOID EnableDisconnectMenuItem(BOOL Enable)
424 {
425 HMENU hMenuBar;
426 HMENU hFileMenu;
427
428 hMenuBar = GetMenu(hMainWnd);
429 hFileMenu = GetSubMenu(hMenuBar, 0);
430
431 if (Enable)
432 {
433 EnableMenuItem(hFileMenu, ID_FILE_DISCONNECT, MF_BYCOMMAND|MF_ENABLED);
434 }
435 else
436 {
437 EnableMenuItem(hFileMenu, ID_FILE_DISCONNECT, MF_BYCOMMAND|MF_GRAYED);
438 }
439 }
440
441 VOID EnableStartCaptureMenuItem(BOOL Enable)
442 {
443 HMENU hMenuBar;
444 HMENU hFileMenu;
445
446 hMenuBar = GetMenu(hMainWnd);
447 hFileMenu = GetSubMenu(hMenuBar, 0);
448
449 if (Enable)
450 {
451 EnableMenuItem(hFileMenu, ID_FILE_STARTCAPTURE, MF_BYCOMMAND|MF_ENABLED);
452 }
453 else
454 {
455 EnableMenuItem(hFileMenu, ID_FILE_STARTCAPTURE, MF_BYCOMMAND|MF_GRAYED);
456 }
457 }
458
459 VOID EnableStopCaptureMenuItem(BOOL Enable)
460 {
461 HMENU hMenuBar;
462 HMENU hFileMenu;
463
464 hMenuBar = GetMenu(hMainWnd);
465 hFileMenu = GetSubMenu(hMenuBar, 0);
466
467 if (Enable)
468 {
469 EnableMenuItem(hFileMenu, ID_FILE_STOPCAPTURE, MF_BYCOMMAND|MF_ENABLED);
470 }
471 else
472 {
473 EnableMenuItem(hFileMenu, ID_FILE_STOPCAPTURE, MF_BYCOMMAND|MF_GRAYED);
474 }
475 }
476
477 VOID CheckLocalEchoMenuItem(BOOL Checked)
478 {
479 HMENU hMenuBar;
480 HMENU hFileMenu;
481
482 hMenuBar = GetMenu(hMainWnd);
483 hFileMenu = GetSubMenu(hMenuBar, 0);
484
485 if (Checked)
486 {
487 CheckMenuItem(hFileMenu, ID_FILE_LOCALECHO, MF_BYCOMMAND|MF_CHECKED);
488 }
489 else
490 {
491 CheckMenuItem(hFileMenu, ID_FILE_LOCALECHO, MF_BYCOMMAND|MF_UNCHECKED);
492 }
493 }
494
495 VOID Rs232Thread(VOID* Parameter)
496 {
497 BYTE Byte;
498 TCHAR String[MAX_PATH];
499 MSG msg;
500 DWORD dwNumberOfBytesWritten;
501
502 dwThreadId = GetCurrentThreadId();
503
504 if (!Rs232OpenPortWin32(strComPort))
505 {
506 MessageBox(hMainWnd, TEXT("Error opening port!"), TEXT("Error"), MB_OK|MB_ICONSTOP);
507 bConnected = FALSE;
508 return;
509 }
510
511 _stprintf(String, TEXT("%s,n,8,1"), strBaudRate);
512 if (!Rs232ConfigurePortWin32(String))
513 {
514 MessageBox(hMainWnd, TEXT("Error configuring port!"), TEXT("Error"), MB_OK|MB_ICONSTOP);
515 bConnected = FALSE;
516 return;
517 }
518
519 while (bConnected)
520 {
521 if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
522 {
523 if (msg.message == WM_CHAR)
524 {
525 Rs232WriteByteWin32((BYTE)msg.wParam);
526
527 if (bLocalEcho && msg.wParam != (WPARAM)TEXT('\r'))
528 {
529 PostMessage(hDisplayWnd, WM_CHAR, (WPARAM)msg.wParam, (LPARAM)0);
530
531 if (hCaptureFile)
532 {
533 WriteFile(hCaptureFile, &msg.wParam, sizeof(TCHAR), &dwNumberOfBytesWritten, NULL);
534 }
535 }
536 }
537 }
538
539 if (Rs232ReadByteWin32(&Byte))
540 {
541 _stprintf(String, TEXT("%c"), Byte);
542
543 PostMessage(hDisplayWnd, WM_CHAR, (WPARAM)String[0], (LPARAM)0);
544
545 if (hCaptureFile)
546 {
547 WriteFile(hCaptureFile, &String[0], sizeof(TCHAR), &dwNumberOfBytesWritten, NULL);
548 }
549 }
550 }
551
552 dwThreadId = 0;
553 Rs232ClosePortWin32();
554 }