source: nscp/trunk/modules/CheckSystem/CheckSystem.cpp @ ed754fe

Last change on this file since ed754fe was 3527e99, checked in by Michael Medin <michael@…>, 5 years ago

2007-11-28 MickeM

  • Fixed some UNICODE issues with process-listings + Added an error message if the "detected" process enumeration method is not available. + Fixed some more unicode issues Password encrypt/decrypt: #107
  • Fixed unicode issues with "external programs" #109
  • Fixed so default string for check_nt:s FILEAGE command is "delta" is 5 minutes ago (and not absolute ie. 1970...), Issue #39 + added support for <date strings> to check_nt:s FILEAGE command, Issue #39

append: .<date string> if you want to use a "custom date" like so: ... -v FILEAGE -l c:
windows,Date: %Y-%m-%d %H:%M:%S" -w 5 -c 6 ...
Only the above listed %<char> works, and default to 0 so might not be to pretty but works...

  • Property mode set to 100644
File size: 36.8 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
33CheckSystem gCheckSystem;
34
35/**
36 * DLL Entry point
37 * @param hModule
38 * @param ul_reason_for_call
39 * @param lpReserved
40 * @return
41 */
42BOOL APIENTRY DllMain( HANDLE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved)
43{
44        NSCModuleWrapper::wrapDllMain(hModule, ul_reason_for_call);
45        return TRUE;
46}
47
48/**
49 * Default c-tor
50 * @return
51 */
52CheckSystem::CheckSystem() : processMethod_(0), pdhThread(_T("pdhThread")) {}
53/**
54 * Default d-tor
55 * @return
56 */
57CheckSystem::~CheckSystem() {}
58/**
59 * Load (initiate) module.
60 * Start the background collector thread and let it run until unloadModule() is called.
61 * @return true
62 */
63bool CheckSystem::loadModule() {
64        pdhThread.createThread();
65        std::wstring wantedMethod = NSCModuleHelper::getSettingsString(C_SYSTEM_SECTION_TITLE, C_SYSTEM_ENUMPROC_METHOD, C_SYSTEM_ENUMPROC_METHOD_DEFAULT);
66        CEnumProcess tmp;
67        int method = tmp.GetAvailableMethods();
68        if (wantedMethod == C_SYSTEM_ENUMPROC_METHOD_AUTO) {
69                OSVERSIONINFO osVer = systemInfo::getOSVersion();
70                if (systemInfo::isBelowNT4(osVer)) {
71                        NSC_DEBUG_MSG_STD(_T("Autodetected NT4<, using PSAPI process enumeration."));
72                        if (method == (method|ENUM_METHOD::PSAPI)) {
73                                processMethod_ = ENUM_METHOD::PSAPI;
74                        } else {
75                                NSC_LOG_ERROR_STD(_T("PSAPI method not available, since you are on NT4 you need to install \"Platform SDK Redistributable: PSAPI for Windows NT\" from Microsoft."));
76                                NSC_LOG_ERROR_STD(_T("Try this URL: http://www.microsoft.com/downloads/details.aspx?FamilyID=3d1fbaed-d122-45cf-9d46-1cae384097ac"));
77                        }
78                } else if (systemInfo::isAboveW2K(osVer)) {
79                        NSC_DEBUG_MSG_STD(_T("Autodetected W2K>, using TOOLHELP process enumeration."));
80                        if (method == (method|ENUM_METHOD::TOOLHELP)) {
81                                processMethod_ = ENUM_METHOD::TOOLHELP;
82                        } else {
83                                NSC_LOG_ERROR_STD(_T("TOOLHELP was not available, since you are on > W2K you need top manually override the ") C_SYSTEM_ENUMPROC_METHOD _T("option in NSC:ini."));
84                        }
85                } else {
86                        NSC_DEBUG_MSG_STD(_T("Autodetected failed, using PSAPI process enumeration."));
87                        processMethod_ = ENUM_METHOD::PSAPI;
88                        if (method == (method|ENUM_METHOD::PSAPI)) {
89                                processMethod_ = ENUM_METHOD::PSAPI;
90                        } else {
91                                NSC_LOG_ERROR_STD(_T("PSAPI method not availabletry installing \"Platform SDK Redistributable: PSAPI for Windows NT\" from Microsoft."));
92                                NSC_LOG_ERROR_STD(_T("Try this URL: http://www.microsoft.com/downloads/details.aspx?FamilyID=3d1fbaed-d122-45cf-9d46-1cae384097ac"));
93                        }
94                }
95        } else if (wantedMethod == C_SYSTEM_ENUMPROC_METHOD_PSAPI) {
96                NSC_DEBUG_MSG_STD(_T("Using PSAPI method."));
97                if (method == (method|ENUM_METHOD::PSAPI)) {
98                        processMethod_ = ENUM_METHOD::PSAPI;
99                } else {
100                        NSC_LOG_ERROR_STD(_T("PSAPI method not available, check ") C_SYSTEM_ENUMPROC_METHOD _T(" option."));
101                }
102        } else {
103                NSC_DEBUG_MSG_STD(_T("Using TOOLHELP method."));
104                if (method == (method|ENUM_METHOD::TOOLHELP)) {
105                        processMethod_ = ENUM_METHOD::TOOLHELP;
106                } else {
107                        NSC_LOG_ERROR_STD(_T("TOOLHELP method not avalible, check ") C_SYSTEM_ENUMPROC_METHOD _T(" option."));
108                }
109        }
110       
111        return true;
112}
113/**
114 * Unload (terminate) module.
115 * Attempt to stop the background processing thread.
116 * @return true if successfully, false if not (if not things might be bad)
117 */
118bool CheckSystem::unloadModule() {
119        if (!pdhThread.exitThread(20000)) {
120                std::wcout << _T("MAJOR ERROR: Could not unload thread...") << std::endl;
121                NSC_LOG_ERROR(_T("Could not exit the thread, memory leak and potential corruption may be the result..."));
122        }
123        return true;
124}
125/**
126 * Check if we have a command handler.
127 * @return true (as we have a command handler)
128 */
129bool CheckSystem::hasCommandHandler() {
130        return true;
131}
132/**
133 * Check if we have a message handler.
134 * @return false as we have no message handler
135 */
136bool CheckSystem::hasMessageHandler() {
137        return false;
138}
139
140int CheckSystem::commandLineExec(const TCHAR* command,const unsigned int argLen,TCHAR** args) {
141        if (_wcsicmp(command, _T("debugpdh")) == 0) {
142                PDH::Enumerations::Objects lst;
143                try {
144                        lst = PDH::Enumerations::EnumObjects();
145                } catch (const PDH::PDHException e) {
146                        std::wcout << _T("Service enumeration failed: ") << e.getError();
147                        return 0;
148                }
149                for (PDH::Enumerations::Objects::iterator it = lst.begin();it!=lst.end();++it) {
150                        if ((*it).instances.size() > 0) {
151                                for (PDH::Enumerations::Instances::const_iterator it2 = (*it).instances.begin();it2!=(*it).instances.end();++it2) {
152                                        for (PDH::Enumerations::Counters::const_iterator it3 = (*it).counters.begin();it3!=(*it).counters.end();++it3) {
153                                                std::wstring counter = _T("\\") + (*it).name + _T("(") + (*it2).name + _T(")\\") + (*it3).name;
154                                                std::wcout << _T("testing: ") << counter << _T(": ");
155                                                std::list<std::wstring> errors;
156                                                std::list<std::wstring> status;
157                                                std::wstring error;
158                                                bool bStatus = true;
159                                                if (PDH::Enumerations::validate(counter, error)) {
160                                                        status.push_back(_T("open"));
161                                                } else {
162                                                        errors.push_back(_T("NOT found: ") + error);
163                                                        bStatus = false;
164                                                }
165                                                if (bStatus) {
166                                                        PDH::PDHCounter *pCounter = NULL;
167                                                        PDH::PDHQuery pdh;
168                                                        try {
169                                                                PDHCollectors::StaticPDHCounterListener<double, PDH_FMT_DOUBLE> cDouble;
170                                                                pCounter = pdh.addCounter(counter, &cDouble);
171                                                                pdh.open();
172
173                                                                if (pCounter != NULL) {
174                                                                        try {
175                                                                                PDH::PDHCounterInfo info = pCounter->getCounterInfo();
176                                                                                errors.push_back(_T("CounterName: ") + info.szCounterName);
177                                                                                errors.push_back(_T("ExplainText: ") + info.szExplainText);
178                                                                                errors.push_back(_T("FullPath: ") + info.szFullPath);
179                                                                                errors.push_back(_T("InstanceName: ") + info.szInstanceName);
180                                                                                errors.push_back(_T("MachineName: ") + info.szMachineName);
181                                                                                errors.push_back(_T("ObjectName: ") + info.szObjectName);
182                                                                                errors.push_back(_T("ParentInstance: ") + info.szParentInstance);
183                                                                                errors.push_back(_T("Type: ") + strEx::itos(info.dwType));
184                                                                                errors.push_back(_T("Scale: ") + strEx::itos(info.lScale));
185                                                                                errors.push_back(_T("Default Scale: ") + strEx::itos(info.lDefaultScale));
186                                                                                errors.push_back(_T("Status: ") + strEx::itos(info.CStatus));
187                                                                                status.push_back(_T("described"));
188                                                                        } catch (const PDH::PDHException e) {
189                                                                                errors.push_back(_T("Describe failed: ") + e.getError());
190                                                                                bStatus = false;
191                                                                        }
192                                                                }
193
194                                                                pdh.gatherData();
195                                                                pdh.close();
196                                                                status.push_back(_T("queried"));
197                                                        } catch (const PDH::PDHException e) {
198                                                                errors.push_back(_T("Query failed: ") + e.getError());
199                                                                bStatus = false;
200                                                                try {
201                                                                        pdh.gatherData();
202                                                                        pdh.close();
203                                                                        bStatus = true;
204                                                                } catch (const PDH::PDHException e) {
205                                                                        errors.push_back(_T("Query failed (again!): ") + e.getError());
206                                                                }
207                                                        }
208
209                                                }
210                                                if (!bStatus) {
211                                                        std::list<std::wstring>::const_iterator cit = status.begin();
212                                                        for (;cit != status.end(); ++cit) {
213                                                                std::wcout << *cit << _T(", ");
214                                                        }
215                                                        std::wcout << std::endl;
216                                                        std::wcout << _T("  | Log") << std::endl;
217                                                        std::wcout << _T("--+------  --    -") << std::endl;
218                                                        cit = errors.begin();
219                                                        for (;cit != errors.end(); ++cit) {
220                                                                std::wcout << _T("  | ") << *cit << std::endl;
221                                                        }
222                                                } else {
223                                                        std::list<std::wstring>::const_iterator cit = status.begin();
224                                                        for (;cit != status.end(); ++cit) {
225                                                                std::wcout << *cit << _T(", ");;
226                                                        }
227                                                        std::wcout << std::endl;
228                                                }
229                                        }
230                                }
231                        } else {
232                                for (PDH::Enumerations::Counters::const_iterator it2 = (*it).counters.begin();it2!=(*it).counters.end();++it2) {
233                                        std::wstring counter = _T("\\") + (*it).name + _T("\\") + (*it2).name;
234                                        std::wcout << _T("testing: ") << counter << _T(": ");
235                                        std::wstring error;
236                                        if (PDH::Enumerations::validate(counter, error)) {
237                                                std::wcout << _T(" found ");
238                                        } else {
239                                                std::wcout << _T(" *NOT* found (") << error << _T(") ") << std::endl;
240                                                break;
241                                        }
242                                        bool bOpend = false;
243                                        try {
244                                                PDH::PDHQuery pdh;
245                                                PDHCollectors::StaticPDHCounterListener<double, PDH_FMT_DOUBLE> cDouble;
246                                                pdh.addCounter(counter, &cDouble);
247                                                pdh.open();
248                                                pdh.gatherData();
249                                                pdh.close();
250                                                bOpend = true;
251                                        } catch (const PDH::PDHException e) {
252                                                std::wcout << _T(" could *not* be open (") << e.getError() << _T(") ") << std::endl;
253                                                break;
254                                        }
255                                        std::wcout << _T(" open ");
256                                        std::wcout << std::endl;;
257                                }
258                        }
259                }
260        } else if (_wcsicmp(command, _T("listpdh")) == 0) {
261                PDH::Enumerations::Objects lst;
262                try {
263                        lst = PDH::Enumerations::EnumObjects();
264                } catch (const PDH::PDHException e) {
265                        std::wcout << _T("Service enumeration failed: ") << e.getError();
266                        return 0;
267                }
268                for (PDH::Enumerations::Objects::iterator it = lst.begin();it!=lst.end();++it) {
269                        if ((*it).instances.size() > 0) {
270                                for (PDH::Enumerations::Instances::const_iterator it2 = (*it).instances.begin();it2!=(*it).instances.end();++it2) {
271                                        for (PDH::Enumerations::Counters::const_iterator it3 = (*it).counters.begin();it3!=(*it).counters.end();++it3) {
272                                                std::wcout << _T("\\") << (*it).name << _T("(") << (*it2).name << _T(")\\") << (*it3).name << std::endl;;
273                                        }
274                                }
275                        } else {
276                                for (PDH::Enumerations::Counters::const_iterator it2 = (*it).counters.begin();it2!=(*it).counters.end();++it2) {
277                                        std::wcout << _T("\\") << (*it).name << _T("\\") << (*it2).name << std::endl;;
278                                }
279                        }
280                }
281        }
282        return 0;
283}
284
285
286/**
287 * Main command parser and delegator.
288 * This also handles a lot of the simpler responses (though some are deferred to other helper functions)
289 *
290 *
291 * @param command
292 * @param argLen
293 * @param **args
294 * @return
295 */
296NSCAPI::nagiosReturn CheckSystem::handleCommand(const strEx::blindstr command, const unsigned int argLen, TCHAR **char_args, std::wstring &msg, std::wstring &perf) {
297        std::list<std::wstring> stl_args;
298        CheckSystem::returnBundle rb;
299        if (command == _T("checkCPU")) {
300                return checkCPU(argLen, char_args, msg, perf);
301        } else if (command == _T("checkUpTime")) {
302                return checkUpTime(argLen, char_args, msg, perf);
303        } else if (command == _T("checkServiceState")) {
304                return checkServiceState(argLen, char_args, msg, perf);
305        } else if (command == _T("checkProcState")) {
306                return checkProcState(argLen, char_args, msg, perf);
307        } else if (command == _T("checkMem")) {
308                return checkMem(argLen, char_args, msg, perf);
309        } else if (command == _T("checkCounter")) {
310                return checkCounter(argLen, char_args, msg, perf);
311        }
312        return NSCAPI::returnIgnored;
313}
314
315
316class cpuload_handler {
317public:
318        static int parse(std::wstring s) {
319                return strEx::stoi(s);
320        }
321        static int parse_percent(std::wstring s) {
322                return strEx::stoi(s);
323        }
324        static std::wstring print(int value) {
325                return strEx::itos(value) + _T("%");
326        }
327        static std::wstring print_unformated(int value) {
328                return strEx::itos(value);
329        }
330        static std::wstring print_perf(int value) {
331                return strEx::itos(value);
332        }
333        static std::wstring print_percent(int value) {
334                return strEx::itos(value) + _T("%");
335        }
336        static std::wstring key_prefix() {
337                return _T("average load ");
338        }
339        static std::wstring key_postfix() {
340                return _T("");
341        }
342};
343NSCAPI::nagiosReturn CheckSystem::checkCPU(const unsigned int argLen, TCHAR **char_args, std::wstring &msg, std::wstring &perf)
344{
345        typedef checkHolders::CheckConatiner<checkHolders::MaxMinBounds<checkHolders::NumericBounds<int, cpuload_handler> > > CPULoadConatiner;
346
347        std::list<std::wstring> stl_args = arrayBuffer::arrayBuffer2list(argLen, char_args);
348        if (stl_args.empty()) {
349                msg = _T("ERROR: Missing argument exception.");
350                return NSCAPI::returnUNKNOWN;
351        }
352        std::list<CPULoadConatiner> list;
353        NSCAPI::nagiosReturn returnCode = NSCAPI::returnOK;
354        bool bNSClient = false;
355        bool bPerfData = true;
356        CPULoadConatiner tmpObject;
357
358        tmpObject.data = _T("cpuload");
359
360        MAP_OPTIONS_BEGIN(stl_args)
361                MAP_OPTIONS_NUMERIC_ALL(tmpObject, _T(""))
362                MAP_OPTIONS_STR(_T("warn"), tmpObject.warn.max)
363                MAP_OPTIONS_STR(_T("crit"), tmpObject.crit.max)
364                MAP_OPTIONS_BOOL_FALSE(IGNORE_PERFDATA, bPerfData)
365                MAP_OPTIONS_STR_AND(_T("time"), tmpObject.data, list.push_back(tmpObject))
366                MAP_OPTIONS_STR_AND(_T("Time"), tmpObject.data, list.push_back(tmpObject))
367                MAP_OPTIONS_SHOWALL(tmpObject)
368                MAP_OPTIONS_BOOL_TRUE(NSCLIENT, bNSClient)
369                MAP_OPTIONS_SECONDARY_BEGIN(_T(":"), p2)
370                        else if (p2.first == _T("Time")) {
371                                tmpObject.data = p__.second;
372                                tmpObject.alias = p2.second;
373                                list.push_back(tmpObject);
374                        }
375        MAP_OPTIONS_MISSING_EX(p2, msg, _T("Unknown argument: "))
376                MAP_OPTIONS_SECONDARY_END()
377                MAP_OPTIONS_FALLBACK_AND(tmpObject.data, list.push_back(tmpObject))
378        MAP_OPTIONS_END()
379
380        for (std::list<CPULoadConatiner>::const_iterator it = list.begin(); it != list.end(); ++it) {
381                CPULoadConatiner load = (*it);
382                PDHCollector *pObject = pdhThread.getThread();
383                if (!pObject) {
384                        msg = _T("ERROR: PDH Collection thread not running.");
385                        return NSCAPI::returnUNKNOWN;
386                }
387                int value = pObject->getCPUAvrage(load.data + _T("m"));
388                if (value == -1) {
389                        msg = _T("ERROR: We don't collect data this far back: ") + load.getAlias();
390                        return NSCAPI::returnUNKNOWN;
391                }
392                if (bNSClient) {
393                        if (!msg.empty()) msg += _T("&");
394                        msg += strEx::itos(value);
395                } else {
396                        load.setDefault(tmpObject);
397                        load.perfData = bPerfData;
398                        load.runCheck(value, returnCode, msg, perf);
399                }
400        }
401
402        if (msg.empty())
403                msg = _T("OK CPU Load ok.");
404        else if (!bNSClient)
405                msg = NSCHelper::translateReturn(returnCode) + _T(": ") + msg;
406        return returnCode;
407}
408
409NSCAPI::nagiosReturn CheckSystem::checkUpTime(const unsigned int argLen, TCHAR **char_args, std::wstring &msg, std::wstring &perf)
410{
411        typedef checkHolders::CheckConatiner<checkHolders::MaxMinBoundsTime> UpTimeConatiner;
412
413        std::list<std::wstring> stl_args = arrayBuffer::arrayBuffer2list(argLen, char_args);
414        if (stl_args.empty()) {
415                msg = _T("ERROR: Missing argument exception.");
416                return NSCAPI::returnUNKNOWN;
417        }
418        NSCAPI::nagiosReturn returnCode = NSCAPI::returnOK;
419        bool bNSClient = false;
420        bool bPerfData = true;
421        UpTimeConatiner bounds;
422
423        bounds.data = _T("uptime");
424
425        MAP_OPTIONS_BEGIN(stl_args)
426                MAP_OPTIONS_NUMERIC_ALL(bounds, _T(""))
427                MAP_OPTIONS_STR(_T("warn"), bounds.warn.min)
428                MAP_OPTIONS_STR(_T("crit"), bounds.crit.min)
429                MAP_OPTIONS_BOOL_FALSE(IGNORE_PERFDATA, bPerfData)
430                MAP_OPTIONS_STR(_T("Alias"), bounds.data)
431                MAP_OPTIONS_SHOWALL(bounds)
432                MAP_OPTIONS_BOOL_TRUE(NSCLIENT, bNSClient)
433                MAP_OPTIONS_MISSING(msg, _T("Unknown argument: "))
434                MAP_OPTIONS_END()
435
436
437        PDHCollector *pObject = pdhThread.getThread();
438        if (!pObject) {
439                msg = _T("ERROR: PDH Collection thread not running.");
440                return NSCAPI::returnUNKNOWN;
441        }
442        unsigned long long value = pObject->getUptime();
443        if (bNSClient) {
444                msg = strEx::itos(value);
445        } else {
446                value *= 1000;
447                bounds.perfData = bPerfData;
448                bounds.runCheck(value, returnCode, msg, perf);
449        }
450
451        if (msg.empty())
452                msg = _T("OK all counters within bounds.");
453        else if (!bNSClient)
454                msg = NSCHelper::translateReturn(returnCode) + _T(": ") + msg;
455        return returnCode;
456}
457
458// @todo state_handler
459
460
461
462/**
463 * Retrieve the service state of one or more services (by name).
464 * Parse a list with a service names and verify that all named services are running.
465 * <pre>
466 * Syntax:
467 * request: checkServiceState <option> [<option> [...]]
468 * Return: <return state>&<service1> : <state1> - <service2> : <state2> - ...
469 * Available options:
470 *              <name>=<state>  Check if a service has a specific state
471 *                      State can be wither started or stopped
472 *              ShowAll                 Show the state of all listed service. If not set only critical services are listed.
473 * Examples:
474 * checkServiceState showAll myService MyService
475 *</pre>
476 *
477 * @param command Command to execute
478 * @param argLen The length of the argument buffer
479 * @param **char_args The argument buffer
480 * @param &msg String to put message in
481 * @param &perf String to put performance data in
482 * @return The status of the command
483 */
484NSCAPI::nagiosReturn CheckSystem::checkServiceState(const unsigned int argLen, TCHAR **char_args, std::wstring &msg, std::wstring &perf)
485{
486        typedef checkHolders::CheckConatiner<checkHolders::SimpleBoundsStateBoundsInteger> StateConatiner;
487        std::list<std::wstring> stl_args = arrayBuffer::arrayBuffer2list(argLen, char_args);
488        if (stl_args.empty()) {
489                msg = _T("ERROR: Missing argument exception.");
490                return NSCAPI::returnUNKNOWN;
491        }
492        std::list<StateConatiner> list;
493        std::set<std::wstring> excludeList;
494        NSCAPI::nagiosReturn returnCode = NSCAPI::returnOK;
495        bool bNSClient = false;
496        StateConatiner tmpObject;
497        bool bPerfData = true;
498        bool bAutoStart = false;
499
500        tmpObject.data = _T("service");
501        tmpObject.crit.state = _T("started");
502        //{{
503        MAP_OPTIONS_BEGIN(stl_args)
504                MAP_OPTIONS_SHOWALL(tmpObject)
505                MAP_OPTIONS_STR(_T("Alias"), tmpObject.data)
506                MAP_OPTIONS_BOOL_FALSE(IGNORE_PERFDATA, bPerfData)
507                MAP_OPTIONS_BOOL_TRUE(NSCLIENT, bNSClient)
508                MAP_OPTIONS_BOOL_TRUE(_T("CheckAll"), bAutoStart)
509                MAP_OPTIONS_INSERT(_T("exclude"), excludeList)
510                MAP_OPTIONS_SECONDARY_BEGIN(_T(":"), p2)
511                MAP_OPTIONS_MISSING_EX(p2, msg, _T("Unknown argument: "))
512                MAP_OPTIONS_SECONDARY_END()
513                else {
514                        tmpObject.data = p__.first;
515                        if (p__.second.empty())
516                                tmpObject.crit.state = _T("started");
517                        else
518                                tmpObject.crit.state = p__.second;
519                        list.push_back(tmpObject);
520                }
521        MAP_OPTIONS_END()
522        //}}
523        if (bAutoStart) {
524                // get a list of all service with startup type Automatic
525                /*
526                ;check_all_services[SERVICE_BOOT_START]=ignored
527                ;check_all_services[SERVICE_SYSTEM_START]=ignored
528                ;check_all_services[SERVICE_AUTO_START]=started
529                ;check_all_services[SERVICE_DEMAND_START]=ignored
530                ;check_all_services[SERVICE_DISABLED]=stopped
531                std::wstring wantedMethod = NSCModuleHelper::getSettingsString(C_SYSTEM_SECTION_TITLE, C_SYSTEM_ENUMPROC_METHOD, C_SYSTEM_ENUMPROC_METHOD_DEFAULT);
532                */
533                std::map<DWORD,std::wstring> lookups;
534                lookups[SERVICE_BOOT_START] = NSCModuleHelper::getSettingsString(C_SYSTEM_SECTION_TITLE, C_SYSTEM_SVC_ALL_0, C_SYSTEM_SVC_ALL_0_DEFAULT);
535                lookups[SERVICE_SYSTEM_START] = NSCModuleHelper::getSettingsString(C_SYSTEM_SECTION_TITLE, C_SYSTEM_SVC_ALL_1, C_SYSTEM_SVC_ALL_1_DEFAULT);
536                lookups[SERVICE_AUTO_START] = NSCModuleHelper::getSettingsString(C_SYSTEM_SECTION_TITLE, C_SYSTEM_SVC_ALL_2, C_SYSTEM_SVC_ALL_2_DEFAULT);
537                lookups[SERVICE_DEMAND_START] = NSCModuleHelper::getSettingsString(C_SYSTEM_SECTION_TITLE, C_SYSTEM_SVC_ALL_3, C_SYSTEM_SVC_ALL_3_DEFAULT);
538                lookups[SERVICE_DISABLED] = NSCModuleHelper::getSettingsString(C_SYSTEM_SECTION_TITLE, C_SYSTEM_SVC_ALL_4, C_SYSTEM_SVC_ALL_4_DEFAULT);
539
540
541                std::list<TNtServiceInfo> service_list_automatic;
542                TNtServiceInfo::EnumServices(SERVICE_WIN32,SERVICE_INACTIVE|SERVICE_ACTIVE,&service_list_automatic);
543                for (std::list<TNtServiceInfo>::const_iterator service =service_list_automatic.begin();service!=service_list_automatic.end();++service) {
544                        if (excludeList.find((*service).m_strServiceName) == excludeList.end()) {
545                                tmpObject.data = (*service).m_strServiceName;
546                                tmpObject.crit.state = lookups[(*service).m_dwStartType];
547                                list.push_back(tmpObject);
548                        }
549                }
550        }
551        for (std::list<StateConatiner>::iterator it = list.begin(); it != list.end(); ++it) {
552                TNtServiceInfo info;
553                if (bNSClient) {
554                        try {
555                                info = TNtServiceInfo::GetService((*it).data.c_str());
556                        } catch (NTServiceException e) {
557                                if (!msg.empty()) msg += _T(" - ");
558                                msg += (*it).data + _T(": Unknown");
559                                NSCHelper::escalteReturnCodeToWARN(returnCode);
560                                continue;
561                        }
562                        if ((info.m_dwCurrentState == SERVICE_RUNNING) && (*it).showAll()) {
563                                if (!msg.empty()) msg += _T(" - ");
564                                msg += (*it).data + _T(": Started");
565                        } else if (info.m_dwCurrentState == SERVICE_RUNNING) {
566                        } else if (info.m_dwCurrentState == SERVICE_STOPPED) {
567                                if (!msg.empty()) msg += _T(" - ");
568                                msg += (*it).data + _T(": Stopped");
569                                NSCHelper::escalteReturnCodeToCRIT(returnCode);
570                        } else {
571                                if (!msg.empty()) msg += _T(" - ");
572                                msg += (*it).data + _T(": Unknown");
573                                NSCHelper::escalteReturnCodeToWARN(returnCode);
574                        }
575                } else {
576                        try {
577                                info = TNtServiceInfo::GetService((*it).data.c_str());
578                        } catch (NTServiceException e) {
579                                NSC_LOG_ERROR_STD(e.getError());
580                                msg = e.getError();
581                                return NSCAPI::returnUNKNOWN;
582                        }
583                        checkHolders::state_type value;
584                        if (info.m_dwCurrentState == SERVICE_RUNNING)
585                                value = checkHolders::state_started;
586                        else if (info.m_dwCurrentState == SERVICE_STOPPED)
587                                value = checkHolders::state_stopped;
588                        else
589                                value = checkHolders::state_none;
590                        (*it).perfData = bPerfData;
591                        (*it).runCheck(value, returnCode, msg, perf);
592                }
593
594        }
595        if (msg.empty())
596                msg = _T("OK: All services are running.");
597        else if (!bNSClient)
598                msg = NSCHelper::translateReturn(returnCode) + _T(": ") + msg;
599        return returnCode;
600}
601
602/**
603 * Check available memory and return various check results
604 * Example: checkMem showAll maxWarn=50 maxCrit=75
605 *
606 * @param command Command to execute
607 * @param argLen The length of the argument buffer
608 * @param **char_args The argument buffer
609 * @param &msg String to put message in
610 * @param &perf String to put performance data in
611 * @return The status of the command
612 */
613NSCAPI::nagiosReturn CheckSystem::checkMem(const unsigned int argLen, TCHAR **char_args, std::wstring &msg, std::wstring &perf)
614{
615        typedef checkHolders::CheckConatiner<checkHolders::MaxMinBounds<checkHolders::NumericPercentageBounds<checkHolders::PercentageValueType<unsigned __int64, unsigned __int64>, checkHolders::disk_size_handler<unsigned __int64> > > > MemoryConatiner;
616        std::list<std::wstring> stl_args = arrayBuffer::arrayBuffer2list(argLen, char_args);
617        if (stl_args.empty()) {
618                msg = _T("ERROR: Missing argument exception.");
619                return NSCAPI::returnUNKNOWN;
620        }
621        std::list<MemoryConatiner> list;
622        NSCAPI::nagiosReturn returnCode = NSCAPI::returnOK;
623        bool bShowAll = false;
624        bool bPerfData = true;
625        bool bNSClient = false;
626        MemoryConatiner tmpObject;
627
628        MAP_OPTIONS_BEGIN(stl_args)
629                MAP_OPTIONS_SHOWALL(tmpObject)
630                MAP_OPTIONS_STR_AND(_T("type"), tmpObject.data, list.push_back(tmpObject))
631                MAP_OPTIONS_STR_AND(_T("Type"), tmpObject.data, list.push_back(tmpObject))
632                MAP_OPTIONS_SECONDARY_BEGIN(_T(":"), p2)
633                MAP_OPTIONS_SECONDARY_STR_AND(p2,_T("type"), tmpObject.data, tmpObject.alias, list.push_back(tmpObject))
634                        MAP_OPTIONS_MISSING_EX(p2, msg, _T("Unknown argument: "))
635                        MAP_OPTIONS_SECONDARY_END()
636                MAP_OPTIONS_BOOL_FALSE(IGNORE_PERFDATA, bPerfData)
637                MAP_OPTIONS_BOOL_TRUE(NSCLIENT, bNSClient)
638                MAP_OPTIONS_DISK_ALL(tmpObject, _T(""), _T("Free"), _T("Used"))
639                MAP_OPTIONS_STR(_T("Alias"), tmpObject.data)
640                MAP_OPTIONS_SHOWALL(tmpObject)
641                MAP_OPTIONS_MISSING(msg, _T("Unknown argument: "))
642                MAP_OPTIONS_END()
643
644        if (bNSClient) {
645                tmpObject.data = _T("paged");
646                list.push_back(tmpObject);
647        }
648
649        checkHolders::PercentageValueType<unsigned long long, unsigned long long> dataPaged;
650        CheckMemory::memData data;
651        bool firstPaged = true;
652        bool firstMem = true;
653        for (std::list<MemoryConatiner>::const_iterator pit = list.begin(); pit != list.end(); ++pit) {
654                MemoryConatiner check = (*pit);
655                check.setDefault(tmpObject);
656                checkHolders::PercentageValueType<unsigned long long, unsigned long long> value;
657                if (firstPaged && (check.data == _T("paged"))) {
658                        firstPaged = false;
659                        PDHCollector *pObject = pdhThread.getThread();
660                        if (!pObject) {
661                                msg = _T("ERROR: PDH Collection thread not running.");
662                                return NSCAPI::returnUNKNOWN;
663                        }
664                        dataPaged.value = pObject->getMemCommit();
665                        dataPaged.total = pObject->getMemCommitLimit();
666                } else if (firstMem) {
667                        try {
668                                data = memoryChecker.getMemoryStatus();
669                        } catch (CheckMemoryException e) {
670                                msg = e.getError();
671                                return NSCAPI::returnCRIT;
672                        }
673                }
674
675                if (check.data == _T("page")) {
676                        value.value = data.pageFile.total-data.pageFile.avail; // mem.dwTotalPageFile-mem.dwAvailPageFile;
677                        value.total = data.pageFile.total; //mem.dwTotalPageFile;
678                        if (check.alias.empty())
679                                check.alias = _T("page file");
680                } else if (check.data == _T("physical")) {
681                        value.value = data.phys.total-data.phys.avail; //mem.dwTotalPhys-mem.dwAvailPhys;
682                        value.total = data.phys.total; //mem.dwTotalPhys;
683                        if (check.alias.empty())
684                                check.alias = _T("physical memory");
685                } else if (check.data == _T("virtual")) {
686                        value.value = data.virtualMem.total-data.virtualMem.avail;//mem.dwTotalVirtual-mem.dwAvailVirtual;
687                        value.total = data.virtualMem.total;//mem.dwTotalVirtual;
688                        if (check.alias.empty())
689                                check.alias = _T("virtual memory");
690                } else  if (check.data == _T("paged")) {
691                        value.value = dataPaged.value;
692                        value.total = dataPaged.total;
693                        if (check.alias.empty())
694                                check.alias = _T("paged bytes");
695                } else {
696                        msg = check.data + _T(" is not a known check...");
697                        return NSCAPI::returnCRIT;
698                }
699                if (bNSClient) {
700                        msg = strEx::itos(value.total) + _T("&") + strEx::itos(value.value);
701                        return NSCAPI::returnOK;
702                } else {
703                        check.perfData = bPerfData;
704                        check.runCheck(value, returnCode, msg, perf);
705                }
706        }
707        NSC_DEBUG_MSG_STD(_T("Perf data: ") + strEx::itos(bPerfData) + _T(":") + perf);
708
709        if (msg.empty())
710                msg = _T("OK memory within bounds.");
711        else
712                msg = NSCHelper::translateReturn(returnCode) + _T(": ") + msg;
713        return returnCode;
714}
715typedef struct NSPROCDATA__ {
716        NSPROCDATA__() : count(0) {}
717        NSPROCDATA__(const NSPROCDATA__ &other) {
718                count = other.count;
719                entry = other.entry;
720        }
721
722        unsigned int count;
723        CEnumProcess::CProcessEntry entry;
724} NSPROCDATA;
725typedef std::map<std::wstring,NSPROCDATA,strEx::case_blind_string_compare> NSPROCLST;
726/**
727* Get a hash_map with all running processes.
728* @return a hash_map with all running processes
729*/
730NSPROCLST GetProcessList(int processMethod)
731{
732        NSPROCLST ret;
733        if (processMethod == 0) {
734                NSC_LOG_ERROR_STD(_T("ProcessMethod not defined or not available."));
735                return ret;
736        }
737        CEnumProcess enumeration;
738        if (enumeration.SetMethod(processMethod) != processMethod) {
739                NSC_LOG_ERROR_STD(_T("Failed to set process enumeration method"));
740                return ret;
741        }
742        CEnumProcess::CProcessEntry entry;
743        for (BOOL OK = enumeration.GetProcessFirst(&entry); OK; OK = enumeration.GetProcessNext(&entry) ) {
744                NSPROCLST::iterator it = ret.find(entry.sFilename);
745                if (it == ret.end()) {
746                        ret[entry.sFilename].entry = entry;
747                        ret[entry.sFilename].count = 1;
748                } else
749                        (*it).second.count++;
750        }
751        return ret;
752}
753
754/**
755 * Check process state and return result
756 *
757 * @param command Command to execute
758 * @param argLen The length of the argument buffer
759 * @param **char_args The argument buffer
760 * @param &msg String to put message in
761 * @param &perf String to put performance data in
762 * @return The status of the command
763 */
764NSCAPI::nagiosReturn CheckSystem::checkProcState(const unsigned int argLen, TCHAR **char_args, std::wstring &msg, std::wstring &perf)
765{
766        typedef checkHolders::CheckConatiner<checkHolders::MaxMinStateBoundsStateBoundsInteger> StateConatiner;
767        std::list<std::wstring> stl_args = arrayBuffer::arrayBuffer2list(argLen, char_args);
768        if (stl_args.empty()) {
769                msg = _T("ERROR: Missing argument exception.");
770                return NSCAPI::returnUNKNOWN;
771        }
772        std::list<StateConatiner> list;
773        NSCAPI::nagiosReturn returnCode = NSCAPI::returnOK;
774        bool bNSClient = false;
775        StateConatiner tmpObject;
776        bool bPerfData = true;
777
778        tmpObject.data = _T("uptime");
779        tmpObject.crit.state = _T("started");
780
781        MAP_OPTIONS_BEGIN(stl_args)
782                MAP_OPTIONS_NUMERIC_ALL(tmpObject, _T("Count"))
783                MAP_OPTIONS_STR(_T("Alias"), tmpObject.alias)
784                MAP_OPTIONS_SHOWALL(tmpObject)
785                MAP_OPTIONS_BOOL_FALSE(IGNORE_PERFDATA, bPerfData)
786                MAP_OPTIONS_BOOL_TRUE(NSCLIENT, bNSClient)
787                MAP_OPTIONS_SECONDARY_BEGIN(_T(":"), p2)
788        else if (p2.first == _T("Proc")) {
789                        tmpObject.data = p__.second;
790                        tmpObject.alias = p2.second;
791                        list.push_back(tmpObject);
792                }
793        MAP_OPTIONS_MISSING_EX(p2, msg, _T("Unknown argument: "))
794                MAP_OPTIONS_SECONDARY_END()
795                else {
796                        tmpObject.data = p__.first;
797                        if (p__.second.empty())
798                                tmpObject.crit.state = _T("started");
799                        else
800                                tmpObject.crit.state = p__.second;
801                        list.push_back(tmpObject);
802                }
803        MAP_OPTIONS_END()
804
805
806        NSPROCLST runningProcs;
807        try {
808                runningProcs = GetProcessList(processMethod_);
809        } catch (TCHAR *c) {
810                NSC_LOG_ERROR_STD(_T("ERROR: ") + c);
811                msg = static_cast<std::wstring>(_T("ERROR: ")) + c;
812                return NSCAPI::returnUNKNOWN;
813        }
814
815        for (std::list<StateConatiner>::iterator it = list.begin(); it != list.end(); ++it) {
816                NSPROCLST::iterator proc = runningProcs.find((*it).data);
817                bool bFound = (proc != runningProcs.end());
818                std::wstring tmp;
819                TNtServiceInfo info;
820                if (bNSClient) {
821                        if (bFound && (*it).showAll()) {
822                                if (!msg.empty()) msg += _T(" - ");
823                                msg += (*it).data + _T(": Running");
824                        } else if (bFound) {
825                        } else {
826                                if (!msg.empty()) msg += _T(" - ");
827                                msg += (*it).data + _T(": not running");
828                                NSCHelper::escalteReturnCodeToCRIT(returnCode);
829                        }
830                } else {
831                        checkHolders::MaxMinStateValueType<int, checkHolders::state_type> value;
832                        if (bFound) {
833                                value.count = (*proc).second.count;
834                                value.state = checkHolders::state_started;
835                        } else {
836                                value.count = 0;
837                                value.state = checkHolders::state_stopped;
838                        }
839                        (*it).perfData = bPerfData;
840                        (*it).runCheck(value, returnCode, msg, perf);
841                }
842
843        }
844        if (msg.empty())
845                msg = _T("OK: All processes are running.");
846        else if (!bNSClient)
847                msg = NSCHelper::translateReturn(returnCode) + _T(": ") + msg;
848        return returnCode;
849}
850
851
852/**
853 * Check a counter and return the value
854 *
855 * @param command Command to execute
856 * @param argLen The length of the argument buffer
857 * @param **char_args The argument buffer
858 * @param &msg String to put message in
859 * @param &perf String to put performance data in
860 * @return The status of the command
861 *
862 * @todo add parsing support for NRPE
863 */
864NSCAPI::nagiosReturn CheckSystem::checkCounter(const unsigned int argLen, TCHAR **char_args, std::wstring &msg, std::wstring &perf)
865{
866        typedef checkHolders::CheckConatiner<checkHolders::MaxMinBoundsDouble> CounterConatiner;
867
868        std::list<std::wstring> stl_args = arrayBuffer::arrayBuffer2list(argLen, char_args);
869        if (stl_args.empty()) {
870                msg = _T("ERROR: Missing argument exception.");
871                return NSCAPI::returnUNKNOWN;
872        }
873        std::list<CounterConatiner> counters;
874        NSCAPI::nagiosReturn returnCode = NSCAPI::returnOK;
875        bool bNSClient = false;
876        bool bPerfData = true;
877        /* average maax */
878        bool bCheckAverages = true;
879        unsigned int averageDelay = 1000;
880        CounterConatiner tmpObject;
881
882        MAP_OPTIONS_BEGIN(stl_args)
883                MAP_OPTIONS_STR_AND(_T("Counter"), tmpObject.data, counters.push_back(tmpObject))
884                MAP_OPTIONS_STR(_T("MaxWarn"), tmpObject.warn.max)
885                MAP_OPTIONS_STR(_T("MinWarn"), tmpObject.warn.min)
886                MAP_OPTIONS_STR(_T("MaxCrit"), tmpObject.crit.max)
887                MAP_OPTIONS_STR(_T("MinCrit"), tmpObject.crit.min)
888                MAP_OPTIONS_BOOL_FALSE(IGNORE_PERFDATA, bPerfData)
889                MAP_OPTIONS_STR(_T("Alias"), tmpObject.data)
890                MAP_OPTIONS_SHOWALL(tmpObject)
891                MAP_OPTIONS_BOOL_EX(_T("Averages"), bCheckAverages, _T("true"), _T("false"))
892                MAP_OPTIONS_BOOL_TRUE(NSCLIENT, bNSClient)
893                MAP_OPTIONS_FIRST_CHAR('\\', tmpObject.data, counters.push_back(tmpObject))
894                MAP_OPTIONS_SECONDARY_BEGIN(_T(":"), p2)
895        else if (p2.first == _T("Counter")) {
896                tmpObject.data = p__.second;
897                                tmpObject.alias = p2.second;
898                                counters.push_back(tmpObject);
899                        }
900        MAP_OPTIONS_MISSING_EX(p2, msg, _T("Unknown argument: "))
901                MAP_OPTIONS_SECONDARY_END()
902                MAP_OPTIONS_FALLBACK_AND(tmpObject.data, counters.push_back(tmpObject))
903        MAP_OPTIONS_END()
904        for (std::list<CounterConatiner>::const_iterator cit = counters.begin(); cit != counters.end(); ++cit) {
905                CounterConatiner counter = (*cit);
906                try {
907                        std::wstring tstr;
908                        if (!PDH::Enumerations::validate(counter.data, tstr)) {
909                                msg = tstr;
910                                msg += _T(" (") + counter.getAlias() + _T("|") + counter.data + _T(")");
911                                return NSCAPI::returnUNKNOWN;
912                        }
913                        PDH::PDHQuery pdh;
914                        PDHCollectors::StaticPDHCounterListener<double, PDH_FMT_DOUBLE> cDouble;
915                        pdh.addCounter(counter.data, &cDouble);
916                        pdh.open();
917                        if (bCheckAverages) {
918                                pdh.collect();
919                                Sleep(1000);
920                        }
921                        pdh.gatherData();
922                        pdh.close();
923                        double value = cDouble.getValue();
924                        if (bNSClient) {
925                                msg += strEx::itos(static_cast<float>(value));
926                        } else {
927                                counter.perfData = bPerfData;
928                                counter.setDefault(tmpObject);
929                                counter.runCheck(value, returnCode, msg, perf);
930                        }
931                } catch (const PDH::PDHException e) {
932                        NSC_LOG_ERROR_STD(_T("ERROR: ") + e.getError() + _T(" (") + counter.getAlias() + _T("|") + counter.data + _T(")"));
933                        msg = static_cast<std::wstring>(_T("ERROR: ")) + e.getError()+ _T(" (") + counter.getAlias() + _T("|") + counter.data + _T(")");
934                        return NSCAPI::returnUNKNOWN;
935                }
936        }
937
938        if (msg.empty())
939                msg = _T("OK all counters within bounds.");
940        else if (!bNSClient)
941                msg = NSCHelper::translateReturn(returnCode) + _T(": ") + msg;
942        return returnCode;
943}
944NSC_WRAPPERS_MAIN_DEF(gCheckSystem);
945NSC_WRAPPERS_IGNORE_MSG_DEF();
946NSC_WRAPPERS_HANDLE_CMD_DEF(gCheckSystem);
947NSC_WRAPPERS_HANDLE_CONFIGURATION(gCheckSystem);
948NSC_WRAPPERS_CLI_DEF(gCheckSystem);
949
950
951
952MODULE_SETTINGS_START(CheckSystem, _T("System check module"), _T("..."))
953
954PAGE(_T("Check options"))
955
956ITEM_EDIT_TEXT(_T("Check resolution"), _T("This is how often the PDH data is polled and stored in the CPU buffer. (this is enterd in 1/th: of a second)"))
957OPTION(_T("unit"), _T("1/10:th of a second"))
958ITEM_MAP_TO(_T("basic_ini_text_mapper"))
959OPTION(_T("section"), _T("Check System"))
960OPTION(_T("key"), _T("CheckResolution"))
961OPTION(_T("default"), _T("10"))
962ITEM_END()
963
964ITEM_EDIT_TEXT(_T("CPU buffer size"), _T("This is the size of the buffer that stores CPU history."))
965ITEM_MAP_TO(_T("basic_ini_text_mapper"))
966OPTION(_T("section"), _T("Check System"))
967OPTION(_T("key"), _T("CPUBufferSize"))
968OPTION(_T("default"), _T("1h"))
969ITEM_END()
970
971PAGE_END()
972ADVANCED_PAGE(_T("Compatiblity settings"))
973
974ITEM_EDIT_TEXT(_T("MemoryCommitByte"), _T("The memory commited bytes used to calculate the avalible memory."))
975OPTION(_T("disableCaption"), _T("Attempt to autodetect this."))
976OPTION(_T("disabled"), _T("auto"))
977ITEM_MAP_TO(_T("basic_ini_text_mapper"))
978OPTION(_T("section"), _T("Check System"))
979OPTION(_T("key"), _T("MemoryCommitByte"))
980OPTION(_T("default"), _T("auto"))
981ITEM_END()
982
983ITEM_EDIT_TEXT(_T("MemoryCommitLimit"), _T("The memory commit limit used to calculate the avalible memory."))
984OPTION(_T("disableCaption"), _T("Attempt to autodetect this."))
985OPTION(_T("disabled"), _T("auto"))
986ITEM_MAP_TO(_T("basic_ini_text_mapper"))
987OPTION(_T("section"), _T("Check System"))
988OPTION(_T("key"), _T("MemoryCommitLimit"))
989OPTION(_T("default"), _T("auto"))
990ITEM_END()
991
992ITEM_EDIT_TEXT(_T("SystemSystemUpTime"), _T("The PDH counter for the System uptime."))
993OPTION(_T("disableCaption"), _T("Attempt to autodetect this."))
994OPTION(_T("disabled"), _T("auto"))
995ITEM_MAP_TO(_T("basic_ini_text_mapper"))
996OPTION(_T("section"), _T("Check System"))
997OPTION(_T("key"), _T("SystemSystemUpTime"))
998OPTION(_T("default"), _T("auto"))
999ITEM_END()
1000
1001ITEM_EDIT_TEXT(_T("SystemTotalProcessorTime"), _T("The PDH conter usaed to measure CPU load."))
1002OPTION(_T("disableCaption"), _T("Attempt to autodetect this."))
1003OPTION(_T("disabled"), _T("auto"))
1004ITEM_MAP_TO(_T("basic_ini_text_mapper"))
1005OPTION(_T("section"), _T("Check System"))
1006OPTION(_T("key"), _T("SystemTotalProcessorTime"))
1007OPTION(_T("default"), _T("auto"))
1008ITEM_END()
1009
1010ITEM_EDIT_TEXT(_T("ProcessEnumerationMethod"), _T("The method to use when enumerating processes"))
1011OPTION(_T("count"), _T("3"))
1012OPTION(_T("caption_1"), _T("Autodetect (TOOLHELP for NT/4 and PSAPI for W2k)"))
1013OPTION(_T("value_1"), _T("auto"))
1014OPTION(_T("caption_2"), _T("TOOLHELP use this for NT/4 systems"))
1015OPTION(_T("value_2"), _T("TOOLHELP"))
1016OPTION(_T("caption_3"), _T("PSAPI use this for W2k (and abowe) systems"))
1017OPTION(_T("value_3"), _T("PSAPI"))
1018ITEM_MAP_TO(_T("basic_ini_text_mapper"))
1019OPTION(_T("section"), _T("Check System"))
1020OPTION(_T("key"), _T("ProcessEnumerationMethod"))
1021OPTION(_T("default"), _T("auto"))
1022ITEM_END()
1023
1024PAGE_END()
1025MODULE_SETTINGS_END()
Note: See TracBrowser for help on using the repository browser.