source: nscp/modules/CheckWMI/WMIQuery.cpp @ b749b8d

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

2007-11-04 MickeM

  • Rewritten WMI handling as well as checks so things should be more usefull now (cf. the wiki page for details)
  • Property mode set to 100644
File size: 5.0 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#include "StdAfx.h"
22#include ".\wmiquery.h"
23
24#include <objidl.h>
25#include <Wbemidl.h>
26#include <map>
27
28WMIQuery::WMIQuery(void) : bInitialized(false)
29{
30}
31
32WMIQuery::~WMIQuery(void)
33{
34        if (bInitialized)
35                unInitialize();
36}
37
38
39bool WMIQuery::initialize()
40{
41        NSC_LOG_ERROR_STD("Attempting Inialized WMI component");
42
43        HRESULT hRes = CoInitializeEx(NULL, COINIT_MULTITHREADED);
44        if (FAILED(hRes)) {
45                NSC_LOG_ERROR_STD("CoInitialize failed: " + error::format::from_system(hRes));
46                return false;
47        }
48        bInitialized = true;
49        hRes = CoInitializeSecurity(NULL,-1,NULL,NULL,RPC_C_AUTHN_LEVEL_PKT,RPC_C_IMP_LEVEL_IMPERSONATE,NULL,EOAC_NONE,NULL);
50        if (FAILED(hRes)) {
51                NSC_LOG_ERROR_STD("CoInitializeSecurity failed: " + error::format::from_system(hRes));
52                return false;
53        }
54
55        NSC_LOG_ERROR_STD("Inialized WMI component");
56        return true;
57}
58void WMIQuery::unInitialize()
59{
60        CoUninitialize();
61        bInitialized = false;
62}
63
64
65WMIQuery::result_type WMIQuery::execute(std::string query)
66{
67        if (!bInitialized) {
68                initialize();
69        }
70        result_type ret;
71
72        CComPtr< IWbemLocator > locator;
73        HRESULT hr = CoCreateInstance( CLSID_WbemAdministrativeLocator, NULL, CLSCTX_INPROC_SERVER, IID_IWbemLocator, reinterpret_cast< void** >( &locator ) );
74        if (FAILED(hr)) {
75                throw WMIException("CoCreateInstance for CLSID_WbemAdministrativeLocator failed!", hr);
76        }
77
78        BSTR bstrNamespace = (L"root\\cimv2");
79        CComPtr< IWbemServices > service;
80        hr = locator->ConnectServer( bstrNamespace, NULL, NULL, NULL, WBEM_FLAG_CONNECT_USE_MAX_WAIT, NULL, NULL, &service );
81        if (FAILED(hr)) {
82                throw WMIException("ConnectServer failed!", hr);
83        }
84        CComBSTR strQuery(query.c_str());
85        BSTR strQL = (L"WQL");
86
87        CComPtr< IEnumWbemClassObject > enumerator;
88        hr = service->ExecQuery( strQL, strQuery, WBEM_FLAG_FORWARD_ONLY, NULL, &enumerator );
89        if (FAILED(hr)) {
90                throw WMIException("ExecQuery failed:" + query + " (reason is: " + ComError::getComError() + ")", hr);
91        }
92
93        CComPtr< IWbemClassObject > row = NULL;
94        ULONG retcnt;
95        int i=0;
96        while (hr = enumerator->Next( WBEM_INFINITE, 1L, &row, &retcnt ) == WBEM_S_NO_ERROR) {
97                if (SUCCEEDED(hr)) {
98                        if (retcnt > 0) {
99                                SAFEARRAY* pstrNames;
100                                wmi_row returnRow;
101                                hr = row->GetNames(NULL,WBEM_FLAG_ALWAYS|WBEM_FLAG_NONSYSTEM_ONLY,NULL,&pstrNames);
102                                if (FAILED(hr)) {
103                                        throw WMIException("GetNames failed:" + query, hr);
104                                }
105
106                                long index = 0, begin, end;
107                                CComSafeArray<BSTR> arr = pstrNames;
108                                begin = arr.GetLowerBound();
109                                end = arr.GetUpperBound();
110                                for ( index = begin; index <= end; index++ ) {
111                                        USES_CONVERSION;
112                                        CComBSTR bColumn = arr.GetAt(index);
113                                        std::string column = OLE2T(bColumn);
114                                        CComVariant vValue;
115                                        hr = row->Get(bColumn, 0, &vValue, 0, 0);
116                                        if (FAILED(hr)) {
117                                                throw WMIException("Failed to get value for " + column + " in query: " + query, hr);
118                                        }
119                                        WMIResult value;
120
121                                        if (vValue.vt == VT_INT) {
122                                                value.setNumeric(column, vValue.intVal);
123                                        } else if (vValue.vt == VT_I4) {
124                                                value.setNumeric(column, vValue.lVal);
125                                        } else if (vValue.vt == VT_UINT) {
126                                                value.setNumeric(column, vValue.uintVal);
127                                        } else if (vValue.vt == VT_BSTR) {
128                                                value.setString(column, OLE2T(vValue.bstrVal));
129                                        } else if (vValue.vt == VT_NULL) {
130                                                value.setString(column, "NULL");
131                                        } else if (vValue.vt == VT_BOOL) {
132                                                value.setBoth(column, vValue.iVal, vValue.iVal?"TRUE":"FALSE");
133                                        } else {
134                                                NSC_LOG_ERROR_STD(column + " is not supported (type-id: " + strEx::itos(vValue.vt) + ")");
135                                        }
136                                        returnRow.addValue(column, value);
137                                }
138                                ret.push_back(returnRow);
139                        }
140                }
141                row.Release();
142        }
143        return ret;
144}
Note: See TracBrowser for help on using the repository browser.