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