1 /*---------------------------------------------------------------------------* 2 3 Copyright (C) Nintendo. All rights reserved. 4 5 These coded instructions, statements, and computer programs contain 6 proprietary information of Nintendo of America Inc. and/or Nintendo 7 Company Ltd., and are protected by Federal copyright law. They may 8 not be disclosed to third parties or copied or duplicated in any form, 9 in whole or in part, without the prior written consent of Nintendo. 10 11 *---------------------------------------------------------------------------*/ 12 using System; 13 using System.Diagnostics; 14 using System.Net.Sockets; 15 using System.Linq; 16 using System.IO; 17 using System.Net; 18 using System.Collections.Generic; 19 using System.Threading; 20 using System.Text; 21 using System.Text.RegularExpressions; 22 23 namespace CafeX 24 { 25 /// <summary> 26 /// This class encapsulates the functionality of the dkt.exe tool used by CafeX. 27 /// </summary> 28 static class dkt 29 { 30 static string cygwin_dkt_exe_path = "\"" + Environment.GetEnvironmentVariable("CAFE_ROOT") + "\\system\\bin\\tool\\dkt.exe" + "\""; 31 GetExeName()32 private static string GetExeName() 33 { 34 string dkt_or_temp_exe_path; 35 if (FileUtil.RunningFromCygwin) 36 { 37 // take the monitor from cygwin 38 dkt_or_temp_exe_path = cygwin_dkt_exe_path; 39 } 40 else 41 { 42 dkt_or_temp_exe_path = FileUtil.ExpandExecutable(CafeX.Properties.Resources.win_dkt, "win_dkt.exe"); 43 } 44 return dkt_or_temp_exe_path; 45 } 46 FlushOutputBuffer()47 internal static int FlushOutputBuffer() 48 { 49 #if DEBUG 50 Log.WriteLine("dkt.FlushOutputBuffer started -> calls FlushOuputBuffer( 1 second)."); 51 #endif 52 53 return dkt.FlushOutputBuffer(1); 54 } 55 FlushOutputBuffer(uint seconds)56 internal static int FlushOutputBuffer(uint seconds) 57 { 58 string strSeconds = seconds.ToString(); 59 #if DEBUG 60 Log.WriteLine("dkt.FlushOutputBuffer(" + strSeconds + ") started."); 61 #endif 62 63 return ProcessExecutor.DoProcess(GetExeName(), "-d 40 " + strSeconds); 64 } 65 } 66 67 /// <summary> 68 /// This class encapsulates the functionality of the PCFSServer used by CafeX. 69 /// </summary> 70 static class PCFSServer 71 { 72 static string exe_path = null; 73 static string output_log = String.Empty; setExePath()74 private static void setExePath() 75 { 76 string testInMionBridge = Environment.GetEnvironmentVariable("MION_BRIDGE_TOOLS") + "\\pcfs\\PCFSServer.exe"; 77 if (File.Exists(testInMionBridge)) 78 { 79 exe_path = testInMionBridge; 80 } 81 else 82 { 83 exe_path = Environment.GetEnvironmentVariable("CAFE_ROOT") + "\\system\\bin\\tool\\PCFSServer.exe"; 84 } 85 86 FileUtil.AddQuotes(ref exe_path); 87 } 88 Shutdown()89 internal static int Shutdown() 90 { 91 #if DEBUG 92 Log.WriteLine("PCFSServer.Shutdown started."); 93 #endif 94 95 setExePath(); 96 97 return ProcessExecutor.DoProcess(exe_path, "-q"); 98 } 99 Start(string parameters, string mapping, string log)100 internal static int Start(string parameters, string mapping, string log) 101 { 102 #if DEBUG 103 Log.WriteLine("PCFSServer.Start started. parameters=" + parameters + ", mapping=" + mapping + ", log=" + log); 104 #endif 105 106 setExePath(); 107 output_log = log; 108 return ProcessExecutor.StartProcess_RedirectOutput(exe_path, "-r 100 " + parameters + " " + Environment.GetEnvironmentVariable("PCFS_HEADLESS_EMUL") + " " + mapping, output_callback, false); 109 } 110 output_callback(Object sender, DataReceivedEventArgs line)111 static void output_callback(Object sender, DataReceivedEventArgs line) 112 { 113 #if DEBUG 114 Log.WriteLine("PCFSServer.output_callback started."); 115 #endif 116 117 setExePath(); 118 if (output_log != "/dev/null") 119 { 120 try 121 { 122 FileStream s = new FileStream(output_log, FileMode.Append, FileAccess.Write); 123 StreamWriter w = new StreamWriter(s); 124 w.Write(line.Data); 125 w.Flush(); 126 w.Close(); 127 } 128 catch (IOException ex) 129 { 130 Console.WriteLine("cafex [PCFSServer]: Caught exception while writing stdout to '{0}':", output_log); 131 Console.WriteLine(" {0}", ex.Message); 132 133 // Prevent future log file writes 134 output_log = "/dev/null"; 135 } 136 } 137 } 138 } 139 140 /// <summary> 141 /// This class encapsulates the functionality of the checkbridge tool used by CafeX. 142 /// </summary> 143 static class checkbridgename 144 { 145 static string exe_path = "\"" + Environment.GetEnvironmentVariable("MION_BRIDGE_TOOLS") + "\\checkbridgename.exe" + "\""; 146 CheckName(ref string output)147 internal static int CheckName(ref string output) 148 { 149 #if DEBUG 150 Log.WriteLine("checkbridgename.CheckName started."); 151 #endif 152 string args = string.Format("\"{0}\" -ip {1}", 153 Environment.GetEnvironmentVariable("BRIDGE_CURRENT_NAME"), 154 Environment.GetEnvironmentVariable("BRIDGE_CURRENT_IP_ADDRESS")); 155 156 int returnVal = ProcessExecutor.DoProcess_GetOutput(exe_path, args, out output); 157 158 return returnVal; 159 } 160 CheckName()161 internal static int CheckName() 162 { 163 string output = string.Empty; 164 return CheckName(ref output); 165 } 166 CheckName_IPOnly()167 internal static int CheckName_IPOnly() 168 { 169 #if DEBUG 170 Log.WriteLine("checkbridgename.CheckName_IPOnly started."); 171 #endif 172 173 int returnVal; 174 string output = string.Empty; 175 176 returnVal = ProcessExecutor.DoProcess_GetOutput(exe_path, "-s -ip " + Environment.GetEnvironmentVariable("BRIDGE_CURRENT_IP_ADDRESS"), out output); 177 Console.Write(output); 178 179 return returnVal; 180 } 181 } 182 183 /// <summary> 184 /// This class encapsulates the functionality of the toucanreset tool used by CafeX. 185 /// </summary> 186 static class ToucanReset 187 { 188 static string exe_path = "\"" + Environment.GetEnvironmentVariable("MION_BRIDGE_TOOLS") + "\\ToucanReset.exe" + "\""; 189 Stop()190 internal static int Stop() 191 { 192 #if DEBUG 193 Log.WriteLine("ToucanReset.Stop started."); 194 #endif 195 196 return ProcessExecutor.DoProcess(exe_path, "-stop"); 197 } 198 Reset()199 internal static int Reset() 200 { 201 #if DEBUG 202 Log.WriteLine("ToucanReset.Reset started."); 203 #endif 204 205 return ProcessExecutor.DoProcess(exe_path, Environment.GetEnvironmentVariable("HOSTSTOP_RESET_OPTION")); 206 } 207 } 208 209 /// <summary> 210 /// This class encapsulates the functionality of the fsemul tool used by CafeX. 211 /// </summary> 212 static class FSEmul 213 { 214 static string exe_path = "\"" + Environment.GetEnvironmentVariable("MION_BRIDGE_TOOLS") + "\\FSEmul.exe" + "\""; 215 makemine()216 internal static int makemine() 217 { 218 #if DEBUG 219 Log.WriteLine("FSEmul.makemine started."); 220 #endif 221 222 int returnVal; 223 string output = string.Empty; 224 returnVal = ProcessExecutor.DoProcess_GetOutput(exe_path, "-ip " + Environment.GetEnvironmentVariable("BRIDGE_CURRENT_IP_ADDRESS") + " -makemine", out output); 225 Console.Write(output); 226 227 return returnVal; 228 } 229 FW_SW_Version(string ip, out string fw_ver, out string sw_ver)230 internal static int FW_SW_Version(string ip, out string fw_ver, out string sw_ver) 231 { 232 #if DEBUG 233 Log.WriteLine("FSEmul.FW_SW_Version started."); 234 #endif 235 236 string arguments = (ip != null) ? "-ver -ip " + ip : "-ver"; 237 238 // Set initial empty values 239 fw_ver = string.Empty; 240 sw_ver = string.Empty; 241 242 // Remember and clear the TOUCAN_VERBOSE variable as this causes the version to be parsed as blank 243 string localTOUCAN_VERBOSE = Environment.GetEnvironmentVariable("TOUCAN_VERBOSE"); 244 Environment.SetEnvironmentVariable("TOUCAN_VERBOSE", ""); 245 246 string output = string.Empty; 247 int ret = ProcessExecutor.DoProcess_GetOutput(exe_path, arguments, out output); 248 249 // Restore the TOUCAN_VERBOSE variable 250 if (!string.IsNullOrEmpty(localTOUCAN_VERBOSE)) 251 { 252 Environment.SetEnvironmentVariable("TOUCAN_VERBOSE", localTOUCAN_VERBOSE); 253 } 254 255 // FSEmul was successful, now let's parse the output 256 if (ret == 0) 257 { 258 // Sample output from FSEmul: 259 // Firmware version : 0.0.14.77\r\nSoftware version : 3.2.6.4\r\nFPGA version : 13052071\r\n 260 // 261 // Sometimes there is other text preceding output. So try to find where the "Firmware version" text starts. 262 int realOutputStartIndex = output.IndexOf("Firmware version"); 263 if (realOutputStartIndex >= 0) 264 { 265 string realOutput = output.Substring(realOutputStartIndex); 266 267 // Strip string into only numbers (integer or decimal). Discard any empty strings. 268 string[] split = Regex.Split(realOutput, @"[^0-9\.]+").Where(s => !string.IsNullOrEmpty(s.Trim())).ToArray(); 269 270 if (split.Length >= 3) // FW, SW, FPGA versions 271 { 272 fw_ver = split[0]; 273 sw_ver = split[1]; 274 275 // Success 276 return ret; 277 } 278 } 279 } 280 281 // Failure in all other cases 282 Console.WriteLine("FSEmul failed: Couldn't get firmware versions"); 283 return ret; 284 } 285 boot_mode_detect(string ip, out string boot_mode)286 internal static int boot_mode_detect(string ip, out string boot_mode) 287 { 288 #if DEBUG 289 Log.WriteLine("FSEmul.boot_mode_detect started."); 290 #endif 291 292 if (string.IsNullOrEmpty(ip)) 293 { 294 boot_mode = "UNKNOWN"; 295 return 1; 296 } 297 298 string arguments = "-ip " + ip + " -modedetect"; 299 300 // Remember and clear the TOUCAN_VERBOSE variable as this causes the version to be parsed as blank 301 string localTOUCAN_VERBOSE = Environment.GetEnvironmentVariable("TOUCAN_VERBOSE"); 302 Environment.SetEnvironmentVariable("TOUCAN_VERBOSE", ""); 303 304 string output = string.Empty; 305 int ret = ProcessExecutor.DoProcess_GetOutput(exe_path, arguments, out output); 306 307 // Restore the TOUCAN_VERBOSE variable 308 if (!string.IsNullOrEmpty(localTOUCAN_VERBOSE)) 309 { 310 Environment.SetEnvironmentVariable("TOUCAN_VERBOSE", localTOUCAN_VERBOSE); 311 } 312 313 if (ret != 0) 314 { 315 Console.WriteLine("FSEmul failed: Couldn't detect boot mode!"); 316 boot_mode = "UNKNOWN"; 317 return ret; 318 } 319 320 boot_mode = output.Trim(); 321 return 0; 322 } 323 start(string arguments, string fsemul_params)324 internal static int start(string arguments, string fsemul_params) 325 { 326 #if DEBUG 327 Log.WriteLine("FSEmul.start started."); 328 #endif 329 330 DataReceivedEventHandler handler = new DataReceivedEventHandler((sender, args) => { 331 if (args != null && args.Data != null) 332 { 333 Console.WriteLine(args.Data); 334 // If FSEmul throws, suggest using cafestop -makemine 335 if (args.Data.ToString().Contains("Bridge is being used by the PC with IP Address")) 336 { 337 Console.WriteLine("\nTry using 'cafex stop -makemine' to take control of the Bridge."); 338 } 339 } 340 }); 341 342 return ProcessExecutor.StartProcess_RedirectOutput(exe_path, arguments + " " + fsemul_params, handler, false); 343 } 344 } 345 346 /// <summary> 347 /// This class encapsulates the functionality of the mionbutton tool used by CafeX. 348 /// </summary> 349 static class MionButton 350 { 351 static string exe_path = "\"" + Environment.GetEnvironmentVariable("MION_BRIDGE_TOOLS") + "\\MionButton.exe" + "\""; 352 rsthold(string[] args)353 internal static int rsthold(string[] args) 354 { 355 #if DEBUG 356 Log.WriteLine("MionButton.rsthold started."); 357 #endif 358 string output = string.Empty; 359 int returnVal; 360 string arg_string = StringCombiner.MakeDelimitedString(args, ' '); 361 362 returnVal = ProcessExecutor.DoProcess_GetOutput(exe_path, "-ip " + Environment.GetEnvironmentVariable("BRIDGE_CURRENT_IP_ADDRESS") + " -rsthold " + arg_string, out output); 363 364 // Print output to console 365 Console.Write(output); 366 return returnVal; 367 } 368 forceOff1(string[] args)369 internal static int forceOff1(string[] args) 370 { 371 #if DEBUG 372 Log.WriteLine("mionButton.forceOff1 started."); 373 #endif 374 375 string output = string.Empty; 376 int returnVal; 377 string arg_string = StringCombiner.MakeDelimitedString(args, ' '); 378 379 returnVal = ProcessExecutor.DoProcess_GetOutput(exe_path, "-ip " + Environment.GetEnvironmentVariable("BRIDGE_CURRENT_IP_ADDRESS") + " -forceOff1 " + arg_string, out output); 380 381 // Print output to console 382 Console.Write(output); 383 return returnVal; 384 } 385 init_shutdown_w_FOFF2(string[] args)386 internal static int init_shutdown_w_FOFF2(string[] args) 387 { 388 #if DEBUG 389 Log.WriteLine("MionButton.init_shutdown_w_FOFF2 started."); 390 #endif 391 392 string output = string.Empty; 393 int returnVal; 394 string arg_string = StringCombiner.MakeDelimitedString(args, ' '); 395 396 returnVal = ProcessExecutor.DoProcess_GetOutput(exe_path, "-ip " + Environment.GetEnvironmentVariable("BRIDGE_CURRENT_IP_ADDRESS") + " -init_shutdown_w_FOFF2 60000 " + arg_string, out output); 397 398 // Print output to console 399 Console.Write(output); 400 return returnVal; 401 } 402 forceOff2_off_single_cgi(string[] args)403 internal static int forceOff2_off_single_cgi(string[] args) 404 { 405 #if DEBUG 406 Log.WriteLine("MionButton.forceOff2_off_single_cgi started."); 407 #endif 408 409 string output = string.Empty; 410 int returnVal; 411 string arg_string = StringCombiner.MakeDelimitedString(args, ' '); 412 413 returnVal = ProcessExecutor.DoProcess_GetOutput(exe_path, "-ip " + Environment.GetEnvironmentVariable("BRIDGE_CURRENT_IP_ADDRESS") + " -forceOff2_off_single_cgi " + arg_string, out output); 414 415 // Print output to console 416 Console.Write(output); 417 return returnVal; 418 419 } 420 } 421 422 /// <summary> 423 /// This class encapsulates the functionality of the miontelnet tool used by CafeX. 424 /// </summary> 425 static class miontelnet 426 { 427 static string exe_path = "\"" + Environment.GetEnvironmentVariable("CAFE_ROOT") + "\\system\\bin\\tool\\miontelnet.exe" + "\""; 428 Reboot(out string output)429 internal static int Reboot(out string output) 430 { 431 #if DEBUG 432 Log.WriteLine("miontelnet.Reboot started."); 433 #endif 434 435 return ProcessExecutor.DoProcess_GetOutput(exe_path, "-reboot", out output); 436 } 437 Run(out string output)438 internal static int Run(out string output) 439 { 440 #if DEBUG 441 Log.WriteLine("miontelnet.Run started."); 442 #endif 443 444 return ProcessExecutor.DoProcess_GetOutput(exe_path, null, out output); 445 } 446 } 447 448 /// <summary> 449 /// This class encapsulates the functionality of the mionps tool used by CafeX. 450 /// </summary> 451 static class mionps 452 { 453 static string exe_path = "\"" + Environment.GetEnvironmentVariable("CAFE_ROOT") + "\\system\\bin\\tool\\mionps.exe" + "\""; 454 private static readonly int MIONPS_TIMEOUT_MS = 30000; // 30 seconds 455 Run(string arguments)456 internal static string Run(string arguments) 457 { 458 #if DEBUG 459 Log.WriteLine("mionps.Run started."); 460 #endif 461 462 string output = string.Empty; 463 int returnVal = ProcessExecutor.DoProcess_GetOutput(exe_path, arguments, true, MIONPS_TIMEOUT_MS, out output); 464 // Currently, all the calls to mionps are assuming a single line without CRLF. 465 // If that changes, removing CRLF below will need to be removed and calls to RUN revisited. 466 output = output.Replace("\r\n", ""); 467 // Error checking for mionps 468 if (returnVal != 0) 469 { 470 Console.WriteLine("cafex : Warning! mionps tool returned code {0}.", returnVal); 471 Console.WriteLine("mionps stdout and stderr received:"); 472 Console.WriteLine(output); 473 } 474 475 return output; 476 } 477 } 478 479 /// <summary> 480 /// This class encapsulates the functionality of the mionurl tool used by CafeX. 481 /// </summary> 482 static class mionurl 483 { 484 static string exe_path = "\"" + Environment.GetEnvironmentVariable("CAFE_ROOT") + "\\system\\bin\\tool\\mionurl.exe" + "\""; 485 private static readonly int MIONURL_TIMEOUT_MS = 30000; // 30 seconds 486 Run(string arguments)487 internal static int Run(string arguments) 488 { 489 #if DEBUG 490 Log.WriteLine("mionurl.Run started."); 491 #endif 492 493 string output = string.Empty; 494 int returnVal = ProcessExecutor.DoProcess_GetOutput(exe_path, arguments, true, MIONURL_TIMEOUT_MS, out output); 495 // Currently, all the calls to mionurl are assuming a single line without CRLF. 496 // If that changes, removing CRLF below will need to be removed and calls to RUN revisited. 497 output = output.Replace("\r\n", ""); 498 // Error checking for mionurl 499 if (returnVal != 0) 500 { 501 Console.WriteLine("cafex : Warning! mionurl tool returned code {0}.", returnVal); 502 Console.WriteLine("mionurl stdout and stderr received:"); 503 Console.WriteLine(output); 504 } 505 506 return returnVal; 507 } 508 } 509 510 /// <summary> 511 /// This class encapsulates the functionality of the sessionmanager tool used by CafeX. 512 /// </summary> 513 static class SessionManagerUtil 514 { 515 static string exe_path = "\"" + Environment.GetEnvironmentVariable("MION_BRIDGE_TOOLS") + "\\SessionManagerUtil.exe" + "\""; 516 GetSessionInfo(out string output)517 internal static int GetSessionInfo(out string output) 518 { 519 #if DEBUG 520 Log.WriteLine("SessionManagerUtil.GetSessionInfo started."); 521 #endif 522 523 return ProcessExecutor.DoProcess_GetOutput(exe_path, "-p NAME DEBUG_OUT DEBUG_CONTROL HIO_OUT LAUNCH_CTRL NET_MANAGE PCFS_SATA", out output); 524 } 525 } 526 527 /// <summary> 528 /// This class encapsulates the functionality of the devkitmsg tool used by CafeX. 529 /// </summary> 530 static class devkitmsg 531 { 532 internal static string CAFEX_RECOVER_TEST = Environment.GetEnvironmentVariable("CAFEX_RECOVER_TEST"); 533 static string exe_path = "\"" + Environment.GetEnvironmentVariable("MION_BRIDGE_TOOLS") + "\\devkitmsg.exe" + "\""; 534 help(int timeout)535 internal static int help(int timeout) 536 { 537 #if DEBUG 538 Log.WriteLine("devkitmsg.help started with timeout = " + timeout.ToString()); 539 #endif 540 int returnVal = 2; 541 542 Console.WriteLine("cafex: Probing if COS is ready by sending devkit help msg:"); 543 string msg = "\"help\" -v -p " + Environment.GetEnvironmentVariable("SESSION_LAUNCH_CTRL_PORT"); 544 DateTime maxTime = DateTime.Now.AddMilliseconds((double)timeout); 545 546 //I don't think the following do-while does what some expect it to do. It seems like 547 //it is going to wait "timeout" seconds for devkitmsg to finish and then kill it? What's 548 //actually happening is that you will spam devkitmsg.help for "timeout" seconds 549 550 do 551 { 552 returnVal = ProcessExecutor.DoProcess_WaitTime(exe_path, msg, 10000); //10 seconds should be more than enough 553 if (returnVal == 0) 554 { 555 break; 556 } 557 558 System.Threading.Thread.Sleep(Program.RETRY_TIMESPAN); // wait for a second. 559 } 560 while (maxTime.CompareTo(DateTime.Now) > 0); 561 562 #if DEBUG 563 Log.WriteLine("devkitmsg.help returnVal = " + returnVal.ToString()); 564 #endif 565 566 return returnVal; 567 } 568 CosFlags(string ppc_os_flags)569 internal static int CosFlags(string ppc_os_flags) 570 { 571 #if DEBUG 572 Log.WriteLine("devkitmsg.CosFlags started."); 573 #endif 574 575 return ProcessExecutor.DoProcess(exe_path, "\"cos_flags " + ppc_os_flags + "\" -v -p " + Environment.GetEnvironmentVariable("SESSION_LAUNCH_CTRL_PORT")); 576 } 577 title_softlaunch_with_hint(string os, string tid, string hint, string port)578 internal static int title_softlaunch_with_hint(string os, string tid, string hint, string port) 579 { 580 #if DEBUG 581 Log.WriteLine("devkitmsg.title_softlaunch_with_hint started."); 582 #endif 583 584 return ProcessExecutor.DoProcess(exe_path, "\"title_softlaunch " + os + " " + tid + " " + hint + "\" -v -p " + port); 585 } 586 title_softlaunch(string os, string tid, string port)587 internal static int title_softlaunch(string os, string tid, string port) 588 { 589 #if DEBUG 590 Log.WriteLine("devkitmsg.title_softlaunch started."); 591 #endif 592 DataReceivedEventHandler callback = (sender, e) => 593 { 594 if (e != null && e.Data != null) 595 { 596 Console.WriteLine(e.Data); 597 } 598 }; 599 600 return ProcessExecutor.StartProcess_RedirectOutput(exe_path, "\"title_softlaunch " + os + " " + tid + "\" -v -p " + port, callback, true); 601 } 602 recover()603 internal static int recover() 604 { 605 #if DEBUG 606 Log.WriteLine("devkitmsg.recover started."); 607 #endif 608 609 if (CAFEX_RECOVER_TEST == "1") 610 { 611 Console.WriteLine("devkitmsg_cmd: recover -v -p "); 612 return 0; 613 } 614 615 return ProcessExecutor.DoProcess(exe_path, "recover -v -p " + Environment.GetEnvironmentVariable("SESSION_LAUNCH_CTRL_PORT")); 616 } 617 update_pcfs()618 internal static int update_pcfs() 619 { 620 #if DEBUG 621 Log.WriteLine("dvkitmsg.update_pcfs started."); 622 #endif 623 624 if (CAFEX_RECOVER_TEST == "1") 625 { 626 Console.WriteLine("devkitmsg_cmd: update /vol/storage_hfiomlc01/sys/update/pcfs -v -p "); 627 return 0; 628 } 629 630 return ProcessExecutor.DoProcess(exe_path, "\"update /vol/storage_hfiomlc01/sys/update/pcfs\" -v -p " + Environment.GetEnvironmentVariable("SESSION_LAUNCH_CTRL_PORT")); 631 } 632 update_reflash()633 internal static int update_reflash() 634 { 635 #if DEBUG 636 Log.WriteLine("devkitmsg.update_reflash started."); 637 #endif 638 639 if (CAFEX_RECOVER_TEST == "1") 640 { 641 Console.WriteLine("devkitmsg_cmd: reflash /vol/storage_hfiomlc01/sys/update/nand -v -p "); 642 return 0; 643 } 644 645 return ProcessExecutor.DoProcess(exe_path, "\"reflash /vol/storage_hfiomlc01/sys/update/nand\" -v -p " + Environment.GetEnvironmentVariable("SESSION_LAUNCH_CTRL_PORT")); 646 } 647 update_nand()648 internal static int update_nand() 649 { 650 #if DEBUG 651 Log.WriteLine("devkitmsg.update_nand started."); 652 #endif 653 654 if (CAFEX_RECOVER_TEST == "1") 655 { 656 Console.WriteLine("devkitmsg_cmd: update /vol/storage_hfiomlc01/sys/update/nand -v -p "); 657 return 0; 658 } 659 660 return ProcessExecutor.DoProcess(exe_path, "\"update /vol/storage_hfiomlc01/sys/update/nand\" -v -p " + Environment.GetEnvironmentVariable("SESSION_LAUNCH_CTRL_PORT")); 661 } 662 update(string update_path)663 internal static int update(string update_path) 664 { 665 #if DEBUG 666 Log.WriteLine("devkitmsg.update started."); 667 #endif 668 669 if (string.IsNullOrEmpty(update_path)) 670 { 671 return 1; 672 } 673 674 if (CAFEX_RECOVER_TEST == "1") 675 { 676 Console.WriteLine("devkitmsg_cmd: update " + update_path + " -v -p "); 677 return 0; 678 } 679 680 return ProcessExecutor.DoProcess(exe_path, "\"update " + update_path + "\" -v -p " + Environment.GetEnvironmentVariable("SESSION_LAUNCH_CTRL_PORT")); 681 } 682 reflash(string reflash_path)683 internal static int reflash(string reflash_path) 684 { 685 #if DEBUG 686 Log.WriteLine("devkitmsg.reflash started."); 687 #endif 688 if (string.IsNullOrEmpty(reflash_path)) 689 { 690 return 1; 691 } 692 693 if (CAFEX_RECOVER_TEST == "1") 694 { 695 Console.WriteLine("devkitmsg_cmd: reflash " + reflash_path + " -v -p "); 696 return 0; 697 } 698 699 return ProcessExecutor.DoProcess(exe_path, "\"reflash " + reflash_path + "\" -v -p " + Environment.GetEnvironmentVariable("SESSION_LAUNCH_CTRL_PORT")); 700 } 701 clr_usrdata()702 internal static int clr_usrdata() 703 { 704 #if DEBUG 705 Log.WriteLine("devkitmsg.clr_usrdata started."); 706 #endif 707 708 if (CAFEX_RECOVER_TEST == "1") 709 { 710 Console.WriteLine("devkitmsg_cmd: clr_usrdata -v -p "); 711 return 0; 712 } 713 714 return ProcessExecutor.DoProcess(exe_path, "clr_usrdata -v -p " + Environment.GetEnvironmentVariable("SESSION_LAUNCH_CTRL_PORT")); 715 } 716 sys_mode_dev()717 internal static int sys_mode_dev() 718 { 719 #if DEBUG 720 Log.WriteLine("devkitmsg.sys_mode_dev started."); 721 #endif 722 723 return ProcessExecutor.DoProcess(exe_path, "\"sys_mode 1\" -v -p " + Environment.GetEnvironmentVariable("SESSION_LAUNCH_CTRL_PORT")); 724 } 725 sys_mode_prod()726 internal static int sys_mode_prod() 727 { 728 #if DEBUG 729 Log.WriteLine("devkitmsg.sys_mode_prod started."); 730 #endif 731 732 return ProcessExecutor.DoProcess(exe_path, "\"sys_mode 0\" -v -p " + Environment.GetEnvironmentVariable("SESSION_LAUNCH_CTRL_PORT")); 733 } 734 sys_mode_test()735 internal static int sys_mode_test() 736 { 737 #if DEBUG 738 Log.WriteLine("devkitmsg.sys_mode_test started."); 739 #endif 740 741 return ProcessExecutor.DoProcess(exe_path, "\"sys_mode 2\" -v -p " + Environment.GetEnvironmentVariable("SESSION_LAUNCH_CTRL_PORT")); 742 } 743 standby_en(int value)744 internal static int standby_en(int value) 745 { 746 #if DEBUG 747 Log.WriteLine("devkitmsg.standby_en " + value); 748 #endif 749 750 return ProcessExecutor.DoProcess(exe_path, " 'standby_en 1' -v -p " + Environment.GetEnvironmentVariable("SESSION_LAUNCH_CTRL_PORT")); 751 } 752 753 754 } 755 756 static class cosdebug 757 { 758 #if TIMER 759 public static PerfTimer cosdebugSetupTime = new PerfTimer("cosdebugSetupTime"); 760 #endif 761 #if false 762 private static Thread retry_thread = null; 763 private static ManualResetEvent stop_event = null; 764 765 private struct LaunchRetryParams 766 { 767 public int port; 768 public string TID_HI; 769 public string TID_LO; 770 public int retries; 771 public int timeout; 772 public int delay; 773 } 774 #endif 775 StreamDiscard(Stream stream)776 internal static void StreamDiscard(Stream stream) 777 { 778 try 779 { 780 int b; 781 stream.ReadTimeout = 500; 782 #if DEBUG 783 Console.Write("cafex: cosdebug.launch discarding:"); 784 #endif 785 while ((b = stream.ReadByte()) != -1) 786 { 787 #if DEBUG 788 Console.Write(" {0:X2}", b); 789 #endif 790 } 791 } 792 catch (IOException) 793 { 794 // Eat this exception. The timeout just expired 795 } 796 finally 797 { 798 #if DEBUG 799 Console.WriteLine(); 800 #endif 801 } 802 } 803 #if false launch_retry_thread(object data)804 private static void launch_retry_thread(object data) 805 { 806 LaunchRetryParams lrparams = (LaunchRetryParams)data; 807 #if DEBUG 808 Log.WriteLine("cosdebug.launch_retry_thread started."); 809 Log.WriteLine("Params:"); 810 Log.WriteLine(string.Format(" port: {0}.", lrparams.port)); 811 Log.WriteLine(string.Format(" TID_HI: {0}.", lrparams.TID_HI)); 812 Log.WriteLine(string.Format(" TID_LO: {0}.", lrparams.TID_LO)); 813 Log.WriteLine(string.Format(" retries: {0}.", lrparams.retries)); 814 Log.WriteLine(string.Format(" timeout: {0}.", lrparams.timeout)); 815 #endif 816 cattoucan.ClearNotifications(); 817 818 ManualResetEvent[] evtHandle = new ManualResetEvent[3]; 819 820 evtHandle[0] = new ManualResetEvent(false); 821 cattoucan.AddNotification(Nintendo.SDSG.CatToucan.Terms.KI_PIREPARE_TITLE_ASYNC, evtHandle[0]); 822 823 evtHandle[1] = new ManualResetEvent(false); 824 cattoucan.AddNotification("System busy, try again", evtHandle[1]); 825 826 evtHandle[2] = stop_event; 827 828 for (int retry = 0; retry < lrparams.retries; retry++) 829 { 830 launch(lrparams.port, lrparams.TID_HI, lrparams.TID_LO); 831 832 long start = DateTime.Now.Ticks; 833 #if DEBUG 834 Log.WriteLine(string.Format("cosdebug.launch_retry_thread: waiting on handles {0} and {1}.", evtHandle[0].Handle, evtHandle[1].Handle)); 835 #endif 836 switch (WaitHandle.WaitAny(evtHandle, lrparams.timeout)) 837 { 838 case 0: 839 // Got the success message and we are done 840 Log.WriteLineRaw("cafex: Got successful title fast launch message."); 841 #if DEBUG 842 Log.WriteLine(string.Format("cosdebug.launch_retry_thread: waited {0}mS.", TimeSpan.FromTicks(DateTime.Now.Ticks - start).TotalMilliseconds)); 843 #endif 844 evtHandle[0].Reset(); 845 return; 846 847 case 1: 848 // Got the retry, so we continue 849 Log.WriteLineRaw(string.Format("cafex: Got system busy message after fast launch, waiting {0}mS and retrying...", lrparams.delay)); 850 #if DEBUG 851 Log.WriteLine(string.Format("cosdebug.launch_retry_thread: waited {0}mS.", TimeSpan.FromTicks(DateTime.Now.Ticks - start).TotalMilliseconds)); 852 Log.WriteLine(string.Format(" : delaying {0}mS.", lrparams.delay)); 853 #endif 854 evtHandle[1].Reset(); 855 Thread.Sleep(lrparams.delay); 856 break; 857 858 case 2: 859 #if DEBUG 860 Log.WriteLine("cosdebug.retry_launch_thread: Got stop event, returning."); 861 #endif 862 return; 863 864 case WaitHandle.WaitTimeout: 865 Log.WriteLineRaw(string.Format("cafex: Fastlaunch timeout of {0}mS exceeded waiting for title to start, exiting.", lrparams.timeout)); 866 Environment.Exit((int)CAFEX_ERROR.RUN_FASTLAUNCH_FAILED); 867 return; 868 } 869 } 870 871 // Exhausted all of our tries 872 Log.WriteLineRaw(string .Format("cafex: Unable to fastlaunch title after {0} attempts, exiting.", lrparams.retries)); 873 Environment.Exit((int)CAFEX_ERROR.RUN_FASTLAUNCH_FAILED); 874 } 875 launch_retry(int port, string TID_HI, string TID_LO, int retries, int timeout, int delay)876 internal static void launch_retry(int port, string TID_HI, string TID_LO, int retries, int timeout, int delay) 877 { 878 #if DEBUG 879 Log.WriteLine("cosdebug.launch_retry started."); 880 #endif 881 LaunchRetryParams lrparams = new LaunchRetryParams(); 882 883 lrparams.port = port; 884 lrparams.TID_HI = TID_HI; 885 lrparams.TID_LO = TID_LO; 886 lrparams.retries = retries; 887 lrparams.timeout = timeout; 888 lrparams.delay = delay; 889 890 retry_thread = new Thread(cosdebug.launch_retry_thread); 891 stop_event = new ManualResetEvent(false); 892 893 retry_thread.Start(lrparams); 894 #if DEBUG 895 Log.WriteLine("cosdebug.launch_retry exited."); 896 #endif 897 } 898 stop_retry(int timeout)899 public static void stop_retry(int timeout) 900 { 901 if (retry_thread != null) 902 { 903 stop_event.Set(); 904 retry_thread.Join(timeout); 905 } 906 } 907 #endif 908 launch(int port, string TID_HI, string TID_LO)909 internal static int launch(int port, string TID_HI, string TID_LO) 910 { 911 #if DEBUG 912 Log.WriteLine("cosdebug.launch started."); 913 #endif 914 try 915 { 916 TcpClient client = new TcpClient("localhost", port); 917 NetworkStream stream = client.GetStream(); 918 919 // Discard any input if anything is waiting after connect. COS sends some prompts after connect. 920 StreamDiscard(stream); 921 922 string message = string.Format("\rcos launch 0x{0} 0x{1}\r", TID_HI, TID_LO); 923 Log.WriteLineRaw(string.Format("cafex: sending '{0}' to the devkit using port {1}...", message.Trim(), port)); 924 byte[] data = System.Text.Encoding.ASCII.GetBytes(message); 925 926 #if DEBUG 927 Console.Write("cafex: cosdebug.launch write ({0} bytes):", data.Length); 928 for (int i = 0; i < data.Length; i++) 929 { 930 Console.Write(" 0x{0:X2}", data[i]); 931 } 932 Console.WriteLine(); 933 #endif 934 stream.WriteTimeout = 5000; 935 stream.Write(data, 0, data.Length); 936 937 // Discard any input stream if anything is sent after the write. 938 StreamDiscard(stream); 939 940 client.Close(); 941 } 942 catch (InvalidOperationException e) 943 { 944 Log.WriteLine(string.Format("cafex: cosdebug.launch: InvalidOperationException: {0}", e)); 945 } 946 catch (ArgumentNullException e) 947 { 948 Log.WriteLine(string.Format("cafex: cosdebug.launch: ArgumentNullException: {0}", e)); 949 } 950 catch (SocketException e) 951 { 952 Log.WriteLine(string.Format("cafex: cosdebug.launch: SocketException: {0}", e)); 953 } 954 catch (IOException e) 955 { 956 Log.WriteLine(string.Format("cafex: cosdebug.launch: IOException: {0}", e)); 957 } 958 959 return 0; 960 } 961 try_launch(string TID, int index)962 internal static bool try_launch(string TID, int index) 963 { 964 int retries = Convert.ToInt32(Program.CAFERUN_OPTION_FASTLAUNCH_RETRIES.value); 965 int timeout = Convert.ToInt32(Program.CAFERUN_OPTION_FASTLAUNCH_TIMEOUT.value); 966 int delay = Convert.ToInt32(Program.CAFERUN_OPTION_FASTLAUNCH_DELAY.value); 967 int port = Convert.ToInt32(Program.SESSION_NET_MANAGE_PORT.value); 968 string TID_HI = TID.Substring(index, 8); 969 string TID_LO = TID.Substring(index + 8, 8); 970 971 if (Program.CAFE_PROFILE.value != null && Program.CAFE_PROFILE.value == "1") 972 { 973 CafeXEventtLog.Instance.WriteToEventLog(562, string.Format("[{0}] [BEGIN] [CafeX] System is doing FAST RELAUNCH", DateTime.Now.ToString("HH:mm:ss:fff"))); 974 } 975 976 cattoucan.BeginTitleFastSync(); 977 for (index = 0; index < retries; ++index) 978 { 979 cattoucan.PrepareFastLaunch(delay); 980 launch(port, TID_HI, TID_LO); 981 if (cattoucan.SyncWithTitle(timeout, true)) 982 { 983 return true; 984 } 985 #if DEBUG 986 Log.WriteLine("Retrying fast launch..."); 987 #endif 988 } 989 990 cattoucan.FinishSync(true); 991 return false; 992 } 993 ParseReceivedMessage(string sMessage, string sParseStr, string sArgs)994 internal static bool ParseReceivedMessage(string sMessage, string sParseStr, string sArgs) 995 { 996 string[] msgArray = sMessage.Split(' '); 997 for (int i = 0; i < msgArray.Length; i++) 998 { 999 string str = msgArray[i]; 1000 if ((str.CompareTo(sParseStr) == 0) && 1001 ((i + 1) < msgArray.Length) && 1002 (msgArray[i + 1].CompareTo(sArgs) == 0)) 1003 return true; 1004 } 1005 1006 return false; 1007 } 1008 SendCOSCommandAndRecvReply(int iPort, string sCmd, string sArgs, int iRetries, int iTimeout, int iDelay)1009 internal static string SendCOSCommandAndRecvReply(int iPort, string sCmd, string sArgs, int iRetries, int iTimeout, int iDelay) 1010 { 1011 StringBuilder completeMessage = new StringBuilder(); 1012 TcpClient client = null; 1013 NetworkStream stream = null; 1014 #if DEBUG 1015 Log.WriteLine("cosdebug." + sCmd + " started."); 1016 #endif 1017 try 1018 { 1019 #if TIMER 1020 Log.WriteLine("new TcpClient start"); 1021 cosdebugSetupTime.Report(); 1022 #endif 1023 client = new TcpClient("localhost", iPort); 1024 #if TIMER 1025 Log.WriteLine("new TcpClient end"); 1026 cosdebugSetupTime.Report(); 1027 #endif 1028 stream = client.GetStream(); 1029 // Discard any input if anything is waiting after connect. COS sends some prompts after connect. 1030 //StreamDiscard(stream); 1031 1032 string message = string.Format("{0} {1}\r", sCmd, sArgs); 1033 Log.WriteLineRaw(string.Format("cafex: sending '{0}' to the devkit using port {1}...", message.Trim(), iPort)); 1034 byte[] data = System.Text.Encoding.ASCII.GetBytes(message); 1035 1036 #if DEBUG 1037 Console.Write("cafex: cosdebug.{0} write ({1} bytes):", sCmd, data.Length); 1038 for (int i = 0; i < data.Length; i++) 1039 { 1040 Console.Write(" 0x{0:X2}", data[i]); 1041 } 1042 Console.WriteLine(); 1043 #endif 1044 stream.WriteTimeout = iTimeout; 1045 stream.ReadTimeout = iTimeout; 1046 stream.Write(data, 0, data.Length); 1047 1048 Thread.Sleep(iDelay); 1049 1050 if (stream.CanRead) 1051 { 1052 byte[] readBuffer = new byte[4096]; 1053 int readIndex = 0; 1054 int numberOfBytesRead = 0; 1055 int count = 0; 1056 1057 while (!stream.DataAvailable) 1058 { 1059 if (count == iRetries) 1060 { 1061 break; 1062 } 1063 Thread.Sleep(iDelay); 1064 count++; 1065 } 1066 if (count <= iRetries || stream.DataAvailable) 1067 { 1068 1069 // Incoming message may be larger than the buffer size. 1070 while (stream.DataAvailable) 1071 { 1072 numberOfBytesRead = stream.Read(readBuffer, readIndex, readBuffer.Length); 1073 completeMessage.AppendFormat("{0}", Encoding.ASCII.GetString(readBuffer, 0, numberOfBytesRead)); 1074 readIndex += numberOfBytesRead; 1075 Thread.Sleep(200); 1076 } 1077 #if DEBUG 1078 Console.Write("cafex: cosdebug.{0} read ({1}):", sCmd, completeMessage); 1079 Console.WriteLine(); 1080 #endif 1081 } 1082 } 1083 } 1084 catch (InvalidOperationException e) 1085 { 1086 Log.WriteLine(string.Format("cafex: cosdebug.{0}: InvalidOperationException: {1}", sCmd, e)); 1087 } 1088 catch (ArgumentNullException e) 1089 { 1090 Log.WriteLine(string.Format("cafex: cosdebug.{0}: ArgumentNullException: {1}", sCmd, e)); 1091 } 1092 catch (SocketException e) 1093 { 1094 Log.WriteLine(string.Format("cafex: cosdebug.{0}: SocketException: {1}", sCmd, e)); 1095 } 1096 catch (IOException e) 1097 { 1098 Log.WriteLine(string.Format("cafex: cosdebug.{0}: IOException: {1}", sCmd, e)); 1099 } 1100 catch (Exception e) 1101 { 1102 Log.WriteLine(string.Format("cafex: cosdebug.{0}: Exception: {1}", sCmd, e)); 1103 } 1104 1105 finally 1106 { 1107 if (stream != null) 1108 { 1109 stream.Close(); 1110 } 1111 if (client != null) 1112 { 1113 client.Close(); 1114 } 1115 } 1116 return completeMessage.ToString(); 1117 } 1118 1119 #if false SendCOSCommandAndRecvReply(int iPort, string sCmd, string sArgs, int iRetries, int iTimeout, int iDelay)1120 internal static string SendCOSCommandAndRecvReply(int iPort, string sCmd, string sArgs, int iRetries, int iTimeout, int iDelay) 1121 { 1122 #if DEBUG 1123 Log.WriteLine("cosdebug." + sCmd + " started."); 1124 #endif 1125 Socket skt = null; 1126 StringBuilder completeMessage = new StringBuilder(); 1127 try 1128 { 1129 IPAddress[] ipAddrList = Dns.GetHostEntry("localhost").AddressList; 1130 1131 skt = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 1132 1133 skt.Connect(ipAddrList, iPort); 1134 1135 if (skt.Connected) 1136 { 1137 string message = string.Format("{0} {1}\r", sCmd, sArgs); 1138 Log.WriteLineRaw(string.Format("cafex: sending '{0}' to the devkit using port {1}...", message.Trim(), iPort)); 1139 byte[] bytesSent = System.Text.Encoding.ASCII.GetBytes(message); 1140 1141 #if DEBUG 1142 Console.Write("cafex: cosdebug.{0} write ({1} bytes):", sCmd, bytesSent.Length); 1143 for (int i = 0; i < bytesSent.Length; i++) 1144 { 1145 Console.Write(" 0x{0:X2}", bytesSent[i]); 1146 } 1147 Console.WriteLine(); 1148 #endif 1149 skt.SendTimeout = iTimeout; 1150 skt.ReceiveTimeout = iTimeout; 1151 skt.Send(bytesSent, bytesSent.Length, 0); 1152 1153 Thread.Sleep(1000); 1154 1155 byte[] bytesRead = new byte[4096]; 1156 int numberOfBytesRead = 0; 1157 1158 numberOfBytesRead = skt.Receive(bytesRead, bytesRead.Length, 0); 1159 completeMessage.AppendFormat("{0}", Encoding.ASCII.GetString(bytesRead, 0, numberOfBytesRead)); 1160 1161 #if DEBUG 1162 Console.Write("cafex: cosdebug.{0} read ({1}):", sCmd, completeMessage); 1163 Console.WriteLine(); 1164 #endif 1165 } 1166 } 1167 catch (InvalidOperationException e) 1168 { 1169 Log.WriteLine(string.Format("cafex: cosdebug.{0}: InvalidOperationException: {1}", sCmd, e)); 1170 } 1171 catch (ArgumentNullException e) 1172 { 1173 Log.WriteLine(string.Format("cafex: cosdebug.{0}: ArgumentNullException: {1}", sCmd, e)); 1174 } 1175 catch (SocketException e) 1176 { 1177 Log.WriteLine(string.Format("cafex: cosdebug.{0}: SocketException: {1}", sCmd, e)); 1178 } 1179 catch (IOException e) 1180 { 1181 Log.WriteLine(string.Format("cafex: cosdebug.{0}: IOException: {1}", sCmd, e)); 1182 } 1183 finally 1184 { 1185 if (skt != null) 1186 { 1187 skt.Close(); 1188 } 1189 } 1190 return completeMessage.ToString(); 1191 } 1192 #endif 1193 RecvReply(int iPort, int iTimeout)1194 internal static string RecvReply(int iPort, int iTimeout) 1195 { 1196 try 1197 { 1198 TcpClient client = new TcpClient("localhost", iPort); 1199 NetworkStream stream = client.GetStream(); 1200 1201 if (stream.CanRead) 1202 { 1203 byte[] readBuffer = new byte[4096]; 1204 StringBuilder completeMessage = new StringBuilder(); 1205 int numberOfBytesRead = 0; 1206 int count = 10; 1207 1208 while (!stream.DataAvailable) 1209 { 1210 if (count == 0) 1211 { 1212 break; 1213 } 1214 Thread.Sleep(10); 1215 count--; 1216 } 1217 1218 if (count > 0 || stream.DataAvailable) 1219 { 1220 1221 // Incoming message may be larger than the buffer size. 1222 do 1223 { 1224 numberOfBytesRead = stream.Read(readBuffer, 0, readBuffer.Length); 1225 1226 completeMessage.AppendFormat("{0}", Encoding.ASCII.GetString(readBuffer, 0, numberOfBytesRead)); 1227 1228 } while (stream.DataAvailable); 1229 #if DEBUG 1230 Console.Write("cafex: cosdebug.RecvReply read ({0}):", completeMessage); 1231 Console.WriteLine(); 1232 #endif 1233 } 1234 client.Close(); 1235 return completeMessage.ToString(); 1236 } 1237 1238 client.Close(); 1239 return string.Empty; 1240 } 1241 catch (InvalidOperationException e) 1242 { 1243 Log.WriteLine(string.Format("cafex: cosdebug.RecvReply: InvalidOperationException: {0}", e)); 1244 } 1245 catch (ArgumentNullException e) 1246 { 1247 Log.WriteLine(string.Format("cafex: cosdebug.RecvReply: ArgumentNullException: {0}", e)); 1248 } 1249 catch (SocketException e) 1250 { 1251 Log.WriteLine(string.Format("cafex: cosdebug.RecvReply: SocketException: {0}", e)); 1252 } 1253 catch (IOException e) 1254 { 1255 Log.WriteLine(string.Format("cafex: cosdebug.RecvReply: IOException: {0}", e)); 1256 } 1257 1258 return string.Empty; 1259 } 1260 SendKillRestartAndResponse(int iPort, int iRetries, int iTimeout, int iDelay)1261 internal static bool SendKillRestartAndResponse(int iPort, int iRetries, int iTimeout, int iDelay) 1262 { 1263 string args = Convert.ToString((int)DateTime.Now.Ticks); 1264 #if TIMER 1265 Log.WriteLine("SendCOSCommandAndRecvReply start"); 1266 cosdebugSetupTime.Reset(); 1267 cosdebugSetupTime.Start(); 1268 #endif 1269 string reply = SendCOSCommandAndRecvReply(iPort, 1270 "cos killrestart", 1271 args, 1272 iRetries, 1273 iTimeout, 1274 iDelay); 1275 #if TIMER 1276 Log.WriteLine("SendCOSCommandAndRecvReply end"); 1277 cosdebugSetupTime.Stop(); 1278 #endif 1279 if (string.IsNullOrEmpty(reply)) 1280 { 1281 return false; 1282 } 1283 1284 bool bFoundAck = ParseReceivedMessage(reply, "kill_ack", args); 1285 bool bFoundDone = ParseReceivedMessage(reply, "kill_done", args); 1286 1287 if (bFoundAck && bFoundDone) 1288 return true; 1289 1290 //This happens rarely 1291 if (bFoundAck && !bFoundDone) 1292 { 1293 Thread.Sleep(iDelay); 1294 reply = RecvReply(iPort, iDelay); 1295 1296 if (string.IsNullOrEmpty(reply)) 1297 return false; 1298 bFoundDone = ParseReceivedMessage(reply, "kill_done", args); 1299 1300 if (bFoundDone) 1301 return true; 1302 } 1303 1304 return (bFoundAck && bFoundDone); 1305 } 1306 } 1307 1308 /// <summary> 1309 /// This class encapsulates the functionality of the synctool used by CafeX. 1310 /// </summary> 1311 static class synctool 1312 { 1313 static string exe_path = "\"" + Environment.GetEnvironmentVariable("CAFE_ROOT") + "\\system\\bin\\tool\\synctool.exe" + "\""; 1314 sync(string cfg, string src, string dst, string log)1315 internal static int sync(string cfg, string src, string dst, string log) 1316 { 1317 #if DEBUG 1318 Log.WriteLine("synctool.sync started."); 1319 #endif 1320 1321 FileUtil.AddQuotes(ref src); 1322 FileUtil.AddQuotes(ref dst); 1323 string output = string.Empty; 1324 int ret = ProcessExecutor.DoProcess_GetOutput(exe_path, "-cfgxml " + cfg + " " + src + " " + dst + " ", out output); 1325 FileStream fs = new FileStream(log, FileMode.Create); 1326 StreamWriter sw = new StreamWriter(fs); 1327 sw.Write(output); 1328 sw.Flush(); 1329 sw.Close(); 1330 return ret; 1331 } 1332 } 1333 1334 /// <summary> 1335 /// This class encapsulates the functionality of the pcfsserversync tool used by CafeX. 1336 /// </summary> 1337 static class PCFSServerSync 1338 { 1339 static string exe_path = Environment.GetEnvironmentVariable("CAFE_ROOT") + "\\system\\bin\\tool\\PCFSServerSync.exe"; 1340 sync(string date, string elf, string mapping)1341 internal static int sync(string date, string elf, string mapping) 1342 { 1343 #if DEBUG 1344 Log.WriteLine("PCFSServerSync.sync started."); 1345 #endif 1346 1347 return ProcessExecutor.DoProcess(exe_path, "-comment \"cafex run: ----- [" + date + "] Launching " + Path.GetFileName(elf) + " -----\" " + Environment.GetEnvironmentVariable("PCFS_HEADLESS_EMUL") + " -softlaunch -message " + mapping); 1348 } 1349 wait_sync(string date)1350 internal static int wait_sync(string date) 1351 { 1352 #if DEBUG 1353 Log.WriteLine("PCFSServerSync.wait_sync started."); 1354 #endif 1355 1356 return ProcessExecutor.DoProcess(exe_path, "-wait 25000 " + Environment.GetEnvironmentVariable("PCFS_HEADLESS_EMUL") + " -comment cafex run: [" + date + "] ----- Hard-launch Startup Complete -----"); 1357 } 1358 } 1359 1360 1361 /// <summary> 1362 /// This class encapsulates the functionality of the ImageUploader tool used by CafeX. 1363 /// </summary> 1364 static class ImageUploader 1365 { 1366 static string exe_path = Environment.GetEnvironmentVariable("MION_BRIDGE_TOOLS") + "\\ImageUploader.exe"; 1367 upload(string ip, int bankno, string wumad_file)1368 internal static int upload(string ip, int bankno, string wumad_file) 1369 { 1370 #if DEBUG 1371 Log.WriteLine("ImageUploader.upload started."); 1372 #endif 1373 DataReceivedEventHandler callback = (sender, e) => 1374 { 1375 if (e != null && e.Data != null) 1376 { 1377 Console.WriteLine(e.Data); 1378 } 1379 }; 1380 1381 return ProcessExecutor.StartProcess_RedirectOutput(exe_path, string.Format("-ip {0} -upload {1} -w {2}", ip, bankno, wumad_file), callback, true); 1382 } 1383 } 1384 1385 /// <summary> 1386 /// This class encapsulates the functionality of the winmakebsf tool used by CafeX. 1387 /// </summary> 1388 static class makebsf 1389 { 1390 static string exe_path = "\"" + Environment.GetEnvironmentVariable("CAFE_ROOT") + "\\system\\bin\\tool\\winmakebsf.exe" + "\""; 1391 make(string quiet, string bsf_file, string flags)1392 internal static int make(string quiet, string bsf_file, string flags) 1393 { 1394 #if DEBUG 1395 Log.WriteLine("makebsf.make started."); 1396 #endif 1397 FileUtil.AddQuotes(ref bsf_file); 1398 1399 string output = string.Empty; 1400 int ret = ProcessExecutor.DoProcess_GetOutput(exe_path, quiet + " -i 0x20008000 -j 0x20008800 -o " + bsf_file + " -f " + flags, out output); 1401 if (!string.IsNullOrEmpty(output)) 1402 { 1403 Console.Write(output); 1404 } 1405 1406 return ret; 1407 } 1408 } 1409 1410 /// <summary> 1411 /// This class encapsulates the functionality of the winmakedlf tool used by CafeX. 1412 /// </summary> 1413 static class makedlf 1414 { 1415 static string exe_path = "\"" + Environment.GetEnvironmentVariable("CAFE_ROOT") + "\\system\\bin\\tool\\winmakedlf.exe" + "\""; 1416 make(string quiet, string file_list, string output_dlf_file, out string commandResult)1417 internal static int make(string quiet, string file_list, string output_dlf_file, out string commandResult) 1418 { 1419 #if DEBUG 1420 Log.WriteLine("makedlf.make started."); 1421 #endif 1422 commandResult = string.Empty; 1423 FileUtil.AddQuotes(ref file_list); 1424 FileUtil.AddQuotes(ref output_dlf_file); 1425 return ProcessExecutor.DoProcess_GetOutput(exe_path, quiet + " -p " + file_list + " -l 0x0,0x80000,0x90000 -o " + output_dlf_file, out commandResult); 1426 } 1427 } 1428 1429 /// <summary> 1430 /// This class encapsulates the functionality of the makewumaddlf tool used by CafeX. 1431 /// </summary> 1432 static class makewumaddlf 1433 { 1434 static string exe_path = "\"" + Environment.GetEnvironmentVariable("CAFE_ROOT") + "\\system\\bin\\tool\\mastering\\makewumaddlf.exe" + "\""; 1435 make(string wumadFile, string extractionFolder, string output_dlf_file)1436 internal static int make(string wumadFile, string extractionFolder, string output_dlf_file) 1437 { 1438 #if DEBUG 1439 Log.WriteLine("make_wumad_dlf make started."); 1440 #endif 1441 1442 FileUtil.AddQuotes(ref extractionFolder); 1443 FileUtil.AddQuotes(ref output_dlf_file); 1444 1445 // In case the file is null, adjust the parameters accordingly 1446 if (!string.IsNullOrEmpty(wumadFile)) 1447 { 1448 FileUtil.AddQuotes(ref wumadFile); 1449 wumadFile = wumadFile + " "; 1450 } 1451 1452 DataReceivedEventHandler callback = (sender, e) => 1453 { 1454 if (e != null && e.Data != null) 1455 { 1456 Console.WriteLine(e.Data); 1457 } 1458 }; 1459 1460 return ProcessExecutor.StartProcess_RedirectOutput(exe_path, wumadFile + extractionFolder + " " + output_dlf_file, callback, true); 1461 } 1462 } 1463 1464 /// <summary> 1465 /// This class encapsulates the functionality of the cafemakedlf tool used by CafeX. 1466 /// </summary> 1467 static class cafemakedlf 1468 { 1469 static string exe_path = "\"" + Environment.GetEnvironmentVariable("CAFE_ROOT") + "\\system\\bin\\tool\\mastering\\cafemakedlf.exe" + "\""; 1470 make(string default_ddf, string common_ddf_file, string individual_ddf_file, string options)1471 internal static int make(string default_ddf, string common_ddf_file, string individual_ddf_file, string options) 1472 { 1473 #if DEBUG 1474 Log.WriteLine("cafemakedlf.make started."); 1475 #endif 1476 FileUtil.AddQuotes(ref default_ddf); 1477 FileUtil.AddQuotes(ref common_ddf_file); 1478 string arguments = "-uf " + default_ddf + " " + common_ddf_file + " "; 1479 if (individual_ddf_file != null) 1480 { 1481 FileUtil.AddQuotes(ref individual_ddf_file); 1482 arguments += " " + individual_ddf_file; 1483 } 1484 1485 if (options != null) 1486 { 1487 arguments += " " + options; 1488 } 1489 1490 return ProcessExecutor.DoProcess(exe_path, arguments); 1491 } 1492 } 1493 1494 /// <summary> 1495 /// This class encapsulates the functionality of the multi compiler used by CafeX. 1496 /// </summary> 1497 static class multi 1498 { 1499 static string exe_path = "\"" + Environment.GetEnvironmentVariable("GHS_ROOT") + "\\multi.exe" + "\""; 1500 start(string multi_connect, string cafe_multi_init, string multielf)1501 internal static int start(string multi_connect, string cafe_multi_init, string multielf) 1502 { 1503 #if DEBUG 1504 Log.WriteLine("multi.start started."); 1505 #endif 1506 String ProfCmd = ""; 1507 String ProfComment = Path.GetFileName(multielf); // change wacks so it prints out as a string nicely... 1508 FileUtil.AddQuotes(ref multielf); 1509 1510 if (Program.CAFE_PROFILE.value != null && Program.CAFE_PROFILE.value == "1") 1511 { 1512 CafeXEventtLog.Instance.WriteToEventLog(900, DateTime.Now, ProfComment); 1513 String ProfFunc = "eventCreate2 /id 901 /d " + ProfComment; 1514 // the ugliest line of code in the entire world 1515 ProfCmd = "-cmd \"python -b -s \\\"os.system('" + ProfFunc + "')\\\"\" "; 1516 } 1517 String ExeCmd = "-cmd prepare_target " + multi_connect + " " + cafe_multi_init + " " + ProfCmd + multielf; 1518 // Console.WriteLine("\n---------------\n" + exe_path + " " + ExeCmd + "\n-------------\n"); 1519 return ProcessExecutor.DoProcess_DontWait(exe_path, ExeCmd); 1520 } 1521 1522 } 1523 1524 internal enum SyncStage 1525 { 1526 None, 1527 Busy, 1528 Boot, 1529 TitleSoft, 1530 TitleFast, 1531 Menu, 1532 } 1533 1534 /// <summary> 1535 /// This class emulates the functionality of the cattoucan tool. 1536 /// </summary> 1537 static class cattoucan 1538 { 1539 private static List<KeyValuePair<string, ManualResetEvent>> notifyList = new List<KeyValuePair<string, ManualResetEvent>>(); 1540 private static List<KeyValuePair<string, Func<string, bool>>> callbackList = new List<KeyValuePair<string, Func<string, bool>>>(); 1541 1542 internal static SyncStage sync = SyncStage.None; 1543 private static Nintendo.SDSG.CatToucan toucan; 1544 private static EventWaitHandle evtHandle = null; 1545 private static Thread cattoucanThread = null; 1546 private static Nintendo.SDSG.CatToucan.ExitReason exit_reason = null; 1547 outputThread(object arg)1548 static void outputThread(object arg) 1549 { 1550 // Start relaying data 1551 exit_reason = toucan.RelaySerialCharacters((Program.quiet_mode && !Program.ignore_quiet_mode) ? 1552 TextWriter.Null : Console.Out, 1553 true); 1554 lock (cattoucanThread) 1555 { 1556 toucan = null; 1557 } 1558 1559 // We don't expect for toucan to exit if we're trying to sync something 1560 if (sync != SyncStage.None) 1561 { 1562 Console.WriteLine("cafex {0}: WARNING: CatToucan exited during sync! Cafex Code={1}, App Code={2}, Sync={3}", 1563 Program.command, 1564 exit_reason.reason, 1565 exit_reason.AppExitCode, 1566 sync); 1567 } 1568 #if DEBUG 1569 Log.WriteLine("cattoucan exiting with reason = " + exit_reason.reason); 1570 Log.WriteLine("Application exited with code " + exit_reason.AppExitCode); 1571 #endif 1572 if (exit_reason.reason == Nintendo.SDSG.CatToucan.ExitReason.Reason.StoppedDueToDroppedConnection) 1573 { 1574 Console.WriteLine("cafex : connection to CAT-DEV on port {0} failed or was dropped.", arg); 1575 } 1576 } 1577 createCattoucan(bool exclusive_match)1578 static void createCattoucan(bool exclusive_match) 1579 { 1580 string port = Program.SESSION_DEBUG_OUT_PORT.value; 1581 #if DEBUG 1582 Log.WriteLine("cattoucan.start started. port=" + port); 1583 #endif 1584 if (port.StartsWith("localhost:")) 1585 { 1586 port = port.Remove(0, 10); 1587 } 1588 #if DEBUG 1589 Log.WriteLine("cattoucan starting to read from port " + port); 1590 #endif 1591 toucan = new Nintendo.SDSG.CatToucan(Convert.ToInt32(port)); 1592 foreach (KeyValuePair<string, ManualResetEvent> kvp in notifyList) 1593 { 1594 toucan.AddNotification(kvp); 1595 } 1596 foreach (KeyValuePair<string, Func<string, bool>> kvp in callbackList) 1597 { 1598 toucan.AddNotification(kvp); 1599 } 1600 1601 toucan.ExclusiveMatch = exclusive_match; 1602 cattoucanThread = new Thread(new ParameterizedThreadStart(outputThread)); 1603 cattoucanThread.Start(port); 1604 } 1605 start(bool no_console, bool exclusive_match)1606 internal static int start(bool no_console, bool exclusive_match) 1607 { 1608 if (Program.quiet_mode) 1609 { 1610 stopCattoucan(); 1611 #if DEBUG 1612 Log.WriteLine("cattoucan DID NOT START because quiet is true"); 1613 #endif 1614 return 0; 1615 } 1616 1617 if (cattoucanThread != null) 1618 { 1619 lock (cattoucanThread) 1620 { 1621 if (toucan != null) 1622 { 1623 toucan.ExclusiveMatch = exclusive_match; 1624 } 1625 } 1626 } 1627 else 1628 { 1629 createCattoucan(exclusive_match); 1630 } 1631 1632 #if DEBUG 1633 Log.WriteLine("Joining cattoucan thread from start"); 1634 #endif 1635 cattoucanThread.Join(); 1636 cattoucanThread = null; 1637 #if DEBUG 1638 Log.WriteLine("Async cattoucan exited from start"); 1639 #endif 1640 return exit_reason.AppExitCode; 1641 } 1642 stopCattoucan()1643 internal static int stopCattoucan() 1644 { 1645 if (cattoucanThread == null) 1646 { 1647 return -1; 1648 } 1649 #if DEBUG 1650 Log.WriteLine("Stopping relay"); 1651 #endif 1652 lock (cattoucanThread) 1653 { 1654 if (toucan != null) 1655 { 1656 toucan.StopRelay(); 1657 } 1658 } 1659 #if DEBUG 1660 Log.WriteLine("Joining cattoucan thread from stop"); 1661 #endif 1662 cattoucanThread.Join(); 1663 cattoucanThread = null; 1664 #if DEBUG 1665 Log.WriteLine("Async cattoucan stopped"); 1666 #endif 1667 if (exit_reason.reason != Nintendo.SDSG.CatToucan.ExitReason.Reason.StoppedDueToDroppedConnection) 1668 { 1669 return exit_reason.AppExitCode; 1670 } 1671 1672 return 0; 1673 } 1674 AddNotification(string match, ManualResetEvent evt)1675 internal static void AddNotification(string match, ManualResetEvent evt) 1676 { 1677 KeyValuePair<string, ManualResetEvent> kvp = new KeyValuePair<string, ManualResetEvent>(match, evt); 1678 if (toucan != null) 1679 { 1680 toucan.AddNotification(kvp); 1681 } 1682 1683 notifyList.Add(kvp); 1684 } 1685 closeEvent(ref EventWaitHandle evtHandle)1686 private static void closeEvent(ref EventWaitHandle evtHandle) 1687 { 1688 if (evtHandle != null) 1689 { 1690 evtHandle.Close(); 1691 evtHandle = null; 1692 } 1693 } 1694 AddNotification(string match, Func<string, bool> callback)1695 internal static void AddNotification(string match, Func<string, bool> callback) 1696 { 1697 KeyValuePair<string, Func<string, bool>> kvp = new KeyValuePair<string, Func<string, bool>>(match, callback); 1698 if (toucan != null) 1699 { 1700 toucan.AddNotification(kvp); 1701 } 1702 1703 int already = callbackList.IndexOf(kvp); 1704 if (already >= 0) 1705 { 1706 #if DEBUG 1707 Log.WriteLine("Overriding existing handler for '{0}'!", match); 1708 #endif 1709 callbackList.RemoveAt(already); 1710 } 1711 callbackList.Add(kvp); 1712 } 1713 ClearNotifications()1714 internal static void ClearNotifications() 1715 { 1716 if (toucan != null) 1717 { 1718 toucan.ClearNotifications(); 1719 } 1720 1721 notifyList.Clear(); 1722 callbackList.Clear(); 1723 } 1724 BeginBootSync()1725 internal static void BeginBootSync() 1726 { 1727 sync = SyncStage.None; 1728 1729 // Prepare cattoucan to wait for boot syncronization 1730 closeEvent(ref evtHandle); 1731 evtHandle = new EventWaitHandle(false, EventResetMode.ManualReset); 1732 1733 if (cattoucanThread == null) 1734 { 1735 createCattoucan(false); 1736 } 1737 } 1738 SendSyncRequest(int timeout)1739 internal static bool SendSyncRequest(int timeout) 1740 { 1741 if (evtHandle == null) 1742 { 1743 return false; 1744 } 1745 1746 lock (cattoucanThread) 1747 { 1748 sync = SyncStage.None; 1749 } 1750 1751 // Reset the handle and try sending the request 1752 evtHandle.Reset(); 1753 sync = SyncStage.Boot; 1754 return devkitmsg.help(timeout) == 0; 1755 } 1756 SignalBootEvent()1757 internal static void SignalBootEvent() 1758 { 1759 lock (cattoucanThread) 1760 { 1761 if (sync == SyncStage.Boot) 1762 { 1763 sync = SyncStage.None; 1764 evtHandle.Set(); 1765 } 1766 } 1767 } 1768 SyncWithBoot(int timeout)1769 internal static bool SyncWithBoot(int timeout) 1770 { 1771 if (evtHandle == null) 1772 { 1773 return false; 1774 } 1775 1776 // Wait for this message to be triggered 1777 Console.WriteLine("\nCafex {0}: Waiting for response...", Program.command); 1778 return evtHandle.WaitOne(timeout); 1779 } 1780 BeginTitleSoftSync()1781 internal static void BeginTitleSoftSync() 1782 { 1783 sync = SyncStage.None; 1784 1785 closeEvent(ref evtHandle); 1786 evtHandle = new EventWaitHandle(false, EventResetMode.AutoReset); 1787 1788 sync = SyncStage.TitleSoft; 1789 1790 if (cattoucanThread == null) 1791 { 1792 createCattoucan(false); 1793 } 1794 } 1795 BeginTitleFastSync()1796 internal static void BeginTitleFastSync() 1797 { 1798 stopCattoucan(); 1799 1800 closeEvent(ref evtHandle); 1801 evtHandle = new EventWaitHandle(false, EventResetMode.AutoReset); 1802 1803 sync = SyncStage.None; 1804 1805 createCattoucan(true); 1806 } 1807 PrepareFastLaunch(int delay)1808 internal static void PrepareFastLaunch(int delay) 1809 { 1810 if (sync != SyncStage.Busy) 1811 { 1812 delay = 0; 1813 } 1814 1815 lock (cattoucanThread) 1816 { 1817 sync = SyncStage.None; 1818 } 1819 1820 if (delay != 0) 1821 { 1822 Thread.Sleep(delay); 1823 } 1824 1825 sync = SyncStage.TitleFast; 1826 } 1827 SignalTitleEvent(SyncStage next)1828 internal static void SignalTitleEvent(SyncStage next) 1829 { 1830 lock (cattoucanThread) 1831 { 1832 if (sync != SyncStage.None) 1833 { 1834 #if DEBUG 1835 Log.WriteLine("Signaling title event, next=" + next.ToString()); 1836 #endif 1837 sync = next; 1838 evtHandle.Set(); 1839 } 1840 } 1841 } 1842 SyncWithTitle(int timeout, bool stop)1843 internal static bool SyncWithTitle(int timeout, bool stop) 1844 { 1845 if (evtHandle != null) 1846 { 1847 // Wait for the event to be called 1848 while (evtHandle.WaitOne(timeout)) 1849 { 1850 if (sync == SyncStage.None) 1851 { 1852 // Successfully called 1853 FinishSync(stop); 1854 return true; 1855 } 1856 1857 if (sync == SyncStage.Busy) 1858 { 1859 return false; 1860 } 1861 } 1862 } 1863 return false; 1864 } 1865 BeginMenuSync()1866 internal static void BeginMenuSync() 1867 { 1868 if (cattoucanThread != null) 1869 { 1870 Monitor.Enter(cattoucanThread); 1871 } 1872 1873 sync = SyncStage.None; 1874 1875 if (cattoucanThread != null) 1876 { 1877 Monitor.Exit(cattoucanThread); 1878 } 1879 1880 // Prepare cattoucan to wait for menu syncronization 1881 closeEvent(ref evtHandle); 1882 evtHandle = new EventWaitHandle(false, EventResetMode.ManualReset); 1883 1884 sync = SyncStage.Menu; 1885 1886 if (cattoucanThread == null) 1887 { 1888 createCattoucan(false); 1889 } 1890 } 1891 SignalMenuEvent()1892 internal static void SignalMenuEvent() 1893 { 1894 lock (cattoucanThread) 1895 { 1896 sync = SyncStage.None; 1897 evtHandle.Set(); 1898 } 1899 } 1900 SyncWithMenu()1901 internal static void SyncWithMenu() 1902 { 1903 if (evtHandle != null) 1904 { 1905 // Wait for the event to be called 1906 evtHandle.WaitOne(); 1907 FinishSync(true); 1908 } 1909 } 1910 FinishSync(bool stop)1911 internal static void FinishSync(bool stop) 1912 { 1913 // Clear the sync flags 1914 if (cattoucanThread != null) 1915 { 1916 Monitor.Enter(cattoucanThread); 1917 sync = SyncStage.None; 1918 1919 if (stop) 1920 { 1921 Monitor.Exit(cattoucanThread); 1922 1923 // Stop async cattoucan 1924 stopCattoucan(); 1925 } 1926 } 1927 else 1928 { 1929 // Do not try and exit lock 1930 stop = true; 1931 } 1932 1933 // Delete the event handles 1934 closeEvent(ref evtHandle); 1935 1936 if (!stop) 1937 { 1938 Monitor.Exit(cattoucanThread); 1939 } 1940 } 1941 } 1942 1943 /// <summary> 1944 /// This class encapsulates the functionality required to set the COM ports. 1945 /// </summary> 1946 static class cmd 1947 { 1948 static string exe_path = "cmd.exe"; 1949 mode(int comport)1950 internal static int mode(int comport) 1951 { 1952 #if DEBUG 1953 Log.WriteLine("cmd.mode started."); 1954 #endif 1955 1956 return ProcessExecutor.DoProcess(exe_path, "mode.com com" + comport + ": BAUD=115200 PARITY=N DATA=8 STOP=1 to=off xon=off odsr=off octs=on dtr=off rts=on idsr=off"); 1957 } 1958 } 1959 1960 /// <summary> 1961 /// This class encapsulates the functionality of the monitor tool used by CafeX. 1962 /// </summary> 1963 static class monitor 1964 { 1965 static string cygwin_monitor_exe_path = "\"" + Environment.GetEnvironmentVariable("CAFE_ROOT") + "\\system\\bin\\tool\\monitor.exe" + "\""; 1966 static readonly int MONITOR_FLUSH_TIME = 1; 1967 GetExeName()1968 private static string GetExeName() 1969 { 1970 string monitor_or_temp_exe_path; 1971 if (FileUtil.RunningFromCygwin) 1972 { 1973 // take the monitor from cygwin 1974 monitor_or_temp_exe_path = cygwin_monitor_exe_path; 1975 } 1976 else 1977 { 1978 monitor_or_temp_exe_path = FileUtil.ExpandExecutable(CafeX.Properties.Resources.win_monitor, "win_monitor.exe"); 1979 } 1980 return monitor_or_temp_exe_path; 1981 } 1982 start(string str_opt, string test_str, string timeout, string rc_file, string log)1983 internal static int start(string str_opt, string test_str, string timeout, string rc_file, string log) 1984 { 1985 #if DEBUG 1986 Log.WriteLine("monitor.start started."); 1987 #endif 1988 1989 string output = string.Empty; 1990 1991 int ret = ProcessExecutor.DoProcess_GetOutput(GetExeName(), str_opt + " \"" + test_str + "\" -t " + timeout + " -p " + Environment.GetEnvironmentVariable("SESSION_DEBUG_OUT_PORT"), out output); 1992 1993 FileStream fs = new FileStream(rc_file, FileMode.Create); 1994 StreamWriter sw = new StreamWriter(fs); 1995 sw.WriteLine(ret); 1996 sw.Flush(); 1997 sw.Close(); 1998 1999 fs = new FileStream(log, FileMode.Create); 2000 sw = new StreamWriter(fs); 2001 sw.WriteLine(output); 2002 sw.Flush(); 2003 sw.Close(); 2004 2005 return ret; 2006 } 2007 start_redirectionCallback(string str_opt, string test_str, string timeout, DataReceivedEventHandler callback)2008 internal static int start_redirectionCallback(string str_opt, string test_str, string timeout, DataReceivedEventHandler callback) 2009 { 2010 #if DEBUG 2011 Log.WriteLine("start_redirectionCallback started."); 2012 #endif 2013 2014 string output = string.Empty; 2015 int ret = ProcessExecutor.StartProcess_RedirectOutput(GetExeName(), str_opt + " \"" + test_str + "\" -t " + timeout + " -p " + Environment.GetEnvironmentVariable("SESSION_DEBUG_OUT_PORT"), callback, true); 2016 2017 return ret; 2018 } 2019 flush()2020 internal static void flush() 2021 { 2022 #if DEBUG 2023 Log.WriteLine("monitor.flush started."); 2024 #endif 2025 2026 int ret = ProcessExecutor.DoProcess(GetExeName(), "-t " + MONITOR_FLUSH_TIME + " -s " + MONITOR_FLUSH_TIME); 2027 2028 #if DEBUG 2029 Log.WriteLine("monitor.flush returned = " + ret); 2030 #endif 2031 } 2032 2033 } 2034 2035 static class mionsig 2036 { 2037 static class HTML_CONTENT_TYPE 2038 { 2039 public const string APP_FORM_URL_ENCODED = "application/x-www-form-urlencoded"; 2040 } 2041 2042 static class HTML_METHOD 2043 { 2044 public const string POST = "POST"; 2045 } 2046 2047 internal const string MION_SIG_FMT_ADDR = "http://{0}/signal_get.cgi"; 2048 internal const string MION_ADMIN_USER = "mion"; 2049 internal const string MION_ADMIN_PASS = "/Multi_I/O_Network/"; 2050 internal const string HTML_TAG_END = "</HTML>"; 2051 2052 // Get message between "<html>" tag getHtmlMsg(ref string response)2053 static void getHtmlMsg(ref string response) 2054 { 2055 int end = response.IndexOf(HTML_TAG_END, StringComparison.OrdinalIgnoreCase); 2056 response = response.Substring(6, end - 6); 2057 } 2058 getVDD2()2059 internal static int getVDD2() 2060 { 2061 int VDD2 = 0; 2062 2063 try 2064 { 2065 // Setup web request to MION 2066 HttpWebRequest webReq = (HttpWebRequest)WebRequest.Create(string.Format(MION_SIG_FMT_ADDR, Program.BRIDGE_CURRENT_IP_ADDRESS.value)); 2067 2068 byte[] data = Encoding.UTF8.GetBytes("sig=VDD2"); 2069 2070 webReq.Method = HTML_METHOD.POST; 2071 webReq.ContentType = HTML_CONTENT_TYPE.APP_FORM_URL_ENCODED; 2072 webReq.PreAuthenticate = true; 2073 webReq.Credentials = new NetworkCredential(MION_ADMIN_USER, MION_ADMIN_PASS); 2074 webReq.ContentLength = data.Length; 2075 2076 // Write the request to the stream 2077 using (Stream reqStream = webReq.GetRequestStream()) 2078 { 2079 reqStream.Write(data, 0, data.Length); 2080 reqStream.Flush(); 2081 } 2082 2083 // Obtain the response 2084 data = null; 2085 HttpWebResponse webResp = (HttpWebResponse)webReq.GetResponse(); 2086 webReq = null; 2087 2088 // Read response 2089 string response; 2090 using (Stream respStream = webResp.GetResponseStream()) 2091 { 2092 response = (new StreamReader(respStream)).ReadToEnd(); 2093 } 2094 webResp = null; 2095 2096 // Parse VDD2 signal 2097 getHtmlMsg(ref response); 2098 int.TryParse(response, out VDD2); 2099 2100 } // Any web or IO exception just report VDD2 as low 2101 catch (WebException e) 2102 { 2103 Console.WriteLine(e.Message); 2104 } 2105 catch (IOException e) 2106 { 2107 Console.WriteLine(e.Message); 2108 } 2109 2110 return VDD2; 2111 } 2112 } 2113 }