1 /* -*-C++-*- $NetBSD: hpcmenu.cpp,v 1.5 2001/03/25 17:13:16 uch Exp $ */ 2 3 /*- 4 * Copyright (c) 2001 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by UCHIYAMA Yasushi. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by the NetBSD 21 * Foundation, Inc. and its contributors. 22 * 4. Neither the name of The NetBSD Foundation nor the names of its 23 * contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36 * POSSIBILITY OF SUCH DAMAGE. 37 */ 38 39 #include <hpcmenu.h> 40 #include <hpcboot.h> 41 #include <res/resource.h> 42 #include <menu/window.h> 43 #include <menu/tabwindow.h> 44 #include <menu/rootwindow.h> 45 #include <machine/bootinfo.h> 46 #include <framebuffer.h> 47 #include <console.h> 48 49 static BOOL _find_pref_dir(TCHAR *); 50 // 51 // Main window 52 // 53 class MainTabWindow : public TabWindow 54 { 55 private: 56 HWND _edit_md_root; 57 HWND _combobox_serial_speed; 58 59 int _item_idx; 60 void _insert_item(HWND w, TCHAR *name, int id) { 61 int idx = SendDlgItemMessage(w, id, CB_ADDSTRING, 0, 62 reinterpret_cast <LPARAM>(name)); 63 if (idx != CB_ERR) 64 SendDlgItemMessage(w, IDC_MAIN_DIR, CB_SETITEMDATA, 65 idx, _item_idx++); 66 } 67 68 public: 69 explicit MainTabWindow(TabWindowBase &base, int id) 70 : TabWindow(base, id, TEXT("WMain")) { 71 _item_idx = 0; 72 } 73 virtual ~MainTabWindow(void) { /* NO-OP */ } 74 virtual void init(HWND w) { 75 HpcMenuInterface &menu = HpcMenuInterface::Instance(); 76 struct HpcMenuInterface::HpcMenuPreferences 77 *pref = &menu._pref; 78 _window = w; 79 // insert myself to tab-control 80 TabWindow::init(w); 81 82 // setup child. 83 TCHAR *entry; 84 int i; 85 // kernel directory path 86 for (i = 0; entry = menu.dir(i); i++) 87 _insert_item(w, entry, IDC_MAIN_DIR); 88 SendDlgItemMessage(w, IDC_MAIN_DIR, CB_SETCURSEL, 89 menu.dir_default(), 0); 90 // platform 91 for (i = 0; entry = menu.platform_get(i); i++) 92 _insert_item(w, entry, IDC_MAIN_PLATFORM); 93 SendDlgItemMessage(w, IDC_MAIN_PLATFORM, CB_SETCURSEL, 94 menu.platform_default(), 0); 95 // kernel file name. 96 Edit_SetText(GetDlgItem(w, IDC_MAIN_KERNEL), 97 pref->kernel_user ? pref->kernel_user_file : 98 TEXT("netbsd.gz")); 99 100 // root file system. 101 int fs = pref->rootfs + IDC_MAIN_ROOT_; 102 _set_check(fs, TRUE); 103 104 _edit_md_root = GetDlgItem(w, IDC_MAIN_ROOT_MD_OPS); 105 Edit_SetText(_edit_md_root, pref->rootfs_file); 106 EnableWindow(_edit_md_root, fs == IDC_MAIN_ROOT_MD 107 ? TRUE : FALSE); 108 109 // kernel boot options. 110 _set_check(IDC_MAIN_OPTION_A, pref->boot_ask_for_name); 111 _set_check(IDC_MAIN_OPTION_S, pref->boot_single_user); 112 _set_check(IDC_MAIN_OPTION_V, pref->boot_verbose); 113 _set_check(IDC_MAIN_OPTION_H, pref->boot_serial); 114 115 // serial console speed. 116 TCHAR *speed_tab[] = { L"9600", L"19200", L"115200", 0 }; 117 int sel = 0; 118 i = 0; 119 for (TCHAR **speed = speed_tab; *speed; speed++, i++) { 120 _insert_item(w, *speed, IDC_MAIN_OPTION_H_SPEED); 121 if (_wtoi(*speed) == pref->serial_speed) 122 sel = i; 123 } 124 _combobox_serial_speed = GetDlgItem(_window, 125 IDC_MAIN_OPTION_H_SPEED); 126 SendDlgItemMessage(w, IDC_MAIN_OPTION_H_SPEED, CB_SETCURSEL, 127 sel, 0); 128 EnableWindow(_combobox_serial_speed, pref->boot_serial); 129 } 130 131 void get(void) { 132 HpcMenuInterface &menu = HpcMenuInterface::Instance(); 133 struct HpcMenuInterface::HpcMenuPreferences 134 *pref = &menu._pref; 135 136 HWND w = GetDlgItem(_window, IDC_MAIN_DIR); 137 ComboBox_GetText(w, pref->dir_user_path, MAX_PATH); 138 pref->dir_user = TRUE; 139 w = GetDlgItem(_window, IDC_MAIN_KERNEL); 140 Edit_GetText(w, pref->kernel_user_file, MAX_PATH); 141 pref->kernel_user = TRUE; 142 143 int i = ComboBox_GetCurSel(GetDlgItem(_window, 144 IDC_MAIN_PLATFORM)); 145 menu.platform_set(i); 146 147 if (_is_checked(IDC_MAIN_ROOT_WD)) 148 pref->rootfs = 0; 149 else if (_is_checked(IDC_MAIN_ROOT_SD)) 150 pref->rootfs = 1; 151 else if (_is_checked(IDC_MAIN_ROOT_MD)) 152 pref->rootfs = 2; 153 else if (_is_checked(IDC_MAIN_ROOT_NFS)) 154 pref->rootfs = 3; 155 156 pref->boot_ask_for_name = _is_checked(IDC_MAIN_OPTION_A); 157 pref->boot_verbose = _is_checked(IDC_MAIN_OPTION_V); 158 pref->boot_single_user = _is_checked(IDC_MAIN_OPTION_S); 159 pref->boot_serial = _is_checked(IDC_MAIN_OPTION_H); 160 Edit_GetText(_edit_md_root, pref->rootfs_file, MAX_PATH); 161 162 TCHAR tmpbuf[8]; 163 ComboBox_GetText(_combobox_serial_speed, tmpbuf, 8); 164 pref->serial_speed = _wtoi(tmpbuf); 165 } 166 167 virtual void command(int id, int msg) { 168 switch (id) { 169 case IDC_MAIN_OPTION_H: 170 EnableWindow(_combobox_serial_speed, 171 _is_checked(IDC_MAIN_OPTION_H)); 172 break; 173 case IDC_MAIN_ROOT_WD: 174 /* FALLTHROUGH */ 175 case IDC_MAIN_ROOT_SD: 176 /* FALLTHROUGH */ 177 case IDC_MAIN_ROOT_MD: 178 /* FALLTHROUGH */ 179 case IDC_MAIN_ROOT_NFS: 180 EnableWindow(_edit_md_root, 181 _is_checked(IDC_MAIN_ROOT_MD)); 182 } 183 } 184 }; 185 186 // 187 // Option window 188 // 189 class OptionTabWindow : public TabWindow 190 { 191 public: 192 HWND _spin_edit; 193 HWND _spin; 194 #define IS_CHECKED(x) _is_checked(IDC_OPT_##x) 195 #define SET_CHECK(x, b) _set_check(IDC_OPT_##x,(b)) 196 197 public: 198 explicit OptionTabWindow(TabWindowBase &base, int id) 199 : TabWindow(base, id, TEXT("WOption")) { 200 _spin_edit = NULL; 201 _spin = NULL; 202 } 203 virtual ~OptionTabWindow(void) { /* NO-OP */ } 204 virtual void init(HWND w) { 205 HpcMenuInterface &menu = HpcMenuInterface::Instance(); 206 struct HpcMenuInterface::HpcMenuPreferences 207 *pref = &menu._pref; 208 _window = w; 209 210 TabWindow::init(_window); 211 _spin_edit = GetDlgItem(_window, IDC_OPT_AUTO_INPUT); 212 _spin = CreateUpDownControl(WS_CHILD | WS_BORDER | WS_VISIBLE | 213 UDS_SETBUDDYINT | UDS_ALIGNRIGHT, 214 80, 0, 50, 50, _window, 215 IDC_OPT_AUTO_UPDOWN, 216 _app._instance, _spin_edit, 217 60, 1, 30); 218 BOOL onoff = pref->auto_boot ? TRUE : FALSE; 219 EnableWindow(_spin_edit, onoff); 220 EnableWindow(_spin, onoff); 221 222 SET_CHECK(AUTO, pref->auto_boot); 223 if (pref->auto_boot) 224 { 225 TCHAR tmp[32]; 226 wsprintf(tmp, TEXT("%d"), pref->auto_boot); 227 Edit_SetText(_spin_edit, tmp); 228 } 229 SET_CHECK(VIDEO, pref->reverse_video); 230 SET_CHECK(PAUSE, pref->pause_before_boot); 231 SET_CHECK(DEBUG, pref->load_debug_info); 232 SET_CHECK(SAFETY, pref->safety_message); 233 } 234 235 virtual void command(int id, int msg) { 236 switch (id) { 237 case IDC_OPT_AUTO: 238 if (IS_CHECKED(AUTO)) { 239 EnableWindow(_spin_edit, TRUE); 240 EnableWindow(_spin, TRUE); 241 } else { 242 EnableWindow(_spin_edit, FALSE); 243 EnableWindow(_spin, FALSE); 244 } 245 break; 246 } 247 } 248 249 void get(void) { 250 HpcMenuInterface &menu = HpcMenuInterface::Instance(); 251 struct HpcMenuInterface::HpcMenuPreferences 252 *pref = &menu._pref; 253 if (IS_CHECKED(AUTO)) { 254 TCHAR tmp[32]; 255 Edit_GetText(_spin_edit, tmp, 32); 256 pref->auto_boot = _wtoi(tmp); 257 } else 258 pref->auto_boot = 0; 259 pref->reverse_video = IS_CHECKED(VIDEO); 260 pref->pause_before_boot = IS_CHECKED(PAUSE); 261 pref->load_debug_info = IS_CHECKED(DEBUG); 262 pref->safety_message = IS_CHECKED(SAFETY); 263 } 264 }; 265 266 // 267 // Console window 268 // 269 class ConsoleTabWindow : public TabWindow 270 { 271 private: 272 HWND _filename_edit; 273 BOOL _filesave; 274 HANDLE _logfile; 275 BOOL _open_log_file(void); 276 public: 277 HWND _edit; 278 279 public: 280 explicit ConsoleTabWindow(TabWindowBase &base, int id) 281 : TabWindow(base, id, TEXT("WConsole")) { 282 _edit = NULL; 283 _logfile = INVALID_HANDLE_VALUE; 284 } 285 virtual ~ConsoleTabWindow(void) { 286 if (_logfile != INVALID_HANDLE_VALUE) 287 CloseHandle(_logfile); 288 } 289 virtual void init(HWND); 290 virtual void command(int, int); 291 292 void print(TCHAR *buf, BOOL = FALSE); 293 }; 294 295 void 296 ConsoleTabWindow::print(TCHAR *buf, BOOL force_display) 297 { 298 int cr; 299 TCHAR *p; 300 301 if (force_display) 302 goto display; 303 304 if (_filesave) { 305 if (_logfile == INVALID_HANDLE_VALUE && !_open_log_file()) { 306 _filesave = FALSE; 307 _set_check(IDC_CONS_FILESAVE, _filesave); 308 EnableWindow(_filename_edit, _filesave); 309 goto display; 310 } 311 DWORD cnt; 312 char c; 313 for (int i = 0; *buf != TEXT('\0'); buf++) { 314 c = *buf & 0x7f; 315 WriteFile(_logfile, &c, 1, &cnt, 0); 316 } 317 FlushFileBuffers(_logfile); 318 return; 319 } 320 321 display: 322 // count # of '\n' 323 for (cr = 0, p = buf; p = wcschr(p, TEXT('\n')); cr++, p++) 324 ; 325 // total length of new buffer('\n' -> "\r\n" + '\0') 326 int ln = wcslen(buf) + cr + 1; 327 328 // get old buffer. 329 int lo = Edit_GetTextLength(_edit); 330 size_t sz =(lo + ln) * sizeof(TCHAR); 331 332 p = reinterpret_cast <TCHAR *>(malloc(sz)); 333 if (p == NULL) 334 return; 335 336 memset(p, 0, sz); 337 Edit_GetText(_edit, p, lo + 1); 338 339 // put new buffer to end of old buffer. 340 TCHAR *d = p + lo; 341 while (*buf != TEXT('\0')) { 342 TCHAR c = *buf++; 343 if (c == TEXT('\n')) 344 *d++ = TEXT('\r'); 345 *d++ = c; 346 } 347 *d = TEXT('\0'); 348 349 // display total buffer. 350 Edit_SetText(_edit, p); 351 // Edit_Scroll(_edit, Edit_GetLineCount(_edit), 0); 352 UpdateWindow(_edit); 353 354 free(p); 355 } 356 357 void 358 ConsoleTabWindow::init(HWND w) 359 { 360 // at this time _window is NULL. 361 // use argument of window procedure. 362 TabWindow::init(w); 363 _edit = GetDlgItem(w, IDC_CONS_EDIT); 364 MoveWindow(_edit, 5, 60, _rect.right - _rect.left - 10, 365 _rect.bottom - _rect.top - 60, TRUE); 366 Edit_FmtLines(_edit, TRUE); 367 368 // log file. 369 _filename_edit = GetDlgItem(w, IDC_CONS_FILENAME); 370 _filesave = FALSE; 371 Edit_SetText(_filename_edit, L"bootlog.txt"); 372 EnableWindow(_filename_edit, _filesave); 373 } 374 375 void 376 ConsoleTabWindow::command(int id, int msg) 377 { 378 HpcMenuInterface &menu = HpcMenuInterface::Instance(); 379 struct HpcMenuInterface::cons_hook_args *hook = 0; 380 int bit; 381 382 switch(id) { 383 case IDC_CONS_FILESAVE: 384 _filesave = _is_checked(IDC_CONS_FILESAVE); 385 EnableWindow(_filename_edit, _filesave); 386 break; 387 case IDC_CONS_CHK0: 388 /* FALLTHROUGH */ 389 case IDC_CONS_CHK1: 390 /* FALLTHROUGH */ 391 case IDC_CONS_CHK2: 392 /* FALLTHROUGH */ 393 case IDC_CONS_CHK3: 394 /* FALLTHROUGH */ 395 case IDC_CONS_CHK4: 396 /* FALLTHROUGH */ 397 case IDC_CONS_CHK5: 398 /* FALLTHROUGH */ 399 case IDC_CONS_CHK6: 400 /* FALLTHROUGH */ 401 case IDC_CONS_CHK7: 402 bit = 1 << (id - IDC_CONS_CHK_); 403 if (SendDlgItemMessage(_window, id, BM_GETCHECK, 0, 0)) 404 menu._cons_parameter |= bit; 405 else 406 menu._cons_parameter &= ~bit; 407 break; 408 case IDC_CONS_BTN0: 409 /* FALLTHROUGH */ 410 case IDC_CONS_BTN1: 411 /* FALLTHROUGH */ 412 case IDC_CONS_BTN2: 413 /* FALLTHROUGH */ 414 case IDC_CONS_BTN3: 415 hook = &menu._cons_hook[id - IDC_CONS_BTN_]; 416 if (hook->func) 417 hook->func(hook->arg, menu._cons_parameter); 418 419 break; 420 } 421 } 422 423 BOOL 424 ConsoleTabWindow::_open_log_file() 425 { 426 TCHAR path[MAX_PATH]; 427 TCHAR filename[MAX_PATH]; 428 TCHAR filepath[MAX_PATH]; 429 430 if (!_find_pref_dir(path)) { 431 print(L"couldn't find temporary directory.\n", TRUE); 432 return FALSE; 433 } 434 435 Edit_GetText(_filename_edit, filename, MAX_PATH); 436 wsprintf(filepath, TEXT("\\%s\\%s"), path, filename); 437 _logfile = CreateFile(filepath, GENERIC_WRITE, 0, 0, 438 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 439 0); 440 if (_logfile == INVALID_HANDLE_VALUE) 441 return FALSE; 442 443 wsprintf(path, TEXT("log file is %s\n"), filepath); 444 print(path, TRUE); 445 446 return TRUE; 447 } 448 449 TabWindow * 450 TabWindowBase::boot(int id) 451 { 452 TabWindow *w = NULL; 453 HpcMenuInterface &menu = HpcMenuInterface::Instance(); 454 455 switch(id) { 456 default: 457 break; 458 case IDC_BASE_MAIN: 459 menu._main = new MainTabWindow(*this, IDC_BASE_MAIN); 460 w = menu._main; 461 break; 462 case IDC_BASE_OPTION: 463 menu._option = new OptionTabWindow(*this, IDC_BASE_OPTION); 464 w = menu._option; 465 break; 466 case IDC_BASE_CONSOLE: 467 menu._console = new ConsoleTabWindow(*this, IDC_BASE_CONSOLE); 468 w = menu._console; 469 break; 470 } 471 472 if (w) 473 w->create(0); 474 475 return w; 476 } 477 478 // 479 // External Interface 480 // 481 HpcMenuInterface *HpcMenuInterface::_instance = 0; 482 483 HpcMenuInterface & 484 HpcMenuInterface::Instance() 485 { 486 if (!_instance) 487 _instance = new HpcMenuInterface(); 488 return *_instance; 489 } 490 491 void 492 HpcMenuInterface::Destroy() 493 { 494 if (_instance) 495 delete _instance; 496 } 497 498 void 499 HpcMenuInterface::print(TCHAR *buf) 500 { 501 if (_console) 502 _console->print(buf); 503 } 504 505 void 506 HpcMenuInterface::get_options() 507 { 508 _main->get(); 509 _option->get(); 510 } 511 512 TCHAR * 513 HpcMenuInterface::dir(int i) 514 { 515 int res = IDS_DIR_RES(i); 516 if (!IDS_DIR_RES_VALID(res)) 517 return 0; 518 519 if (_pref.dir_user && res == IDS_DIR_USER_DEFINED) { 520 return _pref.dir_user_path; 521 } 522 523 TCHAR *s = reinterpret_cast <TCHAR *> 524 (LoadString(_root->_app._instance, res, 0, 0)); 525 526 return s; 527 } 528 529 int 530 HpcMenuInterface::dir_default() 531 { 532 return _pref.dir_user ? IDS_DIR_SEQ(IDS_DIR_USER_DEFINED) : 0; 533 } 534 535 BOOL 536 HpcMenuInterface::load() 537 { 538 TCHAR path[MAX_PATH]; 539 540 if (!_find_pref_dir(path)) 541 return FALSE; 542 543 TCHAR filename[MAX_PATH]; 544 wsprintf(filename, TEXT("\\%s\\hpcboot.cnf"), path); 545 HANDLE file = CreateFile(filename, GENERIC_READ, 0, 0, OPEN_EXISTING, 546 FILE_ATTRIBUTE_NORMAL, 0); 547 if (file == INVALID_HANDLE_VALUE) 548 return FALSE; 549 550 DWORD cnt; 551 // read header. 552 if (!ReadFile(file, &_pref, 12, &cnt, 0)) 553 goto bad; 554 if (_pref._magic != HPCBOOT_MAGIC) 555 goto bad; 556 // read all. 557 SetFilePointer(file, 0, 0, FILE_BEGIN); 558 if (!ReadFile(file, &_pref, _pref._size, &cnt, 0)) 559 goto bad; 560 CloseHandle(file); 561 562 return TRUE; 563 bad: 564 CloseHandle(file); 565 return FALSE; 566 } 567 568 BOOL 569 HpcMenuInterface::save() 570 { 571 TCHAR path[MAX_PATH]; 572 573 if (_find_pref_dir(path)) { 574 TCHAR filename[MAX_PATH]; 575 wsprintf(filename, TEXT("\\%s\\hpcboot.cnf"), path); 576 HANDLE file = CreateFile(filename, GENERIC_WRITE, 0, 0, 577 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 578 0); 579 DWORD cnt; 580 WriteFile(file, &_pref, _pref._size, &cnt, 0); 581 CloseHandle(file); 582 return cnt == _pref._size; 583 } 584 585 return FALSE; 586 } 587 588 // arguments for kernel. 589 int 590 HpcMenuInterface::setup_kernel_args(vaddr_t v, paddr_t p) 591 { 592 int argc = 0; 593 kaddr_t *argv = reinterpret_cast <kaddr_t *>(v); 594 char *loc = reinterpret_cast <char *> 595 (v + sizeof(char **) * MAX_KERNEL_ARGS); 596 paddr_t locp = p + sizeof(char **) * MAX_KERNEL_ARGS; 597 size_t len; 598 TCHAR *w; 599 600 #define SETOPT(c) \ 601 __BEGIN_MACRO \ 602 argv[argc++] = ptokv(locp); \ 603 *loc++ =(c); \ 604 *loc++ = '\0'; \ 605 locp += 2; \ 606 __END_MACRO 607 // 1st arg is kernel name. 608 // DPRINTF_SETUP(); if you want to use debug print, enable this line. 609 610 w = _pref.kernel_user_file; 611 argv[argc++] = ptokv(locp); 612 len = WideCharToMultiByte(CP_ACP, 0, w, wcslen(w), 0, 0, 0, 0); 613 WideCharToMultiByte(CP_ACP, 0, w, len, loc, len, 0, 0); 614 loc[len] = '\0'; 615 loc += len + 1; 616 locp += len + 1; 617 618 if (_pref.boot_serial) // serial console 619 SETOPT('h'); 620 if (_pref.boot_verbose) // boot verbosely 621 SETOPT('v'); 622 if (_pref.boot_single_user) // boot to single user 623 SETOPT('s'); 624 if (_pref.boot_ask_for_name) // ask for file name to boot from 625 SETOPT('a'); 626 627 // boot from 628 switch(_pref.rootfs) { 629 case 0: // wd0 630 break; 631 case 1: // sd0 632 argv[argc++] = ptokv(locp); 633 strncpy(loc, "b=sd0", 6); 634 loc += 6; 635 locp += 6; 636 break; 637 case 2: // memory disk 638 w = _pref.rootfs_file; 639 argv[argc++] = ptokv(locp); 640 strncpy(loc, "m=", 2); 641 loc += 2; 642 len = WideCharToMultiByte(CP_ACP, 0, w, wcslen(w), 0, 0, 0, 0); 643 WideCharToMultiByte(CP_ACP, 0, w, len, loc, len, 0, 0); 644 loc[len] = '\0'; 645 loc += len + 1; 646 locp += 2 + len + 1; 647 break; 648 case 3: // nfs 649 argv[argc++] = ptokv(locp); 650 strncpy(loc, "b=nfs", 6); 651 loc += 6; 652 locp += 6; 653 break; 654 } 655 656 return argc; 657 } 658 659 // kernel bootinfo. 660 void 661 HpcMenuInterface::setup_bootinfo(struct bootinfo &bi) 662 { 663 FrameBufferInfo fb(_pref.platid_hi, _pref.platid_lo); 664 TIME_ZONE_INFORMATION tz; 665 GetTimeZoneInformation(&tz); 666 667 memset(&bi, 0, sizeof(struct bootinfo)); 668 bi.length = sizeof(struct bootinfo); 669 bi.reserved = 0; 670 bi.magic = BOOTINFO_MAGIC; 671 bi.fb_addr = fb.addr(); 672 bi.fb_type = fb.type(); 673 bi.fb_line_bytes = fb.linebytes(); 674 bi.fb_width = fb.width(); 675 bi.fb_height = fb.height(); 676 bi.platid_cpu = _pref.platid_hi; 677 bi.platid_machine = _pref.platid_lo; 678 bi.timezone = tz.Bias; 679 } 680 681 // Progress bar 682 void 683 HpcMenuInterface::progress() 684 { 685 SendMessage(_root->_progress_bar->_window, PBM_STEPIT, 0, 0); 686 } 687 688 void 689 HpcMenuInterface::boot() 690 { 691 struct support_status *tab = _unsupported; 692 u_int32_t cpu = _pref.platid_hi; 693 u_int32_t machine = _pref.platid_lo; 694 695 if (_pref.safety_message) 696 for (; tab->cpu; tab++) { 697 if (tab->cpu == cpu && tab->machine == machine) { 698 MessageBox(_root->_window, 699 tab->cause ? tab->cause : 700 L"not supported yet.", 701 TEXT("BOOT FAILED"), 0); 702 return; 703 } 704 } 705 706 if (_boot_hook.func) 707 _boot_hook.func(_boot_hook.arg, _pref); 708 } 709 710 // 711 // Common utility 712 // 713 static BOOL 714 _find_pref_dir(TCHAR *path) 715 { 716 WIN32_FIND_DATA fd; 717 HANDLE find; 718 719 lstrcpy(path, TEXT("\\*.*")); 720 find = FindFirstFile(path, &fd); 721 722 if (find != INVALID_HANDLE_VALUE) { 723 do { 724 int attr = fd.dwFileAttributes; 725 if ((attr & FILE_ATTRIBUTE_DIRECTORY) && 726 (attr & FILE_ATTRIBUTE_TEMPORARY)) { 727 wcscpy(path, fd.cFileName); 728 FindClose(find); 729 return TRUE; 730 } 731 } while (FindNextFile(find, &fd)); 732 } 733 FindClose(find); 734 735 return FALSE; 736 } 737