// Parse options runs through the heirarchy doing all the parsing void ParseOptions(int argc, char* argv[]) { ParseCommandLine(argc, argv); CheckForHelp(); CheckForVersion(); ParseEnvironment(); ParseConfigFiles(); ParseDefaultConfigFile(); }
STDMETHODIMP PartCoverConnector2::StartTarget( BSTR p_targetPath, BSTR p_targetWorkingDir, BSTR p_targetArguments, VARIANT_BOOL redirectOutput, IConnectorActionCallback* callback) { HRESULT hr; _bstr_t targetPath(p_targetPath); _bstr_t targetWorkingDir(p_targetWorkingDir); _bstr_t targetArguments(p_targetArguments); if (targetWorkingDir.length() == 0 || targetPath.length() == 0 ) return E_INVALIDARG; if(callback != 0 ) callback->OpenMessagePipe(); // init message center if(FAILED(hr = m_center.Open())) return hr; if(callback != 0 ) callback->TargetSetEnvironmentVars(); targetArguments = _bstr_t("\"") + targetPath + _bstr_t("\" ") + targetArguments; // get current working dir and settings StringMap env = ParseEnvironment(); env[_T("Cor_Enable_Profiling")] = _T("1"); env[_T("Cor_Profiler")] = _T("{") _T(DRIVER_CORPROFILER_GUID) _T("}"); env[OPTION_MESSOPT] = m_center.getId(); if (m_driverLogging > 0) { DynamicArray<TCHAR> curBuffer(5); _stprintf_s(curBuffer, curBuffer.size(), _T("%d"), m_driverLogging); env[OPTION_VERBOSE] = curBuffer; } if (m_useFileLogging) { DWORD curLength = ::GetCurrentDirectory(0, NULL); DynamicArray<TCHAR> curBuffer(curLength + 25); if (curLength = ::GetCurrentDirectory(curLength + 1, curBuffer)) { _stprintf_s(curBuffer + curLength, 25, DRIVER_LOG_FILENAME); env[OPTION_LOGFILE] = curBuffer; m_logFile = curBuffer; } } if (m_usePipeLogging) { env[OPTION_LOGPIPE] = _T("1"); } // copy old and new env settings LPTSTR new_env = CreateEnvironment(env); if(callback != 0 ) callback->TargetCreateProcess(); // extract STARTUPINFO si; ZeroMemory(&si, sizeof(si)); si.cb = sizeof(si); if (redirectOutput == VARIANT_TRUE) { si.dwFlags = STARTF_USESTDHANDLES; si.hStdError = ::GetStdHandle(STD_ERROR_HANDLE); si.hStdOutput = ::GetStdHandle(STD_OUTPUT_HANDLE); si.hStdInput = ::GetStdHandle(STD_INPUT_HANDLE); } ZeroMemory(&pi, sizeof(pi)); DynamicArray<TCHAR> args(targetArguments.length() + 1); _tcscpy_s(args, targetArguments.length() + 1, targetArguments); BOOL created = ::CreateProcess( NULL, // Application args, // command line NULL, // lpProcessAttributes, NULL, // lpThreadAttributes, redirectOutput == VARIANT_TRUE ? TRUE : FALSE, // bInheritHandles, #ifdef _UNICODE CREATE_UNICODE_ENVIRONMENT | #endif (redirectOutput == VARIANT_TRUE ? 0 : CREATE_NEW_CONSOLE), new_env, targetWorkingDir, &si, &pi ); // clear environment FreeEnvironment(new_env); if (!created) return HRESULT_FROM_WIN32( ::GetLastError() ); if(callback != 0 ) callback->TargetWaitDriver(); if (FAILED(hr = m_center.WaitForClient())) return hr; if(callback != 0 ) callback->DriverConnected(); struct Starter : ITransferrableVisitor { IConnectorActionCallback* m_callback; public: bool readyToGo; Starter(IConnectorActionCallback* callback) : m_callback(callback), readyToGo(false) {} void on(MessageType type) { if (Messages::C_RequestStart == type) readyToGo = true; } void on(FunctionMap& value) {} void on(Rules& value) {} void on(InstrumentResults& value) {} void on(LogMessage& value) { if (m_callback != 0) m_callback->LogMessage(value.getThreadId(), value.getTicks(), _bstr_t(value.getMessage().c_str())); } } messageVisitor(callback); ITransferrable* message; while(SUCCEEDED(m_center.Wait(message))) { message->visit(messageVisitor); destroy(message); if (messageVisitor.readyToGo) break; } if (!messageVisitor.readyToGo) { ATLTRACE("PartCoverConnector2::StartTarget - C_RequestStart wait error"); return E_ABORT; } if(callback != 0 ) callback->DriverSendRules(); m_center.Send(m_rules); m_center.Send(Messages::Message<Messages::C_EndOfInputs>()); if(callback != 0 ) callback->DriverWaitEoIConfirm(); messageVisitor.readyToGo = false; while(SUCCEEDED(m_center.Wait(message))) { message->visit(messageVisitor); destroy(message); if (messageVisitor.readyToGo) break; } return true; }