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