source: nscp/modules/CheckSystem/CheckSystem.cpp @ c391984

0.4.00.4.10.4.2
Last change on this file since c391984 was c391984, checked in by Michael Medin <michael@…>, 2 years ago

0.4.x:

  • tweaks to the build environment to make the installer work
  • fixed Unicode issue
  • fixed performance data
  • improved so alias doesn't re-process the data so much
  • Property mode set to 100644
File size: 57.4 KB
Line 
1/**************************************************************************
2*   Copyright (C) 2004-2007 by Michael Medin <michael@medin.name>         *
3*                                                                         *
4*   This code is part of NSClient++ - http://trac.nakednuns.org/nscp      *
5*                                                                         *
6*   This program is free software; you can redistribute it and/or modify  *
7*   it under the terms of the GNU General Public License as published by  *
8*   the Free Software Foundation; either version 2 of the License, or     *
9*   (at your option) any later version.                                   *
10*                                                                         *
11*   This program is distributed in the hope that it will be useful,       *
12*   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
13*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
14*   GNU General Public License for more details.                          *
15*                                                                         *
16*   You should have received a copy of the GNU General Public License     *
17*   along with this program; if not, write to the                         *
18*   Free Software Foundation, Inc.,                                       *
19*   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
20***************************************************************************/
21
22#include "stdafx.h"
23#include "CheckSystem.h"
24#include <utils.h>
25#include <tlhelp32.h>
26#include <EnumNtSrv.h>
27#include <EnumProcess.h>
28#include <checkHelpers.hpp>
29#include <map>
30#include <set>
31#include <sysinfo.h>
32#include <filter_framework.hpp>
33#include <simple_registry.hpp>
34#include <boost/regex.hpp>
35
36CheckSystem gCheckSystem;
37
38/**
39 * Default c-tor
40 * @return
41 */
42CheckSystem::CheckSystem() : pdhThread(_T("pdhThread")) {}
43/**
44 * Default d-tor
45 * @return
46 */
47CheckSystem::~CheckSystem() {}
48
49namespace sh = nscapi::settings_helper;
50
51/**
52 * Load (initiate) module.
53 * Start the background collector thread and let it run until unloadModule() is called.
54 * @return true
55 */
56bool CheckSystem::loadModule() {
57        return loadModuleEx(_T(""), NSCAPI::normalStart);
58}
59
60/**
61 * New version of the load call.
62 * Start the background collector thread and let it run until unloadModule() is called.
63 * @return true
64 */
65
66bool CheckSystem::loadModuleEx(std::wstring alias, NSCAPI::moduleLoadMode mode) {
67        PDHCollector::system_counter_data *data = new PDHCollector::system_counter_data;
68        data->check_intervall = 100;
69        try {
70                typedef std::map<std::wstring,std::wstring> counter_map_type;
71                std::map<std::wstring,std::wstring> service_mappings;
72                std::map<std::wstring,std::wstring> counters;
73                bool default_counters = true;
74
75                sh::settings_registry settings(get_settings_proxy());
76                settings.set_alias(_T("check"), alias, _T("system/windows"));
77
78                settings.alias().add_path_to_settings()
79                        (_T("WINDOWS CHECK SYSTEM"), _T("Section for system checks and system settings"))
80
81                        (_T("service mapping"), sh::wstring_map_path(&service_mappings)
82                        , _T("SERVICE MAPPING SECTION"), _T(""))
83
84                        (_T("pdh"), _T("PDH COUNTER INFORMATION"), _T(""))
85
86                        (_T("pdh/counters"), sh::wstring_map_path(&counters)
87                        , _T("PDH COUNTERS"), _T(""))
88
89                        ;
90
91
92                settings.alias().add_key_to_settings()
93                        (_T("default"), sh::bool_key(&default_counters, true),
94                        _T("DEFAULT COUNTERS"), _T("Load the default counters: ") PDH_SYSTEM_KEY_CPU _T(", ") PDH_SYSTEM_KEY_MCB _T(", ") PDH_SYSTEM_KEY_MCL _T(" and ") PDH_SYSTEM_KEY_UPT _T(" If not you need to specify these manually. ") )
95
96                        (_T("default"), sh::bool_key(&default_counters, true),
97                        _T("DEFAULT COUNTERS"), _T("Load the default counters: ") PDH_SYSTEM_KEY_CPU _T(", ") PDH_SYSTEM_KEY_MCB _T(", ") PDH_SYSTEM_KEY_MCL _T(" and ") PDH_SYSTEM_KEY_UPT _T(" If not you need to specify these manually. ") )
98
99                        (_T("default buffer length"), sh::wstring_key(&data->buffer_length, _T("1h")),
100                        _T("DEFAULT INTERVALL"), _T("Used to define the default intervall for range buffer checks (ie. CPU)."))
101//
102//                      (_T("hostname cache"), sh::bool_key(&cacheNscaHost_),
103//                      _T("CACHE HOSTNAME"), _T(""))
104//
105//                      (_T("delay"), sh::string_fun_key<std::wstring>(boost::bind(&NSCAAgent::set_delay, this, _1), 0),
106//                      _T("DELAY"), _T(""))
107//
108//                      (_T("payload length"), sh::uint_key(&payload_length_, 512),
109//                      _T("PAYLOAD LENGTH"), _T("The password to use. Again has to be the same as the server or it wont work at all."))
110
111                        ;
112
113
114                settings.register_all();
115                settings.notify();
116
117                lookups_[SERVICE_BOOT_START] = service_mappings[_T("BOOT_START")];
118                lookups_[SERVICE_SYSTEM_START] = service_mappings[_T("SYSTEM_START")];
119                lookups_[SERVICE_AUTO_START] = service_mappings[_T("AUTO_START")];
120                lookups_[SERVICE_DEMAND_START] = service_mappings[_T("DEMAND_START")];
121                lookups_[SERVICE_DISABLED] = service_mappings[_T("DISABLED")];
122
123                typedef PDHCollector::system_counter_data::counter cnt;
124                if (default_counters) {
125                        data->counters.push_back(cnt(PDH_SYSTEM_KEY_CPU, _T("\\238(_total)\\6"), cnt::type_int64, cnt::format_large, cnt::rrd));
126                        data->counters.push_back(cnt(PDH_SYSTEM_KEY_MCB, _T("\\4\\26"), cnt::type_int64, cnt::format_large, cnt::value));
127                        data->counters.push_back(cnt(PDH_SYSTEM_KEY_MCL, _T("\\4\\30"), cnt::type_int64, cnt::format_large, cnt::value));
128                        data->counters.push_back(cnt(PDH_SYSTEM_KEY_UPT, _T("\\2\\674"), cnt::type_int64, cnt::format_large, cnt::value));
129                }
130                BOOST_FOREACH(counter_map_type::value_type c, counters) {
131                        data->counters.push_back(cnt(c.first, c.second, cnt::type_int64, cnt::format_large, cnt::value));
132                }
133
134                get_core()->registerCommand(_T("checkCPU"), _T("Check the CPU load of the computer."));
135                get_core()->registerCommand(_T("checkUpTime"), _T("Check the up-time of the computer."));
136                get_core()->registerCommand(_T("checkServiceState"), _T("Check the state of one or more of the computer services."));
137                get_core()->registerCommand(_T("checkProcState"), _T("Check the state of one or more of the processes running on the computer."));
138                get_core()->registerCommand(_T("checkMem"), _T("Check free/used memory on the system."));
139                get_core()->registerCommand(_T("checkCounter"), _T("Check a PDH counter."));
140                get_core()->registerCommand(_T("listCounterInstances"), _T("List all instances for a counter."));
141                get_core()->registerCommand(_T("checkSingleRegEntry"), _T("Check registry key"));
142        } catch (nscapi::nscapi_exception &e) {
143                NSC_LOG_ERROR_STD(_T("Failed to register command: ") + e.msg_);
144        } catch (...) {
145                NSC_LOG_ERROR_STD(_T("Failed to register command."));
146        }
147
148        if (mode == NSCAPI::normalStart) {
149                pdhThread.createThread(data);
150        }
151
152        return true;
153}
154/**
155 * Unload (terminate) module.
156 * Attempt to stop the background processing thread.
157 * @return true if successfully, false if not (if not things might be bad)
158 */
159bool CheckSystem::unloadModule() {
160        if (!pdhThread.exitThread(20000)) {
161                std::wcout << _T("MAJOR ERROR: Could not unload thread...") << std::endl;
162                NSC_LOG_ERROR(_T("Could not exit the thread, memory leak and potential corruption may be the result..."));
163        }
164        return true;
165}
166/**
167 * Check if we have a command handler.
168 * @return true (as we have a command handler)
169 */
170bool CheckSystem::hasCommandHandler() {
171        return true;
172}
173/**
174 * Check if we have a message handler.
175 * @return false as we have no message handler
176 */
177bool CheckSystem::hasMessageHandler() {
178        return false;
179}
180
181int CheckSystem::commandLineExec(const TCHAR* command,const unsigned int argLen,TCHAR** args) {
182        if (command == NULL) {
183                std::wcerr << _T("Usage: ... CheckSystem <command>") << std::endl;
184                std::wcerr << _T("Commands: debugpdh, listpdh, pdhlookup, pdhmatch, pdhobject") << std::endl;
185                return -1;
186        }
187        if (_wcsicmp(command, _T("debugpdh")) == 0) {
188                PDH::Enumerations::Objects lst;
189                try {
190                        lst = PDH::Enumerations::EnumObjects();
191                } catch (const PDH::PDHException e) {
192                        std::wcout << _T("Service enumeration failed: ") << e.getError();
193                        return 0;
194                }
195                for (PDH::Enumerations::Objects::iterator it = lst.begin();it!=lst.end();++it) {
196                        if ((*it).instances.size() > 0) {
197                                for (PDH::Enumerations::Instances::const_iterator it2 = (*it).instances.begin();it2!=(*it).instances.end();++it2) {
198                                        for (PDH::Enumerations::Counters::const_iterator it3 = (*it).counters.begin();it3!=(*it).counters.end();++it3) {
199                                                std::wstring counter = _T("\\") + (*it).name + _T("(") + (*it2).name + _T(")\\") + (*it3).name;
200                                                std::wcout << _T("testing: ") << counter << _T(": ");
201                                                std::list<std::wstring> errors;
202                                                std::list<std::wstring> status;
203                                                std::wstring error;
204                                                bool bStatus = true;
205                                                if (PDH::PDHResolver::validate(counter, error, false)) {
206                                                        status.push_back(_T("open"));
207                                                } else {
208                                                        errors.push_back(_T("NOT found: ") + error);
209                                                        bStatus = false;
210                                                }
211                                                if (bStatus) {
212                                                       
213                                                        //typedef boost::shared_ptr<PDHCollectors::StaticPDHCounterListener<double, PDH_FMT_DOUBLE> > cnt_type;
214                                                        typedef boost::shared_ptr<PDH::PDHCounter> counter_ptr;
215                                                        //typedef boost::shared_ptr<PDH::PDHCounterListener> cnt_type;
216                                                        counter_ptr pCounter;
217                                                        //PDH::PDHCounter *pCounter = NULL;
218                                                        PDH::PDHQuery pdh;
219                                                        try {
220                                                                //pCounter.reset(new PDHCollectors::StaticPDHCounterListener<double, PDH_FMT_DOUBLE>);
221                                                                //PDHCollectors::StaticPDHCounterListener<double, PDH_FMT_DOUBLE> cDouble;
222                                                                pdh.addCounter(counter);
223                                                                pdh.open();
224
225                                                                if (pCounter != NULL) {
226                                                                        try {
227                                                                                PDH::PDHCounterInfo info = pCounter->getCounterInfo();
228                                                                                errors.push_back(_T("CounterName: ") + info.szCounterName);
229                                                                                errors.push_back(_T("ExplainText: ") + info.szExplainText);
230                                                                                errors.push_back(_T("FullPath: ") + info.szFullPath);
231                                                                                errors.push_back(_T("InstanceName: ") + info.szInstanceName);
232                                                                                errors.push_back(_T("MachineName: ") + info.szMachineName);
233                                                                                errors.push_back(_T("ObjectName: ") + info.szObjectName);
234                                                                                errors.push_back(_T("ParentInstance: ") + info.szParentInstance);
235                                                                                errors.push_back(_T("Type: ") + strEx::itos(info.dwType));
236                                                                                errors.push_back(_T("Scale: ") + strEx::itos(info.lScale));
237                                                                                errors.push_back(_T("Default Scale: ") + strEx::itos(info.lDefaultScale));
238                                                                                errors.push_back(_T("Status: ") + strEx::itos(info.CStatus));
239                                                                                status.push_back(_T("described"));
240                                                                        } catch (const PDH::PDHException e) {
241                                                                                errors.push_back(_T("Describe failed: ") + e.getError());
242                                                                                bStatus = false;
243                                                                        }
244                                                                }
245
246                                                                pdh.gatherData();
247                                                                pdh.close();
248                                                                status.push_back(_T("queried"));
249                                                        } catch (const PDH::PDHException e) {
250                                                                errors.push_back(_T("Query failed: ") + e.getError());
251                                                                bStatus = false;
252                                                                try {
253                                                                        pdh.gatherData();
254                                                                        pdh.close();
255                                                                        bStatus = true;
256                                                                } catch (const PDH::PDHException e) {
257                                                                        errors.push_back(_T("Query failed (again!): ") + e.getError());
258                                                                }
259                                                        }
260
261                                                }
262                                                if (!bStatus) {
263                                                        std::list<std::wstring>::const_iterator cit = status.begin();
264                                                        for (;cit != status.end(); ++cit) {
265                                                                std::wcout << *cit << _T(", ");
266                                                        }
267                                                        std::wcout << std::endl;
268                                                        std::wcout << _T("  | Log") << std::endl;
269                                                        std::wcout << _T("--+------  --    -") << std::endl;
270                                                        cit = errors.begin();
271                                                        for (;cit != errors.end(); ++cit) {
272                                                                std::wcout << _T("  | ") << *cit << std::endl;
273                                                        }
274                                                } else {
275                                                        std::list<std::wstring>::const_iterator cit = status.begin();
276                                                        for (;cit != status.end(); ++cit) {
277                                                                std::wcout << *cit << _T(", ");;
278                                                        }
279                                                        std::wcout << std::endl;
280                                                }
281                                        }
282                                }
283                        } else {
284                                if ((*it).counters.size() == 0) {
285                                        std::wcout << _T("empty counter: ") << (*it).name << std::endl;
286                                }
287                                for (PDH::Enumerations::Counters::const_iterator it2 = (*it).counters.begin();it2!=(*it).counters.end();++it2) {
288                                        std::wstring counter = _T("\\") + (*it).name + _T("\\") + (*it2).name;
289                                        std::wcout << _T("testing: ") << counter << _T(": ");
290                                        std::wstring error;
291                                        if (PDH::PDHResolver::validate(counter, error, false)) {
292                                                std::wcout << _T(" found ");
293                                        } else {
294                                                std::wcout << _T(" *NOT* found (") << error << _T(") ") << std::endl;
295                                                break;
296                                        }
297                                        bool bOpend = false;
298                                        try {
299                                                PDH::PDHQuery pdh;
300                                                //PDHCollectors::StaticPDHCounterListener<double, PDH_FMT_DOUBLE> cDouble;
301                                                pdh.addCounter(counter);
302                                                pdh.open();
303                                                pdh.gatherData();
304                                                pdh.close();
305                                                bOpend = true;
306                                        } catch (const PDH::PDHException e) {
307                                                std::wcout << _T(" could *not* be open (") << e.getError() << _T(") ") << std::endl;
308                                                break;
309                                        }
310                                        std::wcout << _T(" open ");
311                                        std::wcout << std::endl;
312                                }
313                        }
314                }
315        } else if (_wcsicmp(command, _T("listpdh")) == 0) {
316                PDH::Enumerations::Objects lst;
317                try {
318                        lst = PDH::Enumerations::EnumObjects();
319                } catch (const PDH::PDHException e) {
320                        std::wcout << _T("Service enumeration failed: ") << e.getError();
321                        return 0;
322                }
323                for (PDH::Enumerations::Objects::iterator it = lst.begin();it!=lst.end();++it) {
324                        if ((*it).instances.size() > 0) {
325                                for (PDH::Enumerations::Instances::const_iterator it2 = (*it).instances.begin();it2!=(*it).instances.end();++it2) {
326                                        for (PDH::Enumerations::Counters::const_iterator it3 = (*it).counters.begin();it3!=(*it).counters.end();++it3) {
327                                                std::wcout << _T("\\") << (*it).name << _T("(") << (*it2).name << _T(")\\") << (*it3).name << std::endl;;
328                                        }
329                                }
330                        } else {
331                                for (PDH::Enumerations::Counters::const_iterator it2 = (*it).counters.begin();it2!=(*it).counters.end();++it2) {
332                                        std::wcout << _T("\\") << (*it).name << _T("\\") << (*it2).name << std::endl;;
333                                }
334                        }
335                }
336        } else if (_wcsicmp(command, _T("pdhlookup")) == 0) {
337                try {
338                        std::wstring name = arrayBuffer::arrayBuffer2string(args, argLen, _T(" "));
339                        if (name.empty()) {
340                                NSC_LOG_ERROR_STD(_T("Need to specify counter index name!"));
341                                return 0;
342                        }
343                        DWORD dw = PDH::PDHResolver::lookupIndex(name);
344                        NSC_LOG_MESSAGE_STD(_T("--+--[ Lookup Result ]----------------------------------------"));
345                        NSC_LOG_MESSAGE_STD(_T("  | Index for '") + name + _T("' is ") + strEx::itos(dw));
346                        NSC_LOG_MESSAGE_STD(_T("--+-----------------------------------------------------------"));
347                } catch (const PDH::PDHException e) {
348                        NSC_LOG_ERROR_STD(_T("Failed to lookup index: ") + e.getError());
349                        return 0;
350                }
351        } else if (_wcsicmp(command, _T("pdhmatch")) == 0) {
352                try {
353                        std::wstring name = arrayBuffer::arrayBuffer2string(args, argLen, _T(" "));
354                        if (name.empty()) {
355                                NSC_LOG_ERROR_STD(_T("Need to specify counter pattern!"));
356                                return 0;
357                        }
358                        std::list<std::wstring> list = PDH::PDHResolver::PdhExpandCounterPath(name.c_str());
359                        NSC_LOG_MESSAGE_STD(_T("--+--[ Lookup Result ]----------------------------------------"));
360                        for (std::list<std::wstring>::const_iterator cit = list.begin(); cit != list.end(); ++cit) {
361                                NSC_LOG_MESSAGE_STD(_T("  | Found '") + *cit);
362                        }
363                        NSC_LOG_MESSAGE_STD(_T("--+-----------------------------------------------------------"));
364                } catch (const PDH::PDHException e) {
365                        NSC_LOG_ERROR_STD(_T("Failed to lookup index: ") + e.getError());
366                        return 0;
367                }
368        } else if (_wcsicmp(command, _T("pdhobject")) == 0) {
369                try {
370                        std::wstring name = arrayBuffer::arrayBuffer2string(args, argLen, _T(" "));
371                        if (name.empty()) {
372                                NSC_LOG_ERROR_STD(_T("Need to specify counter pattern!"));
373                                return 0;
374                        }
375                        PDH::Enumerations::pdh_object_details list = PDH::Enumerations::EnumObjectInstances(name.c_str());
376                        NSC_LOG_MESSAGE_STD(_T("--+--[ Lookup Result ]----------------------------------------"));
377                        for (std::list<std::wstring>::const_iterator cit = list.counters.begin(); cit != list.counters.end(); ++cit) {
378                                NSC_LOG_MESSAGE_STD(_T("  | Found Counter: ") + *cit);
379                        }
380                        for (std::list<std::wstring>::const_iterator cit = list.instances.begin(); cit != list.instances.end(); ++cit) {
381                                NSC_LOG_MESSAGE_STD(_T("  | Found Instance: ") + *cit);
382                        }
383                        NSC_LOG_MESSAGE_STD(_T("--+-----------------------------------------------------------"));
384                } catch (const PDH::PDHException e) {
385                        NSC_LOG_ERROR_STD(_T("Failed to lookup index: ") + e.getError());
386                        return 0;
387                }
388        }
389        return 0;
390}
391
392
393/**
394 * Main command parser and delegator.
395 * This also handles a lot of the simpler responses (though some are deferred to other helper functions)
396 *
397 *
398 * @param command
399 * @param argLen
400 * @param **args
401 * @return
402 */
403NSCAPI::nagiosReturn CheckSystem::handleCommand(const std::wstring command, std::list<std::wstring> arguments, std::wstring &msg, std::wstring &perf) {
404        CheckSystem::returnBundle rb;
405        if (command == _T("checkcpu")) {
406                return checkCPU(arguments, msg, perf);
407        } else if (command == _T("checkuptime")) {
408                return checkUpTime(arguments, msg, perf);
409        } else if (command == _T("checkservicestate")) {
410                return checkServiceState(arguments, msg, perf);
411        } else if (command == _T("checkprocstate")) {
412                return checkProcState(arguments, msg, perf);
413        } else if (command == _T("checkmem")) {
414                return checkMem(arguments, msg, perf);
415        } else if (command == _T("checkcounter")) {
416                return checkCounter(arguments, msg, perf);
417        } else if (command == _T("listcounterinstances")) {
418                return listCounterInstances(arguments, msg, perf);
419        } else if (command == _T("checksingleregentry")) {
420                return checkSingleRegEntry(arguments, msg, perf);
421        }
422        return NSCAPI::returnIgnored;
423}
424
425
426class cpuload_handler {
427public:
428        static int parse(std::wstring s) {
429                return strEx::stoi(s);
430        }
431        static int parse_percent(std::wstring s) {
432                return strEx::stoi(s);
433        }
434        static std::wstring print(int value) {
435                return strEx::itos(value) + _T("%");
436        }
437        static std::wstring print_unformated(int value) {
438                return strEx::itos(value);
439        }
440
441        static std::wstring get_perf_unit(__int64 value) {
442                return _T("%");
443        }
444        static std::wstring print_perf(__int64 value, std::wstring unit) {
445                return to_wstring(value);
446        }
447        static std::wstring print_percent(int value) {
448                return to_wstring(value) + _T("%");
449        }
450        static std::wstring key_prefix() {
451                return _T("average load ");
452        }
453        static std::wstring key_postfix() {
454                return _T("");
455        }
456};
457NSCAPI::nagiosReturn CheckSystem::checkCPU(std::list<std::wstring> arguments, std::wstring &msg, std::wstring &perf) {
458        typedef checkHolders::CheckContainer<checkHolders::MaxMinBounds<checkHolders::NumericBounds<int, cpuload_handler> > > CPULoadContainer;
459
460        if (arguments.empty()) {
461                msg = _T("ERROR: Missing argument exception.");
462                return NSCAPI::returnUNKNOWN;
463        }
464        std::list<CPULoadContainer> list;
465        NSCAPI::nagiosReturn returnCode = NSCAPI::returnOK;
466        bool bNSClient = false;
467        bool bPerfData = true;
468        CPULoadContainer tmpObject;
469
470        tmpObject.data = _T("cpuload");
471
472        MAP_OPTIONS_BEGIN(arguments)
473                MAP_OPTIONS_NUMERIC_ALL(tmpObject, _T(""))
474                MAP_OPTIONS_STR(_T("warn"), tmpObject.warn.max_)
475                MAP_OPTIONS_STR(_T("crit"), tmpObject.crit.max_)
476                MAP_OPTIONS_BOOL_FALSE(IGNORE_PERFDATA, bPerfData)
477                MAP_OPTIONS_STR_AND(_T("time"), tmpObject.data, list.push_back(tmpObject))
478                MAP_OPTIONS_STR_AND(_T("Time"), tmpObject.data, list.push_back(tmpObject))
479                MAP_OPTIONS_SHOWALL(tmpObject)
480                MAP_OPTIONS_BOOL_TRUE(NSCLIENT, bNSClient)
481                MAP_OPTIONS_SECONDARY_BEGIN(_T(":"), p2)
482                        else if (p2.first == _T("Time")) {
483                                tmpObject.data = p__.second;
484                                tmpObject.alias = p2.second;
485                                list.push_back(tmpObject);
486                        }
487        MAP_OPTIONS_MISSING_EX(p2, msg, _T("Unknown argument: "))
488                MAP_OPTIONS_SECONDARY_END()
489                MAP_OPTIONS_FALLBACK_AND(tmpObject.data, list.push_back(tmpObject))
490        MAP_OPTIONS_END()
491
492        for (std::list<CPULoadContainer>::const_iterator it = list.begin(); it != list.end(); ++it) {
493                CPULoadContainer load = (*it);
494                PDHCollector *pObject = pdhThread.getThread();
495                if (!pObject) {
496                        msg = _T("ERROR: PDH Collection thread not running.");
497                        return NSCAPI::returnUNKNOWN;
498                }
499                int value = pObject->getCPUAvrage(load.data + _T("m"));
500                if (value == -1) {
501                        msg = _T("ERROR: Could not get data for ") + load.getAlias() + _T(" perhaps we don't collect data this far back?");
502                        return NSCAPI::returnUNKNOWN;
503                }
504                if (bNSClient) {
505                        if (!msg.empty()) msg += _T("&");
506                        msg += strEx::itos(value);
507                } else {
508                        load.setDefault(tmpObject);
509                        load.perfData = bPerfData;
510                        load.runCheck(value, returnCode, msg, perf);
511                }
512        }
513
514        if (msg.empty())
515                msg = _T("OK CPU Load ok.");
516        else if (!bNSClient)
517                msg = nscapi::plugin_helper::translateReturn(returnCode) + _T(": ") + msg;
518        return returnCode;
519}
520
521NSCAPI::nagiosReturn CheckSystem::checkUpTime(std::list<std::wstring> arguments, std::wstring &msg, std::wstring &perf)
522{
523        typedef checkHolders::CheckContainer<checkHolders::MaxMinBoundsTime> UpTimeContainer;
524
525        if (arguments.empty()) {
526                msg = _T("ERROR: Missing argument exception.");
527                return NSCAPI::returnUNKNOWN;
528        }
529        NSCAPI::nagiosReturn returnCode = NSCAPI::returnOK;
530        bool bNSClient = false;
531        bool bPerfData = true;
532        UpTimeContainer bounds;
533
534        bounds.data = _T("uptime");
535
536        MAP_OPTIONS_BEGIN(arguments)
537                MAP_OPTIONS_NUMERIC_ALL(bounds, _T(""))
538                MAP_OPTIONS_STR(_T("warn"), bounds.warn.min_)
539                MAP_OPTIONS_STR(_T("crit"), bounds.crit.min_)
540                MAP_OPTIONS_BOOL_FALSE(IGNORE_PERFDATA, bPerfData)
541                MAP_OPTIONS_STR(_T("Alias"), bounds.data)
542                MAP_OPTIONS_SHOWALL(bounds)
543                MAP_OPTIONS_BOOL_TRUE(NSCLIENT, bNSClient)
544                MAP_OPTIONS_MISSING(msg, _T("Unknown argument: "))
545                MAP_OPTIONS_END()
546
547
548        PDHCollector *pObject = pdhThread.getThread();
549        if (!pObject) {
550                msg = _T("ERROR: PDH Collection thread not running.");
551                return NSCAPI::returnUNKNOWN;
552        }
553        unsigned long long value = pObject->getUptime();
554        if (value == -1) {
555                msg = _T("ERROR: Could not get value");
556                return NSCAPI::returnUNKNOWN;
557        }
558        if (bNSClient) {
559                msg = strEx::itos(value);
560        } else {
561                value *= 1000;
562                bounds.perfData = bPerfData;
563                bounds.runCheck(value, returnCode, msg, perf);
564        }
565
566        if (msg.empty())
567                msg = _T("OK all counters within bounds.");
568        else if (!bNSClient)
569                msg = nscapi::plugin_helper::translateReturn(returnCode) + _T(": ") + msg;
570        return returnCode;
571}
572
573// @todo state_handler
574
575
576inline int get_state(DWORD state) {
577        if (state == SERVICE_RUNNING)
578                return checkHolders::state_started;
579        else if (state == SERVICE_STOPPED)
580                return checkHolders::state_stopped;
581        else if (state == MY_SERVICE_NOT_FOUND)
582                return checkHolders::state_not_found;
583        return checkHolders::state_none;
584}
585
586/**
587 * Retrieve the service state of one or more services (by name).
588 * Parse a list with a service names and verify that all named services are running.
589 * <pre>
590 * Syntax:
591 * request: checkServiceState <option> [<option> [...]]
592 * Return: <return state>&<service1> : <state1> - <service2> : <state2> - ...
593 * Available options:
594 *              <name>=<state>  Check if a service has a specific state
595 *                      State can be wither started or stopped
596 *              ShowAll                 Show the state of all listed service. If not set only critical services are listed.
597 * Examples:
598 * checkServiceState showAll myService MyService
599 *</pre>
600 *
601 * @param command Command to execute
602 * @param argLen The length of the argument buffer
603 * @param **char_args The argument buffer
604 * @param &msg String to put message in
605 * @param &perf String to put performance data in
606 * @return The status of the command
607 */
608NSCAPI::nagiosReturn CheckSystem::checkServiceState(std::list<std::wstring> arguments, std::wstring &msg, std::wstring &perf)
609{
610        typedef checkHolders::CheckContainer<checkHolders::SimpleBoundsStateBoundsInteger> StateContainer;
611        if (arguments.empty()) {
612                msg = _T("ERROR: Missing argument exception.");
613                return NSCAPI::returnUNKNOWN;
614        }
615        std::list<StateContainer> list;
616        std::set<std::wstring> excludeList;
617        NSCAPI::nagiosReturn returnCode = NSCAPI::returnOK;
618        bool bNSClient = false;
619        StateContainer tmpObject;
620        bool bPerfData = true;
621        bool bAutoStart = false;
622        unsigned int truncate = 0;
623
624        tmpObject.data = _T("service");
625        tmpObject.crit.state = _T("started");
626        //{{
627        MAP_OPTIONS_BEGIN(arguments)
628                MAP_OPTIONS_SHOWALL(tmpObject)
629                MAP_OPTIONS_STR(_T("Alias"), tmpObject.data)
630                MAP_OPTIONS_STR2INT(_T("truncate"), truncate)
631                MAP_OPTIONS_BOOL_FALSE(IGNORE_PERFDATA, bPerfData)
632                MAP_OPTIONS_BOOL_TRUE(NSCLIENT, bNSClient)
633                MAP_OPTIONS_BOOL_TRUE(_T("CheckAll"), bAutoStart)
634                MAP_OPTIONS_INSERT(_T("exclude"), excludeList)
635                //MAP_OPTIONS_SECONDARY_BEGIN(_T(":"), p2)
636                //MAP_OPTIONS_MISSING_EX(p2, msg, _T("Unknown argument: "))
637                //MAP_OPTIONS_SECONDARY_END()
638                else {
639                        tmpObject.data = p__.first;
640                        if (p__.second.empty())
641                                tmpObject.crit.state = _T("started");
642                        else
643                                tmpObject.crit.state = p__.second;
644                        list.push_back(tmpObject);
645                }
646        MAP_OPTIONS_END()
647        //}}
648        if (bAutoStart) {
649                // get a list of all service with startup type Automatic
650                /*
651                ;check_all_services[SERVICE_BOOT_START]=ignored
652                ;check_all_services[SERVICE_SYSTEM_START]=ignored
653                ;check_all_services[SERVICE_AUTO_START]=started
654                ;check_all_services[SERVICE_DEMAND_START]=ignored
655                ;check_all_services[SERVICE_DISABLED]=stopped
656                std::wstring wantedMethod = NSCModuleHelper::getSettingsString(C_SYSTEM_SECTION_TITLE, C_SYSTEM_ENUMPROC_METHOD, C_SYSTEM_ENUMPROC_METHOD_DEFAULT);
657                */
658
659                std::list<TNtServiceInfo> service_list_automatic = TNtServiceInfo::EnumServices(SERVICE_WIN32,SERVICE_INACTIVE|SERVICE_ACTIVE);
660                for (std::list<TNtServiceInfo>::const_iterator service =service_list_automatic.begin();service!=service_list_automatic.end();++service) {
661                        if (excludeList.find((*service).m_strServiceName) == excludeList.end()) {
662                                tmpObject.data = (*service).m_strServiceName;
663                                tmpObject.crit.state = lookups_[(*service).m_dwStartType];
664                                list.push_back(tmpObject);
665                        }
666                }
667                tmpObject.crit.state = _T("ignored");
668        }
669        for (std::list<StateContainer>::iterator it = list.begin(); it != list.end(); ++it) {
670                TNtServiceInfo info;
671                if (bNSClient) {
672                        try {
673                                info = TNtServiceInfo::GetService((*it).data.c_str());
674                        } catch (NTServiceException e) {
675                                if (!msg.empty()) msg += _T(" - ");
676                                msg += (*it).data + _T(": Error");
677                                nscapi::plugin_helper::escalteReturnCodeToWARN(returnCode);
678                                continue;
679                        }
680                        if ((*it).crit.state.hasBounds()) {
681                                bool ok = (*it).crit.state.check(get_state(info.m_dwCurrentState));
682                                if (!ok || (*it).showAll()) {
683                                        if (info.m_dwCurrentState == SERVICE_RUNNING) {
684                                                if (!msg.empty()) msg += _T(" - ");
685                                                msg += (*it).data + _T(": Started");
686                                        } else if (info.m_dwCurrentState == SERVICE_STOPPED) {
687                                                if (!msg.empty()) msg += _T(" - ");
688                                                msg += (*it).data + _T(": Stopped");
689                                        } else if (info.m_dwCurrentState == MY_SERVICE_NOT_FOUND) {
690                                                if (!msg.empty()) msg += _T(" - ");
691                                                msg += (*it).data + _T(": Not found");
692                                        } else {
693                                                if (!msg.empty()) msg += _T(" - ");
694                                                msg += (*it).data + _T(": Unknown");
695                                        }
696                                        if (!ok)
697                                                nscapi::plugin_helper::escalteReturnCodeToCRIT(returnCode);
698                                }
699                        }
700                } else {
701                        try {
702                                info = TNtServiceInfo::GetService((*it).data.c_str());
703                        } catch (NTServiceException e) {
704                                NSC_LOG_ERROR_STD(e.getError());
705                                msg = e.getError();
706                                return NSCAPI::returnUNKNOWN;
707                        }
708                        checkHolders::state_type value;
709                        if (info.m_dwCurrentState == SERVICE_RUNNING)
710                                value = checkHolders::state_started;
711                        else if (info.m_dwCurrentState == SERVICE_STOPPED)
712                                value = checkHolders::state_stopped;
713                        else if (info.m_dwCurrentState == MY_SERVICE_NOT_FOUND)
714                                value = checkHolders::state_not_found;
715                        else {
716                                NSC_LOG_MESSAGE(_T("Service had no (valid) state: ") + (*it).data + _T(" (") + strEx::itos(info.m_dwCurrentState) + _T(")"));
717                                value = checkHolders::state_none;
718                        }
719                        unsigned int x = returnCode;
720                        (*it).perfData = bPerfData;
721                        (*it).setDefault(tmpObject);
722                        (*it).runCheck(value, returnCode, msg, perf);
723//                      NSC_LOG_MESSAGE(_T("Service: ") + (*it).data + _T(" (") + strEx::itos(info.m_dwCurrentState) + _T(":") + strEx::itos((*it).warn.state.value_) + _T(":") + strEx::itos((*it).crit.state.value_) + _T(") -- (") + strEx::itos(returnCode) + _T(":") + strEx::itos(x) + _T(")"));
724                }
725        }
726        if ((truncate > 0) && (msg.length() > (truncate-4)))
727                msg = msg.substr(0, truncate-4) + _T("...");
728        if (msg.empty() && returnCode == NSCAPI::returnOK)
729                msg = _T("OK: All services are in their appropriate state.");
730        else if (msg.empty())
731                msg = nscapi::plugin_helper::translateReturn(returnCode) + _T(": Whooha this is odd.");
732        else if (!bNSClient)
733                msg = nscapi::plugin_helper::translateReturn(returnCode) + _T(": ") + msg;
734        return returnCode;
735}
736
737/**
738 * Check available memory and return various check results
739 * Example: checkMem showAll maxWarn=50 maxCrit=75
740 *
741 * @param command Command to execute
742 * @param argLen The length of the argument buffer
743 * @param **char_args The argument buffer
744 * @param &msg String to put message in
745 * @param &perf String to put performance data in
746 * @return The status of the command
747 */
748NSCAPI::nagiosReturn CheckSystem::checkMem(std::list<std::wstring> arguments, std::wstring &msg, std::wstring &perf)
749{
750        typedef checkHolders::CheckContainer<checkHolders::MaxMinBounds<checkHolders::NumericPercentageBounds<checkHolders::PercentageValueType<unsigned __int64, unsigned __int64>, checkHolders::disk_size_handler<unsigned __int64> > > > MemoryContainer;
751        if (arguments.empty()) {
752                msg = _T("ERROR: Missing argument exception.");
753                return NSCAPI::returnUNKNOWN;
754        }
755        std::list<MemoryContainer> list;
756        NSCAPI::nagiosReturn returnCode = NSCAPI::returnOK;
757        bool bShowAll = false;
758        bool bPerfData = true;
759        bool bNSClient = false;
760        MemoryContainer tmpObject;
761
762        MAP_OPTIONS_BEGIN(arguments)
763                MAP_OPTIONS_SHOWALL(tmpObject)
764                MAP_OPTIONS_STR_AND(_T("type"), tmpObject.data, list.push_back(tmpObject))
765                MAP_OPTIONS_STR_AND(_T("Type"), tmpObject.data, list.push_back(tmpObject))
766                MAP_OPTIONS_SECONDARY_BEGIN(_T(":"), p2)
767                MAP_OPTIONS_SECONDARY_STR_AND(p2,_T("type"), tmpObject.data, tmpObject.alias, list.push_back(tmpObject))
768                        MAP_OPTIONS_MISSING_EX(p2, msg, _T("Unknown argument: "))
769                        MAP_OPTIONS_SECONDARY_END()
770                MAP_OPTIONS_BOOL_FALSE(IGNORE_PERFDATA, bPerfData)
771                MAP_OPTIONS_BOOL_TRUE(NSCLIENT, bNSClient)
772                MAP_OPTIONS_DISK_ALL(tmpObject, _T(""), _T("Free"), _T("Used"))
773                MAP_OPTIONS_STR(_T("Alias"), tmpObject.data)
774                MAP_OPTIONS_SHOWALL(tmpObject)
775                MAP_OPTIONS_MISSING(msg, _T("Unknown argument: "))
776                MAP_OPTIONS_END()
777
778        if (bNSClient) {
779                tmpObject.data = _T("paged");
780                list.push_back(tmpObject);
781        }
782
783        checkHolders::PercentageValueType<unsigned long long, unsigned long long> dataPaged;
784        CheckMemory::memData data;
785        bool firstPaged = true;
786        bool firstMem = true;
787        for (std::list<MemoryContainer>::const_iterator pit = list.begin(); pit != list.end(); ++pit) {
788                MemoryContainer check = (*pit);
789                check.setDefault(tmpObject);
790                checkHolders::PercentageValueType<unsigned long long, unsigned long long> value;
791                if (firstPaged && (check.data == _T("paged"))) {
792                        firstPaged = false;
793                        PDHCollector *pObject = pdhThread.getThread();
794                        if (!pObject) {
795                                msg = _T("ERROR: PDH Collection thread not running.");
796                                return NSCAPI::returnUNKNOWN;
797                        }
798                        dataPaged.value = pObject->getMemCommit();
799                        if (dataPaged.value == -1) {
800                                msg = _T("ERROR: Failed to get PDH value.");
801                                return NSCAPI::returnUNKNOWN;
802                        }
803                        dataPaged.total = pObject->getMemCommitLimit();
804                        if (dataPaged.total == -1) {
805                                msg = _T("ERROR: Failed to get PDH value.");
806                                return NSCAPI::returnUNKNOWN;
807                        }
808                } else if (firstMem) {
809                        try {
810                                data = memoryChecker.getMemoryStatus();
811                        } catch (CheckMemoryException e) {
812                                msg = e.getError();
813                                return NSCAPI::returnCRIT;
814                        }
815                }
816
817                if (check.data == _T("page")) {
818                        value.value = data.pageFile.total-data.pageFile.avail; // mem.dwTotalPageFile-mem.dwAvailPageFile;
819                        value.total = data.pageFile.total; //mem.dwTotalPageFile;
820                        if (check.alias.empty())
821                                check.alias = _T("page file");
822                } else if (check.data == _T("physical")) {
823                        value.value = data.phys.total-data.phys.avail; //mem.dwTotalPhys-mem.dwAvailPhys;
824                        value.total = data.phys.total; //mem.dwTotalPhys;
825                        if (check.alias.empty())
826                                check.alias = _T("physical memory");
827                } else if (check.data == _T("virtual")) {
828                        value.value = data.virtualMem.total-data.virtualMem.avail;//mem.dwTotalVirtual-mem.dwAvailVirtual;
829                        value.total = data.virtualMem.total;//mem.dwTotalVirtual;
830                        if (check.alias.empty())
831                                check.alias = _T("virtual memory");
832                } else  if (check.data == _T("paged")) {
833                        value.value = dataPaged.value;
834                        value.total = dataPaged.total;
835                        if (check.alias.empty())
836                                check.alias = _T("paged bytes");
837                } else {
838                        msg = check.data + _T(" is not a known check...");
839                        return NSCAPI::returnCRIT;
840                }
841                if (bNSClient) {
842                        msg = strEx::itos(value.total) + _T("&") + strEx::itos(value.value);
843                        return NSCAPI::returnOK;
844                } else {
845                        check.perfData = bPerfData;
846                        check.runCheck(value, returnCode, msg, perf);
847                }
848        }
849
850        if (msg.empty())
851                msg = _T("OK memory within bounds.");
852        else
853                msg = nscapi::plugin_helper::translateReturn(returnCode) + _T(": ") + msg;
854        return returnCode;
855}
856typedef struct NSPROCDATA__ {
857        unsigned int count;
858        unsigned int hung_count;
859        CEnumProcess::CProcessEntry entry;
860        std::wstring key;
861
862        NSPROCDATA__() : count(0), hung_count(0) {}
863        NSPROCDATA__(const NSPROCDATA__ &other) : count(other.count), hung_count(other.hung_count), entry(other.entry), key(other.key) {}
864} NSPROCDATA;
865typedef std::map<std::wstring,NSPROCDATA> NSPROCLST;
866
867class NSC_error : public CEnumProcess::error_reporter {
868        void report_error(std::wstring error) {
869                NSC_LOG_ERROR(error);
870        }
871        void report_warning(std::wstring error) {
872                NSC_LOG_MESSAGE(error);
873        }
874        void report_debug(std::wstring error) {
875                NSC_DEBUG_MSG_STD(_T("PROC::: ") + error);
876        }
877        void report_debug_enter(std::wstring error) {
878                NSC_DEBUG_MSG_STD(_T("PROC>>> ") + error);
879        }
880        void report_debug_exit(std::wstring error) {
881                NSC_DEBUG_MSG_STD(_T("PROC<<<") + error);
882        }
883};
884
885/**
886* Get a hash_map with all running processes.
887* @return a hash_map with all running processes
888*/
889NSPROCLST GetProcessList(bool getCmdLines, bool use16Bit)
890{
891        NSPROCLST ret;
892        CEnumProcess enumeration;
893        if (!enumeration.has_PSAPI()) {
894                NSC_LOG_ERROR_STD(_T("Failed to enumerat processes"));
895                NSC_LOG_ERROR_STD(_T("PSAPI method not availabletry installing \"Platform SDK Redistributable: PSAPI for Windows NT\" from Microsoft."));
896                NSC_LOG_ERROR_STD(_T("Try this URL: http://www.microsoft.com/downloads/details.aspx?FamilyID=3d1fbaed-d122-45cf-9d46-1cae384097ac"));
897                throw CEnumProcess::process_enumeration_exception(_T("PSAPI not avalible, please see eror log for details."));
898        }
899        NSC_error err;
900        CEnumProcess::process_list list = enumeration.enumerate_processes(getCmdLines, use16Bit, &err);
901        for (CEnumProcess::process_list::const_iterator entry = list.begin(); entry != list.end(); ++entry) {
902                std::wstring key;
903                if (getCmdLines && !(*entry).command_line.empty())
904                        key = (*entry).command_line;
905                else
906                        key = boost::to_lower_copy((*entry).filename);
907                NSPROCLST::iterator it = ret.find(key);
908                if (it == ret.end()) {
909                        ret[key].entry = (*entry);
910                        ret[key].count = 1;
911                        ret[key].hung_count = (*entry).hung?1:0;
912                        ret[key].key = key;
913                } else {
914                        if ((*entry).hung)
915                                (*it).second.hung_count++;
916                        (*it).second.count++;
917                }
918        }
919        return ret;
920}
921
922/**
923 * Check process state and return result
924 *
925 * @param command Command to execute
926 * @param argLen The length of the argument buffer
927 * @param **char_args The argument buffer
928 * @param &msg String to put message in
929 * @param &perf String to put performance data in
930 * @return The status of the command
931 */
932NSCAPI::nagiosReturn CheckSystem::checkProcState(std::list<std::wstring> arguments, std::wstring &msg, std::wstring &perf)
933{
934        typedef checkHolders::CheckContainer<checkHolders::MaxMinStateBoundsStateBoundsInteger> StateContainer;
935        if (arguments.empty()) {
936                msg = _T("ERROR: Missing argument exception.");
937                return NSCAPI::returnUNKNOWN;
938        }
939        std::list<StateContainer> list;
940        NSCAPI::nagiosReturn returnCode = NSCAPI::returnOK;
941        bool bNSClient = false;
942        StateContainer tmpObject;
943        bool bPerfData = true;
944        bool use16bit = false;
945        bool useCmdLine = false;
946        typedef enum {
947                match_string, match_substring, match_regexp
948        } match_type;
949        match_type match = match_string;
950
951       
952
953        tmpObject.data = _T("uptime");
954        tmpObject.crit.state = _T("started");
955
956        MAP_OPTIONS_BEGIN(arguments)
957                MAP_OPTIONS_NUMERIC_ALL(tmpObject, _T("Count"))
958                MAP_OPTIONS_STR(_T("Alias"), tmpObject.alias)
959                MAP_OPTIONS_SHOWALL(tmpObject)
960                MAP_OPTIONS_BOOL_FALSE(IGNORE_PERFDATA, bPerfData)
961                MAP_OPTIONS_BOOL_TRUE(NSCLIENT, bNSClient)
962                MAP_OPTIONS_BOOL_TRUE(_T("cmdLine"), useCmdLine)
963                MAP_OPTIONS_BOOL_TRUE(_T("16bit"), use16bit)
964                MAP_OPTIONS_MODE(_T("match"), _T("string"), match,  match_string)
965                MAP_OPTIONS_MODE(_T("match"), _T("regexp"), match,  match_regexp)
966                MAP_OPTIONS_MODE(_T("match"), _T("substr"), match,  match_substring)
967                MAP_OPTIONS_MODE(_T("match"), _T("substring"), match,  match_substring)
968                MAP_OPTIONS_SECONDARY_BEGIN(_T(":"), p2)
969        else if (p2.first == _T("Proc")) {
970                        tmpObject.data = p__.second;
971                        tmpObject.alias = p2.second;
972                        list.push_back(tmpObject);
973                }
974        MAP_OPTIONS_MISSING_EX(p2, msg, _T("Unknown argument: "))
975                MAP_OPTIONS_SECONDARY_END()
976                else {
977                        tmpObject.data = p__.first;
978                        if (p__.second.empty())
979                                tmpObject.crit.state = _T("started");
980                        else
981                                tmpObject.crit.state = p__.second;
982                        list.push_back(tmpObject);
983                }
984        MAP_OPTIONS_END()
985
986        NSPROCLST runningProcs;
987        try {
988                runningProcs = GetProcessList(useCmdLine, use16bit);
989        } catch (CEnumProcess::process_enumeration_exception &e) {
990                NSC_LOG_ERROR_STD(_T("ERROR: ") + e.what());
991                msg = static_cast<std::wstring>(_T("ERROR: ")) + e.what();
992                return NSCAPI::returnUNKNOWN;
993        } catch (...) {
994                NSC_LOG_ERROR_STD(_T("Unhandled error when processing command"));
995                msg = _T("Unhandled error when processing command");
996                return NSCAPI::returnUNKNOWN;
997        }
998
999        for (std::list<StateContainer>::iterator it = list.begin(); it != list.end(); ++it) {
1000                NSPROCLST::iterator proc;
1001                if (match == match_string) {
1002                        proc = runningProcs.find((*it).data);
1003                } else if (match == match_substring) {
1004                        for (proc=runningProcs.begin();proc!=runningProcs.end();++proc) {
1005                                if ((*proc).first.find((*it).data) != std::wstring::npos)
1006                                        break;
1007                        }
1008#ifdef USE_BOOST
1009                } else if (match == match_regexp) {
1010                        try {
1011                                boost::wregex filter((*it).data,boost::regex::icase);
1012                                for (proc=runningProcs.begin();proc!=runningProcs.end();++proc) {
1013                                        std::wstring value = (*proc).first;
1014                                        if (boost::regex_match(value, filter))
1015                                                break;
1016                                }
1017                        } catch (const boost::bad_expression e) {
1018                                NSC_LOG_ERROR_STD(_T("Failed to compile regular expression: ") + (*proc).first);
1019                                msg = _T("Failed to compile regular expression: ") + (*proc).first;
1020                                return NSCAPI::returnUNKNOWN;
1021                        } catch (...) {
1022                                NSC_LOG_ERROR_STD(_T("Failed to compile regular expression: ") + (*proc).first);
1023                                msg = _T("Failed to compile regular expression: ") + (*proc).first;
1024                                return NSCAPI::returnUNKNOWN;
1025                        }
1026#else
1027                        NSC_LOG_ERROR_STD(_T("NSClient++ is compiled without USEBOOST so no regular expression support for you...") + (*proc).first);
1028                        msg = _T("Regular expression is not supported: ") + (*proc).first;
1029                        return NSCAPI::returnUNKNOWN;
1030#endif
1031                } else {
1032                        NSC_LOG_ERROR_STD(_T("Unsupported mode for: ") + (*proc).first);
1033                        msg = _T("Unsupported mode for: ") + (*proc).first;
1034                        return NSCAPI::returnUNKNOWN;
1035                }
1036                bool bFound = (proc != runningProcs.end());
1037                if (bNSClient) {
1038                        if (bFound && (*it).showAll()) {
1039                                if (!msg.empty()) msg += _T(" - ");
1040                                msg += (*proc).first + _T(": Running");
1041                        } else if (bFound) {
1042                        } else {
1043                                if (!msg.empty()) msg += _T(" - ");
1044                                msg += (*it).data + _T(": not running");
1045                                nscapi::plugin_helper::escalteReturnCodeToCRIT(returnCode);
1046                        }
1047                } else {
1048                        checkHolders::MaxMinStateValueType<int, checkHolders::state_type> value;
1049                        if (bFound) {
1050                                if ((*proc).second.hung_count > 0) {
1051                                        NSC_LOG_ERROR_STD(_T("Hung proc: ") + strEx::itos((*proc).second.hung_count));
1052                                        value.count = (*proc).second.count;
1053                                        value.state = checkHolders::state_hung;
1054                                } else {
1055                                        value.count = (*proc).second.count;
1056                                        value.state = checkHolders::state_started;
1057                                }
1058                        } else {
1059                                value.count = 0;
1060                                value.state = checkHolders::state_stopped;
1061                        }
1062                        if (bFound && (*it).alias.empty()) {
1063                                (*it).alias = (*proc).first;
1064                        }
1065                        (*it).perfData = bPerfData;
1066                        (*it).runCheck(value, returnCode, msg, perf);
1067                }
1068
1069        }
1070        if (msg.empty())
1071                msg = _T("OK: All processes are running.");
1072        else if (!bNSClient)
1073                msg = nscapi::plugin_helper::translateReturn(returnCode) + _T(": ") + msg;
1074        return returnCode;
1075}
1076
1077
1078/**
1079 * Check a counter and return the value
1080 *
1081 * @param command Command to execute
1082 * @param argLen The length of the argument buffer
1083 * @param **char_args The argument buffer
1084 * @param &msg String to put message in
1085 * @param &perf String to put performance data in
1086 * @return The status of the command
1087 *
1088 * @todo add parsing support for NRPE
1089 */
1090NSCAPI::nagiosReturn CheckSystem::checkCounter(std::list<std::wstring> arguments, std::wstring &msg, std::wstring &perf)
1091{
1092        typedef checkHolders::CheckContainer<checkHolders::MaxMinBoundsDouble> CounterContainer;
1093
1094        if (arguments.empty()) {
1095                msg = _T("ERROR: Missing argument exception.");
1096                return NSCAPI::returnUNKNOWN;
1097        }
1098        std::list<CounterContainer> counters;
1099        NSCAPI::nagiosReturn returnCode = NSCAPI::returnOK;
1100        bool bNSClient = false;
1101        bool bPerfData = true;
1102        /* average maax */
1103        bool bCheckAverages = true;
1104        std::wstring invalidStatus = _T("UNKNOWN");
1105        unsigned int averageDelay = 1000;
1106        CounterContainer tmpObject;
1107        bool bExpandIndex = false;
1108        bool bForceReload = false;
1109
1110        MAP_OPTIONS_BEGIN(arguments)
1111                MAP_OPTIONS_STR(_T("InvalidStatus"), invalidStatus)
1112                MAP_OPTIONS_STR_AND(_T("Counter"), tmpObject.data, counters.push_back(tmpObject))
1113                MAP_OPTIONS_STR(_T("MaxWarn"), tmpObject.warn.max_)
1114                MAP_OPTIONS_STR(_T("MinWarn"), tmpObject.warn.min_)
1115                MAP_OPTIONS_STR(_T("MaxCrit"), tmpObject.crit.max_)
1116                MAP_OPTIONS_STR(_T("MinCrit"), tmpObject.crit.min_)
1117                MAP_OPTIONS_BOOL_FALSE(IGNORE_PERFDATA, bPerfData)
1118                MAP_OPTIONS_STR(_T("Alias"), tmpObject.data)
1119                MAP_OPTIONS_SHOWALL(tmpObject)
1120                MAP_OPTIONS_BOOL_EX(_T("Averages"), bCheckAverages, _T("true"), _T("false"))
1121                MAP_OPTIONS_BOOL_TRUE(NSCLIENT, bNSClient)
1122                MAP_OPTIONS_BOOL_TRUE(_T("index"), bExpandIndex)
1123                MAP_OPTIONS_BOOL_TRUE(_T("reload"), bForceReload)
1124                MAP_OPTIONS_FIRST_CHAR('\\', tmpObject.data, counters.push_back(tmpObject))
1125                MAP_OPTIONS_SECONDARY_BEGIN(_T(":"), p2)
1126        else if (p2.first == _T("Counter")) {
1127                tmpObject.data = p__.second;
1128                                tmpObject.alias = p2.second;
1129                                counters.push_back(tmpObject);
1130                        }
1131        MAP_OPTIONS_MISSING_EX(p2, msg, _T("Unknown argument: "))
1132                MAP_OPTIONS_SECONDARY_END()
1133                MAP_OPTIONS_FALLBACK_AND(tmpObject.data, counters.push_back(tmpObject))
1134        MAP_OPTIONS_END()
1135
1136        if (counters.empty()) {
1137                msg = _T("No counters specified");
1138                return NSCAPI::returnUNKNOWN;
1139        }
1140
1141        for (std::list<CounterContainer>::const_iterator cit = counters.begin(); cit != counters.end(); ++cit) {
1142                CounterContainer counter = (*cit);
1143                try {
1144
1145
1146                        double value  = 0;
1147                        if (counter.data.find('\\') == std::wstring::npos) {
1148                                PDHCollector *pObject = pdhThread.getThread();
1149                                if (!pObject) {
1150                                        msg = _T("ERROR: PDH Collection thread not running.");
1151                                        return NSCAPI::returnUNKNOWN;
1152                                }
1153                                value = pObject->get_double(counter.data);
1154                                if (value == -1) {
1155                                        msg = _T("ERROR: Failed to get counter value: ") + counter.data;
1156                                        return NSCAPI::returnUNKNOWN;
1157                                }
1158                        } else {
1159                                std::wstring tstr;
1160                                if (bExpandIndex) {
1161                                        PDH::PDHResolver::expand_index(counter.data);
1162                                }
1163                                if (!PDH::PDHResolver::validate(counter.data, tstr, bForceReload)) {
1164                                        NSC_LOG_ERROR_STD(_T("ERROR: Counter not found: ") + counter.data + _T(": ") + tstr);
1165                                        if (bNSClient) {
1166                                                NSC_LOG_ERROR_STD(_T("ERROR: Counter not found: ") + counter.data + _T(": ") + tstr);
1167                                                //msg = _T("0");
1168                                        } else {
1169                                                msg = _T("CRIT: Counter not found: ") + counter.data + _T(": ") + tstr;
1170                                                return NSCAPI::returnCRIT;
1171                                        }
1172                                }
1173                                PDH::PDHQuery pdh;
1174                                typedef boost::shared_ptr<PDHCollectors::StaticPDHCounterListener<double, PDH_FMT_DOUBLE> > ptr_lsnr_type;
1175                                ptr_lsnr_type cDouble(new PDHCollectors::StaticPDHCounterListener<double, PDH_FMT_DOUBLE>());
1176                                //boost::shared_ptr<PDHCollectors::StaticPDHCounterListener<double, PDH_FMT_DOUBLE> > cDouble;
1177                                pdh.addCounter(counter.data, cDouble);
1178                                pdh.open();
1179                                if (bCheckAverages) {
1180                                        pdh.collect();
1181                                        Sleep(1000);
1182                                }
1183                                pdh.gatherData();
1184                                pdh.close();
1185                                value = cDouble->getValue();
1186                        }
1187
1188
1189                        if (bNSClient) {
1190                                if (!msg.empty())
1191                                        msg += _T(",");
1192                                msg += strEx::itos(static_cast<float>(value));
1193                        } else {
1194                                std::wcout << _T("perf data: ") << bPerfData << std::endl;
1195                                counter.perfData = bPerfData;
1196                                counter.setDefault(tmpObject);
1197                                counter.runCheck(value, returnCode, msg, perf);
1198                        }
1199                } catch (const PDH::PDHException e) {
1200                        NSC_LOG_ERROR_STD(_T("ERROR: ") + e.getError() + _T(" (") + counter.getAlias() + _T("|") + counter.data + _T(")"));
1201                        if (bNSClient)
1202                                msg = _T("0");
1203                        else
1204                                msg = static_cast<std::wstring>(_T("ERROR: ")) + e.getError()+ _T(" (") + counter.getAlias() + _T("|") + counter.data + _T(")");
1205                        return NSCAPI::returnUNKNOWN;
1206                }
1207        }
1208
1209        if (msg.empty() && !bNSClient)
1210                msg = _T("OK all counters within bounds.");
1211        else if (msg.empty()) {
1212                NSC_LOG_ERROR_STD(_T("No value found returning 0?"));
1213                msg = _T("0");
1214        }else if (!bNSClient)
1215                msg = nscapi::plugin_helper::translateReturn(returnCode) + _T(": ") + msg;
1216        return returnCode;
1217}
1218
1219
1220
1221/**
1222 * List all instances for a given counter.
1223 *
1224 * @param command Command to execute
1225 * @param argLen The length of the argument buffer
1226 * @param **char_args The argument buffer
1227 * @param &msg String to put message in
1228 * @param &perf String to put performance data in
1229 * @return The status of the command
1230 *
1231 * @todo add parsing support for NRPE
1232 */
1233NSCAPI::nagiosReturn CheckSystem::listCounterInstances(std::list<std::wstring> arguments, std::wstring &msg, std::wstring &perf)
1234{
1235        typedef checkHolders::CheckContainer<checkHolders::MaxMinBoundsDouble> CounterContainer;
1236
1237        if (arguments.empty()) {
1238                msg = _T("ERROR: Missing argument exception.");
1239                return NSCAPI::returnUNKNOWN;
1240        }
1241
1242        std::wstring counter;
1243        BOOST_FOREACH(std::wstring s, arguments) { counter+= s + _T(" "); }
1244        try {
1245                PDH::Enumerations::pdh_object_details obj = PDH::Enumerations::EnumObjectInstances(counter);
1246                for (PDH::Enumerations::pdh_object_details::list::const_iterator it = obj.instances.begin(); it!=obj.instances.end();++it) {
1247                        if (!msg.empty())
1248                                msg += _T(", ");
1249                        msg += (*it);
1250                }
1251                if (msg.empty()) {
1252                        msg = _T("ERROR: No instances found");
1253                        return NSCAPI::returnUNKNOWN;
1254                }
1255        } catch (const PDH::PDHException e) {
1256                msg = _T("ERROR: Failed to enumerate counter instances: " + e.getError());
1257                return NSCAPI::returnUNKNOWN;
1258        } catch (...) {
1259                msg = _T("ERROR: Failed to enumerate counter instances: <UNKNOWN EXCEPTION>");
1260                return NSCAPI::returnUNKNOWN;
1261        }
1262        return NSCAPI::returnOK;
1263}
1264
1265//////////////////////////////////////////////////////////////////////////
1266//////////////////////////////////////////////////////////////////////////
1267
1268struct regkey_info {
1269
1270        std::wstring error;
1271
1272        static regkey_info get(__int64 now, std::wstring path) {
1273                return regkey_info(now, path);
1274        }
1275
1276        regkey_info()
1277                : ullLastWriteTime(0)
1278                , iType(0)
1279                , ullNow(0)
1280                , uiExists(0)
1281                , ullChildCount(0)
1282        {}
1283        regkey_info(__int64 now, std::wstring path)
1284                : path(path)
1285                , ullLastWriteTime(0)
1286                , iType(0)
1287                , ullNow(now)
1288                , uiExists(0)
1289                , ullChildCount(0)
1290        {
1291                std::wstring key;
1292                try {
1293                        std::wcout << _T("opening: ") << path << std::endl;
1294                        std::wstring::size_type pos = path.find_first_of(L'\\');
1295                        if (pos != std::wstring::npos)  {
1296                                key = path.substr(0, pos);
1297                                path = path.substr(pos+1);
1298                                std::wcout << key << _T(":") << path << std::endl;
1299                                simple_registry::registry_key rkey(simple_registry::parseHKEY(key), path);
1300                                info = rkey.get_info();
1301                                uiExists = 1;
1302                        } else {
1303                                error = _T("Failed to parse key");
1304                        }
1305                } catch (simple_registry::registry_exception &e) {
1306                        try {
1307                                std::wstring::size_type pos = path.find_last_of(L'\\');
1308                                if (pos != std::wstring::npos)  {
1309                                        std::wstring item = path.substr(pos+1);
1310                                        path = path.substr(0, pos);
1311                                        std::wcout << key << _T(":") << path << _T(".") << item << std::endl;
1312                                        simple_registry::registry_key rkey(simple_registry::parseHKEY(key), path);
1313                                        info = rkey.get_info(item);
1314                                        uiExists = 1;
1315                                } else {
1316                                        error = _T("Failed to parse key");
1317                                }
1318                        } catch (simple_registry::registry_exception &e) {
1319                                //error = e.what();
1320                        }
1321                } catch (...) {
1322                        error = _T("Unknown exception");
1323                }
1324
1325                //HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\eventlog\Application\MaxSize
1326
1327                // TODO get key info here!
1328                //ullLastWriteTime = ((info.ftLastWriteTime.dwHighDateTime * ((unsigned long long)MAXDWORD+1)) + (unsigned long long)info.ftLastWriteTime.dwLowDateTime);
1329        };
1330
1331        unsigned long long ullSize;
1332        __int64 ullLastWriteTime;
1333        __int64 ullNow;
1334        std::wstring filename;
1335        std::wstring path;
1336        unsigned long ullChildCount;
1337        unsigned long uiExists;
1338        unsigned int iType;
1339        simple_registry::registry_key::reg_info info;
1340
1341        static const __int64 MSECS_TO_100NS = 10000;
1342
1343        __int64 get_written() {
1344                return (ullNow-ullLastWriteTime)/MSECS_TO_100NS;
1345        }
1346        std::wstring render(std::wstring syntax) {
1347                strEx::replace(syntax, _T("%path%"), path);
1348                strEx::replace(syntax, _T("%key%"), filename);
1349                strEx::replace(syntax, _T("%write%"), strEx::format_filetime(ullLastWriteTime, DATE_FORMAT));
1350                strEx::replace(syntax, _T("%write-raw%"), strEx::itos(ullLastWriteTime));
1351                strEx::replace(syntax, _T("%now-raw%"), strEx::itos(ullNow));
1352                strEx::replace(syntax, _T("%type%"), strEx::itos_as_BKMG(iType));
1353                strEx::replace(syntax, _T("%child-count%"), strEx::itos(ullChildCount));
1354                strEx::replace(syntax, _T("%exists%"), strEx::itos(uiExists));
1355                strEx::replace(syntax, _T("%int%"), strEx::itos(info.iValue));
1356                strEx::replace(syntax, _T("%int-value%"), strEx::itos(info.iValue));
1357                strEx::replace(syntax, _T("%string%"), info.sValue);
1358                strEx::replace(syntax, _T("%string-value%"), info.sValue);
1359                return syntax;
1360        }
1361};
1362
1363
1364struct regkey_filter {
1365        filters::filter_all_times written;
1366        filters::filter_all_num_ul type;
1367        filters::filter_all_num_ul exists;
1368        filters::filter_all_num_ul child_count;
1369        filters::filter_all_num_ll value_int;
1370        filters::filter_all_strings value_string;
1371
1372        inline bool hasFilter() {
1373                return type.hasFilter() || exists.hasFilter() || written.hasFilter() || child_count.hasFilter() || value_int.hasFilter() || value_string.hasFilter();
1374        }
1375        bool matchFilter(regkey_info &value) const {
1376                if ((written.hasFilter())&&(written.matchFilter(value.get_written())))
1377                        return true;
1378                else if (type.hasFilter()&&type.matchFilter(value.iType))
1379                        return true;
1380                else if (exists.hasFilter()&&exists.matchFilter(value.uiExists))
1381                        return true;
1382                else if ((child_count.hasFilter())&&(child_count.matchFilter(value.ullChildCount)))
1383                        return true;
1384                else if ((value_int.hasFilter())&&(value_int.matchFilter(value.info.iValue)))
1385                        return true;
1386                else if ((value_string.hasFilter())&&(value_string.matchFilter(value.info.sValue)))
1387                        return true;
1388                return false;
1389        }
1390
1391        std::wstring getValue() const {
1392                if (written.hasFilter())
1393                        return _T("written: ") + written.getValue();
1394                if (type.hasFilter())
1395                        return _T("type: ") + type.getValue();
1396                if (exists.hasFilter())
1397                        return _T("exists: ") + exists.getValue();
1398                if (child_count.hasFilter())
1399                        return _T("child_count: ") + child_count.getValue();
1400                if (value_int.hasFilter())
1401                        return _T("value(i): ") + value_int.getValue();
1402                if (value_string.hasFilter())
1403                        return _T("value(s): ") + value_string.getValue();
1404                return _T("UNknown...");
1405        }
1406
1407};
1408
1409
1410struct regkey_container : public regkey_info {
1411
1412        static regkey_container get(std::wstring path, unsigned long long now) {
1413                return regkey_container(now, path);
1414        }
1415
1416
1417        regkey_container(__int64 now, std::wstring path) : regkey_info(now, path) {}
1418
1419        bool has_errors() {
1420                return !error.empty();
1421        }
1422        std::wstring get_error() {
1423                return error;
1424        }
1425
1426};
1427
1428
1429class regkey_type_handler {
1430public:
1431        static int parse(std::wstring s) {
1432                return 1;
1433        }
1434        static std::wstring print(int value) {
1435                return _T("unknown");
1436        }
1437        static std::wstring print_unformated(int value) {
1438                return strEx::itos(value);
1439        }
1440        static std::wstring key_prefix() {
1441                return _T("");
1442        }
1443        static std::wstring key_postfix() {
1444                return _T("");
1445        }
1446        static std::wstring get_perf_unit(int  value) {
1447                return _T("");
1448        }
1449        static std::wstring print_perf(int  value, std::wstring unit) {
1450                return strEx::itos(value);
1451        }
1452};
1453class regkey_exists_handler {
1454public:
1455        static int parse(std::wstring s) {
1456                if (s  == _T("true"))
1457                        return 1;
1458                return 0;
1459        }
1460        static std::wstring print(int value) {
1461                return value==1?_T("true"):_T("false");
1462        }
1463        static std::wstring print_unformated(int value) {
1464                return strEx::itos(value);
1465        }
1466        static std::wstring key_prefix() {
1467                return _T("");
1468        }
1469        static std::wstring key_postfix() {
1470                return _T("");
1471        }
1472        static std::wstring get_perf_unit(int value) {
1473                return _T("");
1474        }
1475        static std::wstring print_perf(int  value, std::wstring unit) {
1476                return strEx::itos(value);
1477        }
1478};
1479
1480typedef checkHolders::CheckContainer<checkHolders::ExactBounds<checkHolders::NumericBounds<int, regkey_type_handler> > > RegTypeContainer;
1481typedef checkHolders::CheckContainer<checkHolders::ExactBounds<checkHolders::NumericBounds<int, regkey_exists_handler> > > RegExistsContainer;
1482
1483typedef checkHolders::CheckContainer<checkHolders::ExactBoundsULong> ExactULongContainer;
1484typedef checkHolders::CheckContainer<checkHolders::ExactBoundsLongLong> ExactLongLongContainer;
1485typedef checkHolders::CheckContainer<checkHolders::ExactBoundsTime> DateTimeContainer;
1486typedef checkHolders::CheckContainer<checkHolders::FilterBounds<filters::filter_all_strings> > StringContainer;
1487
1488struct check_regkey_child_count : public checkHolders::check_proxy_container<regkey_container, ExactULongContainer> {
1489        check_regkey_child_count() { set_alias(_T("child-count")); }
1490        unsigned long get_value(regkey_container &value) {
1491                return value.ullChildCount;
1492        }
1493};
1494struct check_regkey_int_value : public checkHolders::check_proxy_container<regkey_container, ExactLongLongContainer> {
1495        check_regkey_int_value() { set_alias(_T("value")); }
1496        long long get_value(regkey_container &value) {
1497                return value.info.iValue;
1498        }
1499};
1500struct check_regkey_string_value : public checkHolders::check_proxy_container<regkey_container, StringContainer> {
1501        check_regkey_string_value() { set_alias(_T("value")); }
1502        std::wstring get_value(regkey_container &value) {
1503                return value.info.sValue;
1504        }
1505};
1506struct check_regkey_written : public checkHolders::check_proxy_container<regkey_container, DateTimeContainer> {
1507        check_regkey_written() { set_alias(_T("written")); }
1508        unsigned long long get_value(regkey_container &value) {
1509                return value.ullLastWriteTime;
1510        }
1511};
1512struct check_regkey_type : public checkHolders::check_proxy_container<regkey_container, RegTypeContainer> {
1513        check_regkey_type() { set_alias(_T("type")); }
1514        int get_value(regkey_container &value) {
1515                return value.iType;
1516        }
1517};
1518struct check_regkey_exists : public checkHolders::check_proxy_container<regkey_container, RegExistsContainer> {
1519        check_regkey_exists() { set_alias(_T("exists")); }
1520        int get_value(regkey_container &value) {
1521                return value.uiExists;
1522        }
1523};
1524
1525
1526typedef checkHolders::check_multi_container<regkey_container> check_file_multi;
1527struct check_regkey_factories {
1528        static checkHolders::check_proxy_interface<regkey_container>* type() {
1529                return new check_regkey_type();
1530        }
1531        static checkHolders::check_proxy_interface<regkey_container>* exists() {
1532                return new check_regkey_exists();
1533        }
1534        static checkHolders::check_proxy_interface<regkey_container>* child_count() {
1535                return new check_regkey_child_count();
1536        }
1537        static checkHolders::check_proxy_interface<regkey_container>* written() {
1538                return new check_regkey_written();
1539        }
1540        static checkHolders::check_proxy_interface<regkey_container>* value_string() {
1541                return new check_regkey_string_value();
1542        }
1543        static checkHolders::check_proxy_interface<regkey_container>* value_int() {
1544                return new check_regkey_int_value();
1545        }
1546};
1547
1548#define MAP_FACTORY_PB(value, obj) \
1549                else if ((p__.first == _T("check")) && (p__.second == ##value)) { checker.add_check(check_regkey_factories::obj()); }
1550
1551
1552NSCAPI::nagiosReturn CheckSystem::checkSingleRegEntry(std::list<std::wstring> arguments, std::wstring &message, std::wstring &perf) {
1553        NSCAPI::nagiosReturn returnCode = NSCAPI::returnOK;
1554        check_file_multi checker;
1555        typedef std::pair<int,regkey_filter> filteritem_type;
1556        typedef std::list<filteritem_type > filterlist_type;
1557        if (arguments.empty()) {
1558                message = _T("Missing argument(s).");
1559                return NSCAPI::returnUNKNOWN;
1560        }
1561        std::list<std::wstring> files;
1562        unsigned int truncate = 0;
1563        std::wstring syntax = _T("%filename%");
1564        std::wstring alias;
1565        bool bPerfData = true;
1566
1567        try {
1568                MAP_OPTIONS_BEGIN(arguments)
1569                        MAP_OPTIONS_STR2INT(_T("truncate"), truncate)
1570                        MAP_OPTIONS_BOOL_FALSE(IGNORE_PERFDATA, bPerfData)
1571                        MAP_OPTIONS_STR(_T("syntax"), syntax)
1572                        MAP_OPTIONS_STR(_T("alias"), alias)
1573                        MAP_OPTIONS_PUSH(_T("path"), files)
1574                        MAP_OPTIONS_SHOWALL(checker)
1575                        MAP_OPTIONS_EXACT_NUMERIC_ALL_MULTI(checker, _T(""))
1576                        MAP_FACTORY_PB(_T("type"), type)
1577                        MAP_FACTORY_PB(_T("child-count"), child_count)
1578                        MAP_FACTORY_PB(_T("written"), written)
1579                        MAP_FACTORY_PB(_T("int"), value_int)
1580                        MAP_FACTORY_PB(_T("string"), value_string)
1581                        MAP_OPTIONS_MISSING(message, _T("Unknown argument: "))
1582                        MAP_OPTIONS_END()
1583        } catch (filters::parse_exception e) {
1584                message = e.getMessage();
1585                return NSCAPI::returnUNKNOWN;
1586        } catch (filters::filter_exception e) {
1587                message = e.getMessage();
1588                return NSCAPI::returnUNKNOWN;
1589        }
1590        FILETIME now;
1591        GetSystemTimeAsFileTime(&now);
1592        unsigned __int64 nowi64 = ((now.dwHighDateTime * ((unsigned long long)MAXDWORD+1)) + (unsigned long long)now.dwLowDateTime);
1593        for (std::list<std::wstring>::const_iterator pit = files.begin(); pit != files.end(); ++pit) {
1594                regkey_container info = regkey_container::get(*pit, nowi64);
1595                if (info.has_errors()) {
1596                        message = info.error;
1597                        return NSCAPI::returnUNKNOWN;
1598                }
1599                checker.alias = info.render(syntax);
1600                checker.runCheck(info, returnCode, message, perf);
1601        }
1602        if ((truncate > 0) && (message.length() > (truncate-4))) {
1603                message = message.substr(0, truncate-4) + _T("...");
1604                perf = _T("");
1605        }
1606        if (message.empty())
1607                message = _T("CheckSingleRegkey ok");
1608        return returnCode;
1609}
1610
1611NSC_WRAP_DLL();
1612NSC_WRAPPERS_MAIN_DEF(gCheckSystem);
1613NSC_WRAPPERS_IGNORE_MSG_DEF();
1614NSC_WRAPPERS_HANDLE_CMD_DEF(gCheckSystem);
1615//NSC_WRAPPERS_CLI_DEF(gCheckSystem);
1616
Note: See TracBrowser for help on using the repository browser.