source: nscp/modules/CheckWMI/WMIQuery.h @ 29655a1

0.4.00.4.10.4.2
Last change on this file since 29655a1 was 29655a1, checked in by Michael Medin <michael@…>, 16 months ago
  • Added "back" WMI Query command line exec like so:

nscp wmi --exec wmi-query

CheckWMI Command line syntax:
Allowed options:

-h [ --help ] Show help screen
-w [ --wmi-query ] arg Query to execute
-l [ --limit ] arg Limit number of rows
-n [ --namespace ] arg (=root\cimv2) Namespace

nscp wmi --exec wmi-query --query="Select * from Win32_Process" --limit 2

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