source: nscp/service/NSCPlugin.cpp @ 2305b35

0.4.00.4.10.4.2
Last change on this file since 2305b35 was f0eb62d, checked in by Michael Medin <michael@…>, 4 years ago

Refactored service into its own project

  • Property mode set to 100644
File size: 13.1 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 "NSClient++.h"
23#include <error.hpp>
24/**
25 * Default c-tor
26 * Initializes the plug in name but does not load the actual plug in.<br>
27 * To load the plug in use function load() that loads an initializes the plug in.
28 *
29 * @param file The file (DLL) to load as a NSC plug in.
30 */
31NSCPlugin::NSCPlugin(const std::wstring file)
32        : file_(file)
33        ,hModule_(NULL)
34        ,fLoadModule(NULL)
35        ,fGetName(NULL)
36        ,fHasCommandHandler(NULL)
37        ,fUnLoadModule(NULL)
38        ,fHasMessageHandler(NULL)
39        ,fHandleMessage(NULL)
40        ,fGetDescription(NULL)
41        ,fGetConfigurationMeta(NULL)
42        ,fGetVersion(NULL)
43        ,fCommandLineExec(NULL)
44        ,fShowTray(NULL)
45        ,fHideTray(NULL)
46        ,bLoaded_(false)
47        ,lastIsMsgPlugin_(false)
48        ,broken_(false)
49{
50}
51
52NSCPlugin::NSCPlugin(NSCPlugin &other)
53        :hModule_(NULL)
54        ,fLoadModule(NULL)
55        ,fGetName(NULL)
56        ,fHasCommandHandler(NULL)
57        ,fUnLoadModule(NULL)
58        ,fHasMessageHandler(NULL)
59        ,fHandleMessage(NULL)
60        ,fGetDescription(NULL)
61        ,fGetConfigurationMeta(NULL)
62        ,fGetVersion(NULL)
63        ,fCommandLineExec(NULL)
64        ,fShowTray(NULL)
65        ,fHideTray(NULL)
66        ,bLoaded_(false)
67        ,lastIsMsgPlugin_(false)
68        ,broken_(false)
69{
70        if (other.bLoaded_) {
71                file_ = other.file_;
72                hModule_ = LoadLibrary(file_.c_str());
73                if (!hModule_)
74                        throw NSPluginException(file_, _T("Could not load library: ") + error::lookup::last_error());
75                loadRemoteProcs_();
76                if (!fLoadModule)
77                        throw NSPluginException(file_, _T("Critical error (fLoadModule)"));
78                bLoaded_ = other.bLoaded_;
79        }
80}
81
82/**
83 * Default d-tor
84 */
85NSCPlugin::~NSCPlugin() {
86        if (isLoaded())
87                unload();
88}
89/**
90 * Returns the name of the plug in.
91 *
92 * @return Name of the plug in.
93 *
94 * @throws NSPluginException if the module is not loaded.
95 */
96std::wstring NSCPlugin::getName() {
97        TCHAR *buffer = new TCHAR[1024];
98        if (!getName_(buffer, 1023)) {
99                return _T("Could not get name");
100        }
101        std::wstring ret = buffer;
102        delete [] buffer;
103        return ret;
104}
105std::wstring NSCPlugin::getDescription() {
106        TCHAR *buffer = new TCHAR[4096];
107        if (!getDescription_(buffer, 4095)) {
108                throw NSPluginException(file_, _T("Could not get description"));
109        }
110        std::wstring ret = buffer;
111        delete [] buffer;
112        return ret;
113}
114
115/**
116 * Loads the plug in (DLL) and initializes the plug in by calling NSLoadModule
117 *
118 * @throws NSPluginException when exceptions occur.
119 * Exceptions include but are not limited to: DLL fails to load, DLL is not a correct plug in.
120 */
121void NSCPlugin::load_dll() {
122        if (isLoaded())
123                throw NSPluginException(file_, _T("Module already loaded"));
124        hModule_ = LoadLibrary(file_.c_str());
125        if (!hModule_)
126                throw NSPluginException(file_, _T("Could not load library: ") + error::lookup::last_error());
127        loadRemoteProcs_();
128        bLoaded_ = true;
129}
130
131bool NSCPlugin::load_plugin(NSCAPI::moduleLoadMode mode) {
132        if (!fLoadModule)
133                throw NSPluginException(file_, _T("Critical error (fLoadModule)"));
134        return fLoadModule(mode);
135}
136
137void NSCPlugin::setBroken(bool broken) {
138        broken_ = broken;
139}
140bool NSCPlugin::isBroken() {
141        return broken_;
142}
143
144
145/**
146 * Get the plug in version.
147 *
148 * @bug Not implemented as of yet
149 *
150 * @param *major
151 * @param *minor
152 * @param *revision
153 * @return False
154 */
155bool NSCPlugin::getVersion(int *major, int *minor, int *revision) {
156        if (!isLoaded())
157                throw NSPluginException(file_, _T("Library is not loaded"));
158        if (!fGetVersion)
159                throw NSPluginException(file_, _T("Critical error (fGetVersion)"));
160        try {
161                return fGetVersion(major, minor, revision)?true:false;
162        } catch (...) {
163                throw NSPluginException(file_, _T("Unhandled exception in getVersion."));
164        }
165}
166/**
167 * Returns true if the plug in has a command handler.
168 * @return true if the plug in has a command handler.
169 * @throws NSPluginException if the module is not loaded.
170 */
171bool NSCPlugin::hasCommandHandler() {
172        if (!isLoaded())
173                throw NSPluginException(file_, _T("Module not loaded"));
174        try {
175                if (fHasCommandHandler())
176                        return true;
177                return false;
178        } catch (...) {
179                throw NSPluginException(file_, _T("Unhandled exception in hasCommandHandler."));
180        }
181}
182/**
183* Returns true if the plug in has a message (log) handler.
184* @return true if the plug in has a message (log) handler.
185* @throws NSPluginException if the module is not loaded.
186*/
187bool NSCPlugin::hasMessageHandler() {
188        if (!isLoaded())
189                throw NSPluginException(file_, _T("Module not loaded"));
190        try {
191                if (fHasMessageHandler()) {
192                        lastIsMsgPlugin_ = true;
193                        return true;
194                }
195                return false;
196        } catch (...) {
197                throw NSPluginException(file_, _T("Unhandled exception in hasMessageHandler."));
198        }
199}
200/**
201 * Allow for the plug in to handle a command from the input core.
202 *
203 * Plug ins may refuse to handle the plug in (if not applicable) by returning an empty string.
204 *
205 * @param command The command name (is a string encoded number for legacy commands)
206 * @param argLen The length of the argument buffer.
207 * @param **arguments The arguments for this command
208 * @param returnMessageBuffer Return buffer for plug in to store the result of the executed command.
209 * @param returnMessageBufferLen Size of returnMessageBuffer
210 * @param returnPerfBuffer Return buffer for performance data
211 * @param returnPerfBufferLen Size of returnPerfBuffer
212 * @return Status of execution. Could be error codes, buffer length messages etc.
213 * @throws NSPluginException if the module is not loaded.
214 */
215NSCAPI::nagiosReturn NSCPlugin::handleCommand(const TCHAR* command, const unsigned int argLen, TCHAR **arguments, TCHAR* returnMessageBuffer, unsigned int returnMessageBufferLen, TCHAR* returnPerfBuffer, unsigned int returnPerfBufferLen) {
216        if (!isLoaded())
217                throw NSPluginException(file_, _T("Library is not loaded"));
218        try {
219                return fHandleCommand(command, argLen, arguments, returnMessageBuffer, returnMessageBufferLen, returnPerfBuffer, returnPerfBufferLen);
220        } catch (...) {
221                throw NSPluginException(file_, _T("Unhandled exception in handleCommand."));
222        }
223}
224/**
225 * Handle a message from the core (or any other (or even potentially self) plug in).
226 * A message may be anything really errors, log messages etc.
227 *
228 * @param msgType Type of message (error, warning, debug, etc.)
229 * @param file The file that generated this message generally __FILE__.
230 * @param line The line in the file that generated the message generally __LINE__
231 * @throws NSPluginException if the module is not loaded.
232 */
233void NSCPlugin::handleMessage(int msgType, const TCHAR* file, const int line, const TCHAR *message) {
234        if (!fHandleMessage)
235                throw NSPluginException(file_, _T("Library is not loaded"));
236        try {
237                fHandleMessage(msgType, file, line, message);
238        } catch (...) {
239                throw NSPluginException(file_, _T("Unhandled exception in handleMessage."));
240        }
241}
242/**
243 * Unload the plug in
244 * @throws NSPluginException if the module is not loaded and/or cannot be unloaded (plug in remains loaded if so).
245 */
246void NSCPlugin::unload() {
247        if (!isLoaded())
248                throw NSPluginException(file_, _T("Library is not loaded"));
249        if (!fUnLoadModule)
250                throw NSPluginException(file_, _T("Critical error (fUnLoadModule)"));
251        try {
252                fUnLoadModule();
253        } catch (...) {
254                throw NSPluginException(file_, _T("Unhandled exception in handleMessage."));
255        }
256        FreeLibrary(hModule_);
257        hModule_ = NULL;
258        bLoaded_ = false;
259}
260bool NSCPlugin::getName_(TCHAR* buf, unsigned int buflen) {
261        if (fGetName == NULL)
262                return false;//throw NSPluginException(file_, _T("Critical error (fGetName)"));
263        try {
264                return fGetName(buf, buflen)?true:false;
265        } catch (...) {
266                return false; //throw NSPluginException(file_, _T("Unhandled exception in getName."));
267        }
268}
269bool NSCPlugin::getDescription_(TCHAR* buf, unsigned int buflen) {
270        if (fGetDescription == NULL)
271                throw NSPluginException(file_, _T("Critical error (fGetDescription)"));
272        try {
273                return fGetDescription(buf, buflen)?true:false;
274        } catch (...) {
275                throw NSPluginException(file_, _T("Unhandled exception in getDescription."));
276        }
277}
278
279void NSCPlugin::showTray() {
280        if (fShowTray == NULL)
281                throw NSPluginException(file_, _T("Critical error (ShowTray)"));
282        try {
283                fShowTray();
284        } catch (...) {
285                throw NSPluginException(file_, _T("Unhandled exception in ShowTray."));
286        }
287}
288void NSCPlugin::hideTray() {
289        if (fHideTray == NULL)
290                throw NSPluginException(file_, _T("Critical error (HideTray)"));
291        try {
292                fHideTray();
293        } catch (...) {
294                throw NSPluginException(file_, _T("Unhandled exception in HideTray."));
295        }
296}
297
298/**
299 * Load all remote function pointers from the loaded module.
300 * These pointers are cached for "speed" which might (?) be dangerous if something changes.
301 * @throws NSPluginException if any of the function pointers fail to load.
302 * If NSPluginException  is thrown the loaded might remain partially loaded and crashes might occur if plug in is used in this state.
303 */
304void NSCPlugin::loadRemoteProcs_(void) {
305
306        fLoadModule = (lpLoadModule)GetProcAddress(hModule_, "NSLoadModule");
307        if (!fLoadModule)
308                throw NSPluginException(file_, _T("Could not load NSLoadModule"));
309
310        fModuleHelperInit = (lpModuleHelperInit)GetProcAddress(hModule_, "NSModuleHelperInit");
311        if (!fModuleHelperInit)
312                throw NSPluginException(file_, _T("Could not load NSModuleHelperInit"));
313
314        try {
315                fModuleHelperInit(NSAPILoader);
316        } catch (...) {
317                throw NSPluginException(file_, _T("Unhandled exception in getDescription."));
318        }
319       
320        fGetName = (lpGetName)GetProcAddress(hModule_, "NSGetModuleName");
321        if (!fGetName)
322                throw NSPluginException(file_, _T("Could not load NSGetModuleName"));
323
324        fGetVersion = (lpGetVersion)GetProcAddress(hModule_, "NSGetModuleVersion");
325        if (!fGetVersion)
326                throw NSPluginException(file_, _T("Could not load NSGetModuleVersion"));
327
328        fGetDescription = (lpGetDescription)GetProcAddress(hModule_, "NSGetModuleDescription");
329        if (!fGetDescription)
330                throw NSPluginException(file_, _T("Could not load NSGetModuleDescription"));
331
332        fHasCommandHandler = (lpHasCommandHandler)GetProcAddress(hModule_, "NSHasCommandHandler");
333        if (!fHasCommandHandler)
334                throw NSPluginException(file_, _T("Could not load NSHasCommandHandler"));
335
336        fHasMessageHandler = (lpHasMessageHandler)GetProcAddress(hModule_, "NSHasMessageHandler");
337        if (!fHasMessageHandler)
338                throw NSPluginException(file_, _T("Could not load NSHasMessageHandler"));
339
340        fHandleCommand = (lpHandleCommand)GetProcAddress(hModule_, "NSHandleCommand");
341        if (!fHandleCommand)
342                throw NSPluginException(file_, _T("Could not load NSHandleCommand"));
343
344        fHandleMessage = (lpHandleMessage)GetProcAddress(hModule_, "NSHandleMessage");
345        if (!fHandleMessage)
346                throw NSPluginException(file_, _T("Could not load NSHandleMessage"));
347
348        fUnLoadModule = (lpUnLoadModule)GetProcAddress(hModule_, "NSUnloadModule");
349        if (!fUnLoadModule)
350                throw NSPluginException(file_, _T("Could not load NSUnloadModule"));
351
352        fGetConfigurationMeta = (lpGetConfigurationMeta)GetProcAddress(hModule_, "NSGetConfigurationMeta");
353        fCommandLineExec = (lpCommandLineExec)GetProcAddress(hModule_, "NSCommandLineExec");
354
355        fShowTray = (lpShowTray)GetProcAddress(hModule_, "ShowIcon");
356        fHideTray = (lpHideTray)GetProcAddress(hModule_, "HideIcon");
357
358}
359
360
361std::wstring NSCPlugin::getCongifurationMeta()
362{
363        TCHAR *buffer = new TCHAR[4097];
364        if (!getConfigurationMeta_(buffer, 4096)) {
365                throw NSPluginException(file_, _T("Could not get metadata"));
366        }
367        std::wstring ret = buffer;
368        delete [] buffer;
369        return ret;
370}
371bool NSCPlugin::getConfigurationMeta_(TCHAR* buf, unsigned int buflen) {
372        if (fGetConfigurationMeta == NULL)
373                throw NSPluginException(file_, _T("Critical error (getCongifurationMeta)"));
374        try {
375                return fGetConfigurationMeta(buflen, buf)?true:false;
376        } catch (...) {
377                throw NSPluginException(file_, _T("Unhandled exception in getConfigurationMeta."));
378        }
379}
380
381int NSCPlugin::commandLineExec(const TCHAR* command, const unsigned int argLen, TCHAR **arguments) {
382        if (fCommandLineExec== NULL)
383                throw NSPluginException(file_, _T("Module does not support CommandLineExec"));
384        try {
385                return fCommandLineExec(command, argLen, arguments);
386        } catch (...) {
387                throw NSPluginException(file_, _T("Unhandled exception in commandLineExec."));
388        }
389}
Note: See TracBrowser for help on using the repository browser.