From 5b1cf1f67fd605d9aa12bb2ca60db4b4f629f767 Mon Sep 17 00:00:00 2001 From: Johannes Anderwald Date: Fri, 20 Jul 2007 18:55:03 +0000 Subject: [PATCH] - make sysreg work again under Windows svn path=/trunk/; revision=27759 --- reactos/tools/sysreg/conf_parser.cpp | 30 +- reactos/tools/sysreg/conf_parser.h | 5 +- reactos/tools/sysreg/namedpipe_reader.cpp | 6 +- reactos/tools/sysreg/rosboot_test.cpp | 316 +++++++++++----------- reactos/tools/sysreg/rosboot_test.h | 68 +++-- reactos/tools/sysreg/txtmode.cfg | 24 +- 6 files changed, 253 insertions(+), 196 deletions(-) diff --git a/reactos/tools/sysreg/conf_parser.cpp b/reactos/tools/sysreg/conf_parser.cpp index 388215ff4f5..e9c252974ce 100644 --- a/reactos/tools/sysreg/conf_parser.cpp +++ b/reactos/tools/sysreg/conf_parser.cpp @@ -59,12 +59,15 @@ namespace Sysreg_ if (ws_pos != string::npos && ws_pos > 0 && ws_pos < s_buffer.size()) { string name = s_buffer.substr (0, ws_pos); - string value = s_buffer.substr (ws_pos + 1); + string value = s_buffer.substr (ws_pos + 1, s_buffer.size() - ws_pos - 2); +/* if (value[value.length () -1] == 0xA) { // remove newline char value[value.length ()-1] = _T('\0'); } +*/ +// cerr << "name: "<< name << "value: "<< value << "|" << endl; m_Map[name] = value; ret = true; } @@ -88,6 +91,31 @@ namespace Sysreg_ ConfValue = it->second; return true; } +//---------------------------------------------------------------------------------------- + bool ConfigParser::getDoubleValue(string ConfVariable, double & ConfValue) + { + ConfigMap::iterator it = m_Map.find (ConfVariable); + if (it == m_Map.end ()) + { + cerr << "ConfigParser::getValue failed to find " << ConfVariable << endl; + return false; + } + ConfValue = _tcstod(it->second.c_str(), NULL); + return true; + } +//----------------------------------------------------------------------------------------- + bool ConfigParser::getIntValue(string ConfVariable, long int & ConfValue) + { + ConfigMap::iterator it = m_Map.find (ConfVariable); + if (it == m_Map.end ()) + { + cerr << "ConfigParser::getValue failed to find " << ConfVariable << endl; + return false; + } + + ConfValue = _tcstol(it->second.c_str(), NULL, 10); + return true; + } } // end of namespace Sysreg_ diff --git a/reactos/tools/sysreg/conf_parser.h b/reactos/tools/sysreg/conf_parser.h index f84e39c5ee3..d7875ae2b71 100644 --- a/reactos/tools/sysreg/conf_parser.h +++ b/reactos/tools/sysreg/conf_parser.h @@ -77,6 +77,9 @@ namespace Sysreg_ bool getStringValue(string & ConfVariable, string & ConfValue); + bool getDoubleValue(string ConfVariable, double & value); + bool getIntValue(string ConfVariable, long int & value); + protected: ConfigMap m_Map; @@ -84,6 +87,6 @@ namespace Sysreg_ } // end of namspace Sysreg_ - + #endif /* end of CONF_PARSER_H__ */ diff --git a/reactos/tools/sysreg/namedpipe_reader.cpp b/reactos/tools/sysreg/namedpipe_reader.cpp index 16c71b8e324..a9ad148778c 100644 --- a/reactos/tools/sysreg/namedpipe_reader.cpp +++ b/reactos/tools/sysreg/namedpipe_reader.cpp @@ -41,7 +41,7 @@ namespace System_ return false; } - h_Pipe = CreateFile(PipeCmd.c_str(), + h_Pipe = CreateFile("\\\\.\\pipe\\qemu", //PipeCmd.c_str(), GENERIC_WRITE | GENERIC_READ, 0, NULL, @@ -51,7 +51,7 @@ namespace System_ NULL); if(INVALID_HANDLE_VALUE == h_Pipe) { - cerr << "NamedPipeReader::openPipe> failed to open pipe " << PipeCmd << GetLastError() << endl; + cerr << "NamedPipeReader::openPipe> failed to open pipe " << PipeCmd << " Error:" << GetLastError() << endl; h_Pipe = NULLVAL; return false; } @@ -70,7 +70,7 @@ namespace System_ bool NamedPipeReader::closeSource() { - if (!h_Pipe) + if (h_Pipe == INVALID_HANDLE_VALUE) { cerr << "NamedPipeReader::closePipe> pipe is not open" << endl; return false; diff --git a/reactos/tools/sysreg/rosboot_test.cpp b/reactos/tools/sysreg/rosboot_test.cpp index 4883b86d046..e5f51bc4c4f 100644 --- a/reactos/tools/sysreg/rosboot_test.cpp +++ b/reactos/tools/sysreg/rosboot_test.cpp @@ -16,7 +16,7 @@ #include "file_reader.h" #include "os_support.h" -#include +#include #include #include #include @@ -25,6 +25,7 @@ #include #include #include +#include namespace Sysreg_ @@ -43,20 +44,23 @@ namespace Sysreg_ using std::ofstream; #endif - string RosBootTest::VARIABLE_NAME = _T("ROSBOOT_CMD"); - string RosBootTest::CLASS_NAME = _T("rosboot"); - string RosBootTest::DEBUG_PORT = _T("ROSBOOT_DEBUG_PORT"); - string RosBootTest::DEBUG_FILE = _T("ROSBOOT_DEBUG_FILE"); - string RosBootTest::TIME_OUT = _T("ROSBOOT_TIME_OUT"); - string RosBootTest::PID_FILE= _T("ROSBOOT_PID_FILE"); - string RosBootTest::DELAY_READ = _T("ROSBOOT_DELAY_READ"); - string RosBootTest::CHECK_POINT = _T("ROSBOOT_CHECK_POINT"); - string RosBootTest::SYSREG_CHECKPOINT = _T("SYSREG_CHECKPOINT:"); - string RosBootTest::CRITICAL_APP = _T("ROSBOOT_CRITICAL_APP"); - string RosBootTest::TERMINATE_EMULATOR = _T("ROSBOOT_TERMINATE_EMULATOR"); + string RosBootTest::ROS_EMU_TYPE= _T("ROS_EMU_TYPE"); + string RosBootTest::EMU_TYPE_QEMU = _T("qemu"); + string RosBootTest::EMU_TYPE_VMWARE = _T("vmware"); + string RosBootTest::ROS_EMU_PATH = _T("ROS_EMU_PATH"); + string RosBootTest::ROS_HDD_IMAGE= _T("ROS_HDD_IMAGE"); + string RosBootTest::ROS_CD_IMAGE = _T("ROS_CD_IMAGE"); + string RosBootTest::ROS_MAX_TIME = _T("ROS_MAX_TIME"); + string RosBootTest::ROS_LOG_FILE = _T("ROS_LOG_FILE"); + string RosBootTest::ROS_SYM_DIR = _T("ROS_SYM_DIR"); + string RosBootTest::ROS_DELAY_READ = _T("ROS_DELAY_READ"); + string RosBootTest::ROS_SYSREG_CHECKPOINT = _T("SYSREG_CHECKPOINT:"); + string RosBootTest::ROS_CRITICAL_IMAGE = _T("ROS_CRITICAL_IMAGE"); + string RosBootTest::ROS_EMU_KILL = _T("ROS_EMU_KILL"); + string RosBootTest::ROS_EMU_MEM = _T("ROS_EMU_MEM"); //--------------------------------------------------------------------------------------- - RosBootTest::RosBootTest() : m_Timeout(60.0), m_Delayread(0) + RosBootTest::RosBootTest() : m_MaxTime(0.0), m_DelayRead(0) { } @@ -81,197 +85,184 @@ namespace Sysreg_ //--------------------------------------------------------------------------------------- void RosBootTest::delayRead() { - if (m_Delayread) + if (m_DelayRead) { /// /// delay reading until emulator is ready /// - OsSupport::sleep(m_Delayread * CLOCKS_PER_SEC ); + OsSupport::sleep(m_DelayRead); } } - -//--------------------------------------------------------------------------------------- - bool RosBootTest::configurePipe() +//---------------------------------------------------------------------------------------- + bool RosBootTest::configureQemu() { - if (!_tcscmp(m_DebugPort.c_str(), _T("qemupipe"))) + string qemupath; + string::size_type pos; + + bool bootfromcd = false; + + if (m_CDImage != _T("") ) { - string::size_type pipe_pos = m_BootCmd.find(_T("-serial pipe:")); - if (pipe_pos != string::npos) + bootfromcd = true; + } + +#ifdef __LINUX__ + pos = m_EmuPath.find_last_of(_T("/")); +#else + pos = m_EmuPath.find_last_of(_T("\\")); +#endif + if (pos == string::npos) + { + cerr << "Error: ROS_EMU_PATH is invalid!!!" << endl; + return false; + } + qemupath = m_EmuPath.substr(0, pos); + + + if (m_HDDImage == _T("")) + { + if(!bootfromcd) { - pipe_pos += 12; - string::size_type pipe_pos_end = m_BootCmd.find (_T(" "), pipe_pos); - if (pipe_pos != string::npos && pipe_pos_end != string::npos) - { - m_Pipe = _T("\\\\.\\pipe\\") + m_BootCmd.substr (pipe_pos, pipe_pos_end - pipe_pos); -#ifdef __LINUX__ - m_DataSource = new PipeReader(); -#else - m_DataSource = new NamedPipeReader(); -#endif - return true; - } + cerr << "Error: ROS_CD_IMAGE and ROS_HDD_IMAGE is not set!!!" << endl; + return false; } - } - else if (!_tcscmp(m_DebugPort.c_str(), _T("vmwarepipe"))) - { - cerr << "VmWare debug pipe is currently fixed to \\\\.\\pipe\\vmwaredebug" << endl; - m_Pipe = _T("\\\\.\\pipe\\vmwaredebug"); -#ifdef __LINUX__ - m_DataSource = new PipeReader(); + string qemuimgdir = qemupath; +#ifdef __LINUX___ + qemuimgdir += _T("qemu-img"); #else - m_DataSource = new NamedPipeReader(); -#endif - - return true; + qemuimgdir += _T("qemu-img.exe"); +#endif + /// + /// FIXME + /// call qemu-img to create the tool + /// + cerr << "Creating HDD Image ..." << endl; } - // - // FIXME - // support other emulators + if (m_MaxMem == "") + { + // default to 64M + m_MaxMem = "64"; + } + if (bootfromcd) + { + m_BootCmd = m_EmuPath + _T(" -serial pipe:qemu -L ") + qemupath + _T(" -m ") + m_MaxMem + _T(" -hda ") + m_HDDImage + _T(" -boot d -cdrom ") + m_CDImage; + } + else + { + m_BootCmd = m_EmuPath + _T(" -L ") + qemupath + _T(" -m ") + m_MaxMem + _T(" -boot c -serial pipe:sysreg"); + } + + if (m_KillEmulator == _T("yes")) + { +#ifdef __LINUX__ + m_BootCmd += _T(" -pidfile pid.txt"); +#endif + } + else + { + m_BootCmd += _T(" -no-reboot "); + } + + cerr << "Opening Data Source:" << m_BootCmd << endl; + + +#ifdef __LINUX__ + m_DataSource = new PipeReader(); + m_Src = m_BootCmd; +#else + m_DataSource = new NamedPipeReader(); + m_Src = _T("\\\\.\\pipe\\qemu"); + + if (!executeBootCmd()) + { + cerr << "Error: failed to launch emulator with: " << m_BootCmd << endl; + return false; + } +#endif - return false; + return true; } + //--------------------------------------------------------------------------------------- - bool RosBootTest::configureFile() + bool RosBootTest::configureVmWare() { - if (!_tcscmp(m_DebugPort.c_str(), _T("qemufile"))) - { - string::size_type file_pos = m_BootCmd.find(_T("-serial file:")); - if (file_pos != string::npos) - { - file_pos += 12; - string::size_type file_pos_end = m_BootCmd.find (_T(" "), file_pos); - if (file_pos != string::npos && file_pos_end != string::npos) - { - m_File = m_BootCmd.substr (file_pos, file_pos_end - file_pos); - m_DataSource = new FileReader(); - return true; - } - cerr << "Error: missing space at end of option" << endl; - } - } - else if (!_tcscmp(m_DebugPort.c_str(), _T("vmwarefile"))) - { - cerr << "VmWare debug file is currently fixed to debug.log" << endl; - m_File = "debug.log"; - m_DataSource = new FileReader(); - return true; - } - - // - // FIXME - // support other emulators - + cerr << "VmWare is currently not yet supported" << endl; return false; } //--------------------------------------------------------------------------------------- bool RosBootTest::readConfigurationValues(ConfigParser &conf_parser) { - /// - /// read required configuration arguments - /// + if (!conf_parser.getStringValue(RosBootTest::ROS_EMU_TYPE, m_EmuType)) + { + cerr << "Error: ROS_EMU_TYPE is not set" << endl; + return false; + } + if (!conf_parser.getStringValue(RosBootTest::ROS_EMU_PATH, m_EmuPath)) + { + cerr << "Error: ROS_EMU_PATH is not set" << endl; + return false; + } - - if (!conf_parser.getStringValue (RosBootTest::DEBUG_PORT, m_DebugPort)) - { - cerr << "Error: ROSBOOT_DEBUG_TYPE is not set in configuration file" << endl; - return false; - } - if (!conf_parser.getStringValue(RosBootTest::VARIABLE_NAME, m_BootCmd)) - { - cerr << "Error: ROSBOOT_CMD is not set in configuration file" << endl; - return false; - } - - string timeout; - if (conf_parser.getStringValue(RosBootTest::TIME_OUT, timeout)) - { - TCHAR * stop; - m_Timeout = _tcstod(timeout.c_str (), &stop); - - if (isnan(m_Timeout) || m_Timeout == 0.0) - { - cerr << "Warning: overriding timeout with default of 60 sec" << endl; - m_Timeout = 60.0; - } - } - - string delayread; - if (conf_parser.getStringValue(RosBootTest::DELAY_READ, delayread)) - { - TCHAR * stop; - m_Delayread = _tcstoul(delayread.c_str (), &stop, 10); - if (m_Delayread > 60 || m_Delayread < 0) - { - cerr << "Warning: disabling delay read" << endl; - m_Delayread = 0; - } - } - - /// - /// read optional arguments - /// - - conf_parser.getStringValue (RosBootTest::CHECK_POINT, m_Checkpoint); - conf_parser.getStringValue (RosBootTest::CRITICAL_APP, m_CriticalApp); - conf_parser.getStringValue (RosBootTest::DEBUG_FILE, m_DebugFile); - conf_parser.getStringValue (RosBootTest::TERMINATE_EMULATOR, m_KillEmulator); + conf_parser.getStringValue (RosBootTest::ROS_HDD_IMAGE, m_HDDImage); + conf_parser.getStringValue (RosBootTest::ROS_CD_IMAGE, m_CDImage); + conf_parser.getDoubleValue (RosBootTest::ROS_MAX_TIME, m_MaxTime); + conf_parser.getStringValue (RosBootTest::ROS_LOG_FILE, m_DebugFile); + conf_parser.getStringValue (RosBootTest::ROS_SYM_DIR, m_SymDir); + conf_parser.getIntValue (RosBootTest::ROS_DELAY_READ, m_DelayRead); + conf_parser.getStringValue (RosBootTest::ROS_SYSREG_CHECKPOINT, m_Checkpoint); + conf_parser.getStringValue (RosBootTest::ROS_CRITICAL_IMAGE, m_CriticalImage); + conf_parser.getStringValue (RosBootTest::ROS_EMU_KILL, m_KillEmulator); + conf_parser.getStringValue (RosBootTest::ROS_EMU_MEM, m_MaxMem); return true; } //--------------------------------------------------------------------------------------- bool RosBootTest::execute(ConfigParser &conf_parser) { - if (!readConfigurationValues(conf_parser)) { return false; } - - string src; - if (m_DebugPort.find(_T("pipe")) != string::npos) + if (m_EmuType == EMU_TYPE_QEMU) { - if (!configurePipe()) + if (!configureQemu()) { - cerr << "Error: failed to configure pipe" << endl; + cerr << "Error: failed to configure qemu" << endl; return false; } - -#ifndef __LINUX__ - if (!executeBootCmd()) - { - cerr << "Error: failed to launch emulator" << endl; - return false; - } -#endif - src = m_Pipe; } - else if (m_DebugPort.find(_T("file")) != string::npos) + else if (m_EmuType == EMU_TYPE_VMWARE) { - if (!configureFile()) + if (!configureVmWare()) { - cerr << "Error: failed to configure pipe" << endl; + cerr << "Error: failed to configure vmware" << endl; return false; } - if (!executeBootCmd()) - { - cerr << "Error: failed to launch emulator" << endl; - return false; - } - - src = m_File; } - - if (!m_DataSource->openSource(src)) - { - cerr << "Error: failed to open data source with " << src << endl; + else + { + /// + /// unsupported emulator + + cerr << "Error: ROS_EMU_TYPE value is not supported:" << m_EmuType << "=" << EMU_TYPE_QEMU << endl; return false; } + OsSupport::sleep(500); + + if (!m_DataSource->openSource(m_Src)) + { + cerr << "Error: failed to open data source with " << m_Src << endl; + return false; + } + + OsSupport::sleep(3000); + bool ret = analyzeDebugData(); m_DataSource->closeSource(); @@ -314,10 +305,10 @@ namespace Sysreg_ cout << line << endl; - if (line.find (RosBootTest::SYSREG_CHECKPOINT) != string::npos) + if (line.find (RosBootTest::ROS_SYSREG_CHECKPOINT) != string::npos) { - line.erase (0, line.find (RosBootTest::SYSREG_CHECKPOINT) + - RosBootTest::SYSREG_CHECKPOINT.length ()); + line.erase (0, line.find (RosBootTest::ROS_SYSREG_CHECKPOINT) + + RosBootTest::ROS_SYSREG_CHECKPOINT.length ()); if (!_tcsncmp(line.c_str (), m_Checkpoint.c_str (), m_Checkpoint.length ())) { state = DebugStateCPReached; @@ -357,7 +348,7 @@ namespace Sysreg_ } else if (line.find (_T("Unhandled exception")) != string::npos) { - if (m_CriticalApp == _T("IGNORE")) + if (m_CriticalImage == _T("IGNORE")) { /// /// ignoring all user-mode exceptions @@ -403,7 +394,7 @@ namespace Sysreg_ } string appname = modulename.substr (pos + 1, modulename.length () - pos); - if (m_CriticalApp.find (appname) == string::npos && m_CriticalApp.length () > 1) + if (m_CriticalImage.find (appname) == string::npos && m_CriticalImage.length () > 1) { /// the application is not in the list of /// critical apps. Therefore we ignore the user-mode @@ -453,6 +444,11 @@ namespace Sysreg_ //--------------------------------------------------------------------------------------- bool RosBootTest::isTimeout(double max_timeout) { + if (max_timeout == 0) + { + // no timeout specified + return false; + } static time_t start = 0; if (!start) @@ -493,7 +489,7 @@ namespace Sysreg_ write_log = file.is_open (); while(1) { - if (isTimeout(m_Timeout)) + if (isTimeout(m_MaxTime)) { break; } diff --git a/reactos/tools/sysreg/rosboot_test.h b/reactos/tools/sysreg/rosboot_test.h index 1947e4a5614..46d2de4ec1c 100644 --- a/reactos/tools/sysreg/rosboot_test.h +++ b/reactos/tools/sysreg/rosboot_test.h @@ -11,6 +11,8 @@ */ #include "data_source.h" #include "conf_parser.h" +#include "os_support.h" +#include "user_types.h" #include #include @@ -19,6 +21,8 @@ namespace Sysreg_ { using std::vector; using System_::DataSource; + using System_::OsSupport; + //--------------------------------------------------------------------------------------- /// @@ -30,17 +34,22 @@ namespace Sysreg_ class RosBootTest { public: - static string VARIABLE_NAME; - static string CLASS_NAME; - static string DEBUG_PORT; - static string DEBUG_FILE; - static string TIME_OUT; - static string PID_FILE; - static string CHECK_POINT; - static string SYSREG_CHECKPOINT; - static string DELAY_READ; - static string CRITICAL_APP; - static string TERMINATE_EMULATOR; + + static string ROS_EMU_TYPE; + static string EMU_TYPE_QEMU; + static string EMU_TYPE_VMWARE; + static string ROS_EMU_PATH; + static string ROS_HDD_IMAGE; + static string ROS_CD_IMAGE; + static string ROS_MAX_TIME; + static string ROS_LOG_FILE; + static string ROS_SYM_DIR; + static string ROS_DELAY_READ; + static string ROS_SYSREG_CHECKPOINT; + static string ROS_CRITICAL_IMAGE; + static string ROS_EMU_KILL; + static string ROS_EMU_MEM; + //--------------------------------------------------------------------------------------- /// @@ -81,7 +90,8 @@ namespace Sysreg_ bool configureFile(); bool analyzeDebugData(); bool readConfigurationValues(ConfigParser & conf_parser); - + bool configureQemu(); + bool configureVmWare(); //--------------------------------------------------------------------------------------- /// @@ -122,22 +132,26 @@ typedef enum DebugState protected: - double m_Timeout; - string m_Checkpoint; - string m_CriticalApp; - string m_DebugFile; - string m_BootCmd; - string m_DebugPort; - string m_Pipe; - string m_File; - string m_KillEmulator; - DataSource * m_DataSource; - vector m_Checkpoints; - unsigned long m_Delayread; - long m_Pid; - long m_DelayRead; + string m_EmuType; + string m_EmuPath; + string m_HDDImage; + string m_CDImage; + double m_MaxTime; + string m_DebugFile; + string m_SymDir; + long int m_DelayRead; + string m_Checkpoint; + string m_CriticalImage; + string m_KillEmulator; + string m_MaxMem; + string m_BootCmd; + string m_Src; - }; // end of class RosBootTest + DataSource * m_DataSource; + OsSupport::ProcessID m_Pid; + std::vector m_Checkpoints; + + }; // end of class RosBootTest } // end of namespace Sysreg_ diff --git a/reactos/tools/sysreg/txtmode.cfg b/reactos/tools/sysreg/txtmode.cfg index f07b338cf90..559090364b3 100644 --- a/reactos/tools/sysreg/txtmode.cfg +++ b/reactos/tools/sysreg/txtmode.cfg @@ -14,13 +14,13 @@ ROS_EMU_TYPE=qemu ROS_EMU_PATH=E:\reactos\qemu\qemu.exe -; ROS_HD_IMAGE +; ROS_HDD_IMAGE ; ; The hdd image to use for running the emulator. If this variable is not ; set, SysReg will create a HDD with name "ros.img" using the qemu-img tool. It will search ; this tool in the directory of emulator and abort if the tool cannot be found -ROS_HD_IMAGE=E:\reactos\qemu\RosVMDK.img +ROS_HDD_IMAGE=E:\reactos\qemu\ReactOS.hd ; ROS_CD_IMAGE ; @@ -29,7 +29,7 @@ ROS_HD_IMAGE=E:\reactos\qemu\RosVMDK.img ; from harddisk. ; -ROS_CD_IMAGE=E:\reactos\qemu\Reactos-RegTest.iso +ROS_CD_IMAGE=E:\reactos\qemu\Reactos.iso ;------------------------------------------------------------------------------------------- ; Additional Options @@ -62,7 +62,7 @@ ROS_CD_IMAGE=E:\reactos\qemu\Reactos-RegTest.iso ; ; Note: set this value if you have problems with timeouts or cutoff debugging data ; -; ROS_DELAY_READ=4 +ROS_DELAY_READ=4000 ; ROS_CHECK_POINT ; @@ -77,3 +77,19 @@ ROS_CD_IMAGE=E:\reactos\qemu\Reactos-RegTest.iso ; that the test has failed and quit debugging immediately ; ;ROS_CRITICAL_IMAGE=setup.exe userinit.exe smss.exe winlogon.exe csrss.exe explorer.exe + +; ROS_EMU_KILL +; +; Set this variable to true if you want SysReg to kill the emulator process when it has decided to exit. +; +; Note: Qemu>=0.9.0 has the option to shutdown on reboot (-no--reboot) +; +; ROS_EMU_KILL=yes + +; ROS_EMU_MEM +; +; Controls how much memory the emulator use for ReactOS +; +; ROS_EMU_MEM=64 + +