source: nscp/modules/CheckWMI/WMIQuery.h @ 3692371

0.4.00.4.10.4.2stable
Last change on this file since 3692371 was 7221dc8, checked in by Michael Medin <michael@…>, 5 years ago

2008-09-09 MickeM

  • Improved error handling for the WMI checks. + CheckWMI: Added support for extracting numbers from strings
  • Fixed performance data for "large float values" to be rendered without scientific notation. (#151)
  • Property mode set to 100644
File size: 6.2 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#pragma once
22
23#include <string>
24#include <map>
25#include <strEx.h>
26#include <error.hpp>
27#include <filter_framework.hpp>
28#include <WbemCli.h>
29
30class ComError {
31public:
32        static std::wstring getWMIError(HRESULT hres) {
33                switch (hres) {
34                        case WBEM_E_ACCESS_DENIED:
35                                return _T("The current user does not have permission to view the result set.");
36                        case WBEM_E_FAILED:
37                                return _T("This indicates other unspecified errors.");
38                        case WBEM_E_INVALID_PARAMETER:
39                                return _T("An invalid parameter was specified.");
40                        case WBEM_E_INVALID_QUERY:
41                                return _T("The query was not syntactically valid.");
42                        case WBEM_E_INVALID_QUERY_TYPE:
43                                return _T("The requested query language is not supported.");
44                        case WBEM_E_OUT_OF_MEMORY:
45                                return _T("There was not enough memory to complete the operation.");
46                        case WBEM_E_SHUTTING_DOWN:
47                                return _T("Windows Management service was stopped and restarted. A new call to ConnectServer is required.");
48                        case WBEM_E_TRANSPORT_FAILURE:
49                                return _T("This indicates the failure of the remote procedure call (RPC) link between the current process and Windows Management.");
50                        case WBEM_E_NOT_FOUND:
51                                return _T("The query specifies a class that does not exist.");
52                        default:
53                                return _T("");
54                }
55        }
56        static std::wstring getComError(std::wstring inDesc = _T("")) {
57                USES_CONVERSION;
58                CComPtr<IErrorInfo> errorInfo;
59                HRESULT hr = GetErrorInfo(NULL, &errorInfo);
60                if (FAILED(hr) || hr == S_FALSE)
61                        return _T("unknown error: ") + error::format::from_system(hr);
62                CComBSTR bDesc, bSource;
63                std::wstring src = _T("unknown");
64                hr = errorInfo->GetSource(&bSource);
65                if (SUCCEEDED(hr))
66                        src = OLE2T(bSource);
67                std::wstring desc;
68                hr = errorInfo->GetDescription(&bDesc);
69                if (SUCCEEDED(hr))
70                        desc = OLE2T(bDesc);
71                if (desc.empty() && !inDesc.empty())
72                        desc = inDesc;
73                else if (desc.empty())
74                        desc = _T("unknown error: ") + error::format::from_system(hr);
75                return src + _T(" - ") + desc;
76        }
77};
78
79class WMIException {
80        std::wstring message_;
81public:
82        WMIException(std::wstring str, HRESULT code) {
83                message_ = str + _T(":") + error::format::from_system(code);
84        }
85        WMIException(std::wstring str) {
86                message_ = str;
87        }
88        std::wstring getMessage() {
89                return message_;
90        }
91};
92class WMIQuery
93{
94public:
95        struct WMIResult {
96                std::wstring alias;
97                std::wstring string;
98                long long numeric;
99                bool isNumeric;
100                WMIResult() : isNumeric(false), numeric(0) {}
101                void setString(std::wstring a, std::wstring s) {
102                        string = s;
103                        numeric = strEx::stoi64(s);
104                        alias = a;
105                }
106                void setNumeric(std::wstring a, long long n) {
107                        numeric = n;
108                        string = strEx::itos(n);
109                        alias = a;
110                }
111                void setBoth(std::wstring a, long long n, std::wstring s) {
112                        numeric = n;
113                        string = s;
114                        alias = a;
115                }
116        };
117        struct wmi_row {
118                typedef std::map<std::wstring,WMIResult> list_type;
119                list_type results;
120                boolean hasAlias(std::wstring alias) const {
121                        if (alias.empty())
122                                return true;
123                        return results.find(alias) != results.end();
124                }
125                const WMIResult get(std::wstring alias) const {
126                        WMIResult ret;
127                        list_type::const_iterator cit = results.find(alias);
128                        if (cit != results.end())
129                                ret = (*cit).second;
130                        return ret;
131                }
132                void addValue(std::wstring column, WMIResult value) {
133                        results[column] = value;
134                }
135
136                std::wstring render() {
137                        std::wstring ret;
138                        for (list_type::const_iterator it = results.begin(); it != results.end(); ++it) {
139                                if (!ret.empty())       ret += _T(", ");
140                                ret += (*it).first + _T("=") + (*it).second.string;
141                        }
142                        return ret;
143                }
144
145        };
146        typedef std::list<wmi_row> result_type;
147        struct wmi_filter {
148                std::wstring alias;
149                filters::filter_all_strings string;
150                filters::filter_all_numeric<unsigned long long, checkHolders::int64_handler >  numeric;
151
152                inline bool hasFilter() {
153                        return string.hasFilter() || numeric.hasFilter();
154                }
155                bool matchFilter(const wmi_row &value) const {
156                        if (!value.hasAlias(alias)) {
157                                NSC_DEBUG_MSG_STD(_T("We don't have any column matching: ") + alias);
158                                return false;
159                        }
160                        if (alias.empty()) {
161                                for (wmi_row::list_type::const_iterator cit = value.results.begin(); cit != value.results.end(); ++cit) {
162                                        if ((string.hasFilter())&&(string.matchFilter((*cit).second.string)))
163                                                return true;
164                                        else if ((numeric.hasFilter())&&(numeric.matchFilter((*cit).second.numeric)))
165                                                return true;
166                                }
167                        } else {
168                                if ((string.hasFilter())&&(string.matchFilter(value.get(alias).string)))
169                                        return true;
170                                else if ((numeric.hasFilter())&&(numeric.matchFilter(value.get(alias).numeric)))
171                                        return true;
172                        }
173                        NSC_DEBUG_MSG_STD(_T("Value did not match a filter: ") + alias);
174                        return false;
175                }
176        };
177        WMIQuery(void) {};
178        ~WMIQuery(void) {};
179
180        result_type  execute(std::wstring ns, std::wstring query);
181        std::wstring sanitize_string(LPTSTR in);
182};
Note: See TracBrowser for help on using the repository browser.