ICP  1
isisicp.cpp
Go to the documentation of this file.
1 // isisicp.cpp : Implementation of WinMain
2 
3 
4 #include "stdafx.h"
5 #include "resource.h"
6 #include "isisicp_i.h"
7 #include "isisinstrumentcontrol.h"
8 #include "icputils.h"
9 #include "isisicp_extMC.h"
10 
11 class CisisicpModule;
12 
13 
15 {
17  std::string filename;
18  std::string logdir;
19  HANDLE h;
20  bool file_error;
21  report_arg_t() : module(0), filename(""), logdir(""), h(INVALID_HANDLE_VALUE), file_error(false) {}
22 };
23 
24 
25 class CisisicpModule : public ATL::CAtlServiceModuleT< CisisicpModule, IDS_SERVICENAME >
26  {
27 public :
28  DECLARE_LIBID(LIBID_isisicpLib)
29 // DECLARE_REGISTRY_APPID_RESOURCEID(IDR_ISISICP, "{792C8939-E7F1-46E0-8EF6-DAB7F8CDBC71}")
30  DECLARE_REGISTRY_APPID_RESOURCEID(IDR_ISISICP, "{940B6DC7-2248-474D-B150-B3CC089F166A}") // this is the original number
31  HRESULT InitializeSecurity() throw()
32  {
33  // TODO : Call CoInitializeSecurity and provide the appropriate security settings for
34  // your service
35  // Suggested - PKT Level Authentication,
36  // Impersonation Level of RPC_C_IMP_LEVEL_IDENTIFY
37  // and an appropiate Non NULL Security Descriptor.
38 
39  return S_OK;
40  }
41  HRESULT Start(int nShowCmd) throw();
42  HRESULT OnStop();
43  static int reportFunction(const DAEstatus_message& mess, void* arg);
44  static int writeEventLog(int sev, const char* message, void* arg);
45 };
46 
47 
48 class ISISICPApp : public Poco::Util::Application
49 {
50  int m_nShowCmd;
51 public:
52  ISISICPApp(int nShowCmd) : Poco::Util::Application(), m_nShowCmd(nShowCmd) { }
53  virtual int main(const std::vector<std::string>& args);
54  void runApp()
55  {
56  run();
57  }
58 protected:
59  void initialize(Poco::Util::Application& self)
60  {
61  registerExtraLoggerChannels();
62  if (loadAppConfig("isisicp") != 0) // does equivalent job of default loadConfiguration()
63  {
64 // LogEventEx(ICP_MSG_ERROR, "Cannot load isisicp.default.properties", EVENTLOG_ERROR_TYPE);
65  throw std::exception("Cannot load isisicp.default.properties");
66  }
67  Application::initialize(self);
68  }
69 };
70 
71 CisisicpModule _AtlModule;
72 static ISISICPApp* the_app = NULL;
73 
74 extern "C" int WINAPI _tWinMain(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/,
75  LPTSTR lpCmdLine, int nShowCmd)
76 {
77  int ret = 0;
78  std::vector<std::string> args;
79  args.push_back("isisicp.exe");
80  the_app = new ISISICPApp(nShowCmd);
81  the_app->init(args);
82 // Poco::Thread main_thread;
83 // Poco::RunnableAdapter<ISISICPApp> ra(*the_app, &ISISICPApp::runApp);
84 // main_thread.start(ra);
85 // main_thread.join();
86  ret = the_app->run();
87  delete the_app;
88  the_app = 0;
89  return ret;
90 }
91 
92 
93 int ISISICPApp::main(const std::vector<std::string>& args)
94 {
95  return _AtlModule.WinMain(m_nShowCmd);
96 // return EXIT_OK;
97 }
98 
99 HRESULT CisisicpModule::Start(int nShowCmd) throw()
100 {
101  struct tm* tm_struct;
102  static char buffer[120];
103  static report_arg_t params;
104  time_t the_time;
105  time(&the_time);
106  tm_struct = localtime(&the_time);
107  int i;
108  unsigned flags = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
109  flags &= ~_CRTDBG_LEAK_CHECK_DF; // do not check leak on exit
110  if (getenv("ISISICP_DEBUG_MEMORY") != NULL)
111  {
112  i = atoi(getenv("ISISICP_DEBUG_MEMORY"));
113  flags |= _CRTDBG_LEAK_CHECK_DF; // check leaks on program exit
114  if (i > 0)
115  {
116  flags |= _CRTDBG_DELAY_FREE_MEM_DF; // keep freed memory to check
117  if (i == 1)
118  {
119  flags |= _CRTDBG_CHECK_ALWAYS_DF; // check every allocation
120  }
121  else
122  {
123  flags &= ~_CRTDBG_CHECK_ALWAYS_DF;
124  flags &= 0x0000FFFF; // clear old frequency
125  flags |= (i << 16);
126  }
127  }
128  sprintf(buffer, "c:\\data\\log\\ICPmemory%lu.log", the_time);
129  HANDLE hdebug = CreateFile(buffer, GENERIC_WRITE, FILE_SHARE_READ,
130  defaultNoInheritHandles(), CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_WRITE_THROUGH, 0);
131  _CrtSetReportMode( _CRT_WARN, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG /* | _CRTDBG_MODE_WNDW */ );
132  _CrtSetReportFile( _CRT_WARN, hdebug );
133  _CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG /* | _CRTDBG_MODE_WNDW */ );
134  _CrtSetReportFile( _CRT_ERROR, hdebug );
135  _CrtSetReportMode( _CRT_ASSERT, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG /* | _CRTDBG_MODE_WNDW */ );
136  _CrtSetReportFile( _CRT_ASSERT, hdebug );
137  }
138  _CrtSetDbgFlag(flags);
139 // _CrtSetAllocHook(MyAllocHook);
140 // mkdir("c:\\data\\devel");
141 
142  TCHAR szPath[ MAX_PATH ];
143  GetModuleFileName( NULL, szPath, MAX_PATH ); // get the full path of isisicp.exe executable
144  std::string icp_service_dir = szPath;
145  icp_service_dir.erase(icp_service_dir.find_last_of("/\\")); // strip off filename to get directory
146 
147  // event logging
148  AddEventSource(m_szServiceName, (icp_service_dir+"\\isisicp_extMC.dll").c_str(), 0);
149 
150  params.module = this;
151  params.logdir = the_app->config().getString("isisicp.logdir", "c:\\data\\log");
152  setICPChannelReporter(reportFunction, &params);
153 
154  the_app->logger().information("********************* Starting *********************");
155 
156  // make sure only one ICP running
157  Poco::NamedMutex proc_lock("ISISICP_PROCESS_LOCK");
158  if ( !proc_lock.tryLock() )
159  {
160  std::string mess = Poco::format("Cannot launch ISISICP from %s (global mutex already held)", icp_service_dir);
161  the_app->logger().fatal(mess);
162  std::cerr << mess << std::endl;
163  LogEventEx(ICP_MSG_ERROR, mess.c_str(), EVENTLOG_ERROR_TYPE);
164  return E_FAIL;
165  }
166 
167  // we need a console for some of the commands we spawn from the ICP e.g. end_of_run.cmd -> xcopy
168  AllocConsole();
169  SetConsoleTitle("ISISICP Debug Output");
170  HWND con_win = GetConsoleWindow();
171  if (con_win != NULL)
172  {
173  if (the_app->config().getBool("isisicp.hideconsole"))
174  {
175  ShowWindow(con_win, SW_HIDE);
176  }
177  else
178  {
179  ShowWindow(con_win, SW_MINIMIZE);
180  }
181  }
182  // set process affinity mask to stop us grabbing all cpus on the system
183  DWORD_PTR proc_affinity_mask, system_affinity_mask;
184  if (GetProcessAffinityMask(GetCurrentProcess(), &proc_affinity_mask, &system_affinity_mask) != 0)
185  {
186  proc_affinity_mask = the_app->config().getInt("isisicp.processAffinityMask", proc_affinity_mask);
187  proc_affinity_mask &= system_affinity_mask; // it is an error to ask for more processors than are present on the system
188  if ( (proc_affinity_mask != 0) && (SetProcessAffinityMask(GetCurrentProcess(), proc_affinity_mask) != 0) )
189  {
190  the_app->logger().information("Set process CPU affinity mask to 0x" + Poco::NumberFormatter::formatHex(proc_affinity_mask));
191  }
192  else
193  {
194  the_app->logger().error("cannot set process affinity");
195  }
196  }
197  else
198  {
199  the_app->logger().error("cannot get process affinity");
200  }
201  //
202  InstrumentControlHolder::setDefaultArgs(the_app, icp_service_dir, reportFunction, writeEventLog, &params);
203  CoInitializeEx(NULL, COINIT_MULTITHREADED);
204  the_app->logger().information("Starting ISISICP");
205  LogEventEx(ICP_MSG_INFORMATIONAL, "Starting ISISICP", EVENTLOG_INFORMATION_TYPE);
206  return CAtlServiceModuleT<CisisicpModule,IDS_SERVICENAME>::Start(nShowCmd);
207 }
208 
209 HRESULT CisisicpModule::OnStop()
210 {
211  the_app->logger().information("Stopping ISISICP");
212  LogEventEx(ICP_MSG_INFORMATIONAL, "Stopping ISISICP", EVENTLOG_INFORMATION_TYPE);
213  return S_OK;
214 }
215 
216 int CisisicpModule::reportFunction(const DAEstatus_message& mess, void* arg)
217 {
218  static bool first_call = false;
219  static char icp_log_file_template[240], icp_log_file[240];
220  time_t the_time;
221  time(&the_time);
222  struct tm* tm_struct = localtime(&the_time);
223  report_arg_t* params = (report_arg_t*)arg;
224 // strftime(icp_log_file_template, sizeof(icp_log_file_template), "c:\\data\\log\\icp-%Y-%m-%d-%a-%%02d.log", tm_struct);
225 // for(int i=0; i <= 99; i++)
226 // {
227 // _snprintf(icp_log_file, sizeof(icp_log_file), icp_log_file_template, i);
228 // if (stat(icp_log_file, &stat_buffer) != 0)
229 // {
230 // break; // file not found, so we can use the name
231 // }
232 // }
233  sprintf(icp_log_file_template, "%s\\icp-%%Y-%%m-%%d-%%a.log", params->logdir.c_str());
234  strftime(icp_log_file, sizeof(icp_log_file), icp_log_file_template, tm_struct);
235  if (params->filename != icp_log_file)
236  {
237  if (params->h != INVALID_HANDLE_VALUE)
238  {
239  CloseHandle(params->h);
240  }
241  params->filename = icp_log_file;
242  params->h = createAppendFile(icp_log_file);
243  if (params->h != INVALID_HANDLE_VALUE)
244  {
245  params->file_error = false;
246  }
247  else
248  {
249  params->module->LogEventEx(ICP_MSG_ERROR, "Cannot create ICP LOG file", EVENTLOG_ERROR_TYPE);
250  params->file_error = true;
251  }
252  }
253  std::stringstream f;
254  f << mess << "\r\n";
255  appendToFileAsync(params->h, f.str().c_str());
256 #ifdef _DEBUG
257  OutputDebugString(mess.str().c_str());
258  OutputDebugString("\n");
259 #endif /* _DEBUG */
260 // if (mess >= SEV_ERROR)
261 // {
262 // params->module->LogEventEx(ICP_MSG_ERROR, mess.str().c_str(), EVENTLOG_ERROR_TYPE);
263 // }
264  return S_OK;
265 }
266 
267 int CisisicpModule::writeEventLog(int sev, const char* message, void* arg)
268 {
269  report_arg_t* params = (report_arg_t*)arg;
270  switch(sev)
271  {
272  case SEV_INFO:
273  case SEV_DEBUG:
274  params->module->LogEventEx(ICP_MSG_INFORMATIONAL, message, EVENTLOG_INFORMATION_TYPE);
275  break;
276 
277  case SEV_ERROR:
278  case SEV_FATAL:
279  params->module->LogEventEx(ICP_MSG_ERROR, message, EVENTLOG_ERROR_TYPE);
280  break;
281 
282  case SEV_OK:
283  params->module->LogEventEx(ICP_MSG_SUCCESS, message, EVENTLOG_SUCCESS);
284  break;
285 
286  case SEV_WARNING:
287  params->module->LogEventEx(ICP_MSG_WARNING, message, EVENTLOG_WARNING_TYPE);
288  break;
289 
290  default:
291  params->module->LogEventEx(ICP_MSG_INFORMATIONAL, message, EVENTLOG_INFORMATION_TYPE);
292  break;
293  }
294  return 0;
295 }
296 
297 
std::string logdir
Definition: isisicp.cpp:18
DECLARE_REGISTRY_APPID_RESOURCEID(IDR_ISISICP,"{940B6DC7-2248-474D-B150-B3CC089F166A}") HRESULT InitializeSecurity()
Definition: isisicp.cpp:30
#define IDR_ISISICP
Definition: Resource.h:6
HANDLE h
Definition: isisicp.cpp:19
std::string filename
Definition: isisicp.cpp:17
CisisicpModule * module
Definition: isisicp.cpp:16
bool file_error
Definition: isisicp.cpp:20