source: nscp/service/NSClient++.cpp @ d05c3f0

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

Next major "milestone" we now have one working plugin (CheckHelpers) which loads and works both on Linux and Windows.
This is (as always) a broken build which many many features disabled and non functional...

  • Property mode set to 100644
File size: 55.9 KB
Line 
1///////////////////////////////////////////////////////////////////////////
2// NSClient++ Base Service
3//
4// Copyright (c) 2004 MySolutions NORDIC (http://www.medin.name)
5//
6// Date: 2004-03-13
7// Author: Michael Medin (michael@medin.name)
8//
9// Part of this file is based on work by Bruno Vais (bvais@usa.net)
10//
11// This software is provided "AS IS", without a warranty of any kind.
12// You are free to use/modify this code but leave this header intact.
13//
14//////////////////////////////////////////////////////////////////////////
15#include "StdAfx.h"
16#include "NSClient++.h"
17#include <settings/Settings.h>
18#include <charEx.h>
19//#include <Socket.h>
20#include <config.h>
21#include <msvc_wrappers.h>
22#ifdef WIN32
23#include <Userenv.h>
24#include <Lmcons.h>
25//#ifdef DEBUG
26#include <crtdbg.h>
27//#endif
28#endif
29//#include <remote_processes.hpp>
30//#include <winsvc.h>
31//#include <Userenv.h>
32//#include <Lmcons.h>
33//#include <remote_processes.hpp>
34#include "core_api.h"
35#include "settings_manager_impl.h"
36#include <settings/macros.h>
37#include <NSCHelper.h>
38
39NSClient mainClient(SZSERVICENAME);     // Global core instance.
40bool g_bConsoleLog = false;
41
42#define SETTINGS_GET_BOOL_CORE(key) \
43        settings_manager::get_settings()->get_bool(setting_keys::key ## _PATH, setting_keys::key, setting_keys::key ## _DEFAULT)
44
45#define SETTINGS_GET_STRING_CORE(key) \
46        settings_manager::get_settings()->get_string(setting_keys::key ## _PATH, setting_keys::key, setting_keys::key ## _DEFAULT)
47/*
48#define SETTINGS_SET_STRING_CORE(key, value) \
49        Settings::get_settings()->set_string(setting_keys::key ## _PATH, setting_keys::key, value);
50*/
51/**
52 * START OF Tray starter MERGE HELPER
53 */
54class tray_starter {
55        struct start_block {
56                std::wstring cmd;
57                std::wstring cmd_line;
58                DWORD sessionId;
59        };
60
61public:
62        static LPVOID init(DWORD dwSessionId, std::wstring exe, std::wstring cmdline) {
63                start_block *sb = new start_block;
64                sb->cmd = exe;
65                sb->cmd_line = cmdline;
66                sb->sessionId = dwSessionId;
67                return sb;
68        }
69        DWORD threadProc(LPVOID lpParameter) {
70#ifdef WIN32
71                start_block* param = static_cast<start_block*>(lpParameter);
72                DWORD dwSessionId = param->sessionId;
73                std::wstring cmd = param->cmd;
74                std::wstring cmdline = param->cmd_line;
75                delete param;
76                for (int i=0;i<10;i++) {
77                        Sleep(1000);
78                        if (startTrayHelper(dwSessionId, cmd, cmdline, false))
79                                break;
80                }
81#endif
82                return 0;
83        }
84
85        static bool start(unsigned long  dwSessionId) {
86                boost::filesystem::wpath program = mainClient.getBasePath() / SETTINGS_GET_STRING_CORE(settings_def::SYSTRAY_EXE);
87                std::wstring cmdln = _T("\"") + program.string() + _T("\" -channel __") + strEx::itos(dwSessionId) + _T("__");
88                return tray_starter::startTrayHelper(dwSessionId, program.string(), cmdln);
89        }
90
91        static bool startTrayHelper(unsigned long dwSessionId, std::wstring exe, std::wstring cmdline, bool startThread = true) {
92//              HANDLE hToken = NULL;
93//              if (!remote_processes::GetSessionUserToken(dwSessionId, &hToken)) {
94//                      LOG_ERROR_STD(_T("Failed to query user token: ") + error::lookup::last_error());
95//                      return false;
96//              } else {
97//                      STARTUPINFO          StartUPInfo;
98//                      PROCESS_INFORMATION  ProcessInfo;
99//
100//                      ZeroMemory(&StartUPInfo,sizeof(STARTUPINFO));
101//                      ZeroMemory(&ProcessInfo,sizeof(PROCESS_INFORMATION));
102//                      StartUPInfo.wShowWindow = SW_HIDE;
103//                      StartUPInfo.lpDesktop = L"Winsta0\\Default";
104//                      StartUPInfo.cb = sizeof(STARTUPINFO);
105//
106//                      wchar_t *buffer = new wchar_t[cmdline.size()+10];
107//                      wcscpy(buffer, cmdline.c_str());
108//                      LOG_MESSAGE_STD(_T("Running: ") + exe);
109//                      LOG_MESSAGE_STD(_T("Running: ") + cmdline);
110//
111//                      LPVOID pEnv =NULL;
112//                      DWORD dwCreationFlags = CREATE_NO_WINDOW; //0; //DETACHED_PROCESS
113//
114//                      if(CreateEnvironmentBlock(&pEnv,hToken,TRUE)) {
115//                              dwCreationFlags|=CREATE_UNICODE_ENVIRONMENT;
116//                      } else {
117//                              LOG_ERROR_STD(_T("Failed to create enviornment: ") + error::lookup::last_error());
118//                              pEnv=NULL;
119//                      }
120//                      /*
121//                      LOG_ERROR_STD(_T("Impersonating user: "));
122//                      if (!ImpersonateLoggedOnUser(hToken)) {
123//                              LOG_ERROR_STD(_T("Failed to impersonate the user: ") + error::lookup::last_error());
124//                      }
125//
126//                      wchar_t pszUname[UNLEN + 1];
127//                      ZeroMemory(pszUname,sizeof(pszUname));
128//                      DWORD dwSize = UNLEN;
129//                      if (!GetUserName(pszUname,&dwSize)) {
130//                              DWORD dwErr = GetLastError();
131//                              if (!RevertToSelf())
132//                                      LOG_ERROR_STD(_T("Failed to revert to self: ") + error::lookup::last_error());
133//                              LOG_ERROR_STD(_T("Failed to get username: ") + error::format::from_system(dwErr));
134//                              return false;
135//                      }
136//                     
137//
138//                      PROFILEINFO info;
139//                      info.dwSize = sizeof(PROFILEINFO);
140//                      info.lpUserName = pszUname;
141//                      if (!LoadUserProfile(hToken, &info)) {
142//                              DWORD dwErr = GetLastError();
143//                              if (!RevertToSelf())
144//                                      LOG_ERROR_STD(_T("Failed to revert to self: ") + error::lookup::last_error());
145//                              LOG_ERROR_STD(_T("Failed to get username: ") + error::format::from_system(dwErr));
146//                              return false;
147//                      }
148//                      */
149//                      if (!CreateProcessAsUser(hToken, exe.c_str(), buffer, NULL, NULL, FALSE, dwCreationFlags, pEnv, NULL, &StartUPInfo, &ProcessInfo)) {
150//                              DWORD dwErr = GetLastError();
151//                              delete [] buffer;
152//                              /*
153//                              if (!RevertToSelf()) {
154//                                      LOG_ERROR_STD(_T("Failed to revert to self: ") + error::lookup::last_error());
155//                              }
156//                              */
157//                              if (startThread && dwErr == ERROR_PIPE_NOT_CONNECTED) {
158//                                      LOG_MESSAGE(_T("Failed to start trayhelper: starting a background thread to do it instead..."));
159//                                      Thread<tray_starter> *pThread = new Thread<tray_starter>(_T("tray-starter-thread"));
160//                                      pThread->createThread(tray_starter::init(dwSessionId, exe, cmdline));
161//                                      return false;
162//                              } else if (dwErr == ERROR_PIPE_NOT_CONNECTED) {
163//                                      LOG_ERROR_STD(_T("Thread failed to start trayhelper (will try again): ") + error::format::from_system(dwErr));
164//                                      return false;
165//                              } else {
166//                                      LOG_ERROR_STD(_T("Failed to start trayhelper: ") + error::format::from_system(dwErr));
167//                                      return true;
168//                              }
169//                      } else {
170//                              delete [] buffer;
171//                              /*
172//                              if (!RevertToSelf()) {
173//                                      LOG_ERROR_STD(_T("Failed to revert to self: ") + error::lookup::last_error());
174//                              }
175//                              */
176//                              LOG_MESSAGE_STD(_T("Started tray in other user session: ") + strEx::itos(dwSessionId));
177//                      }
178//
179//
180//                      CloseHandle(hToken);
181//                      return true;
182//              }
183                return false;
184        }
185};
186
187/**
188 * End of class tray started (MERGE HELP)
189 */
190
191#define XNSC_DEFINE_SETTING_KEY(name, tag) \
192        name ## _SECTION \
193       
194 /**
195 * RANDOM JUNK (MERGE HELP)
196 */
197
198void display(std::wstring title, std::wstring message) {
199#ifdef WIN32
200        ::MessageBox(NULL, message.c_str(), title.c_str(), MB_OK|MB_ICONERROR);
201#endif
202        std::wcout << title << std::endl << message << std::endl;
203}
204
205
206bool is_module(boost::filesystem::wpath file )
207{
208        return boost::ends_with(file.string(), _T(".dll")) || boost::ends_with(file.string(), _T(".so"));
209}
210/**
211 * Application startup point
212 *
213 * @param argc Argument count
214 * @param argv[] Argument array
215 * @param envp[] Environment array
216 * @return exit status
217 */
218int nscp_main(int argc, wchar_t* argv[]);
219
220#ifdef WIN32
221int wmain(int argc, wchar_t* argv[], wchar_t* envp[]) { return nscp_main(argc, argv); }
222#else
223int main(int argc, char* argv[]) {
224        wchar_t **wargv = new wchar_t*[argc];
225        for (int i=0;i<argc;i++) {
226                std::wstring s = to_wstring(argv[i]);
227                wargv[i] = new wchar_t[s.length()+10];
228                wcscpy(wargv[i], s.c_str());
229        }
230        int ret = nscp_main(argc, wargv);
231        for (int i=0;i<argc;i++) {
232                delete [] wargv[i];
233        }
234        delete [] wargv;
235}
236#endif
237int nscp_main(int argc, wchar_t* argv[])
238{
239        srand( (unsigned)time( NULL ) );
240        int nRetCode = 0;
241        if ( (argc > 1) && ((*argv[1] == '-') || (*argv[1] == '/')) ) {
242                if (false) {
243#ifdef WIN32
244                } if ( wcscasecmp( _T("install"), argv[1]+1 ) == 0 ) {
245                        bool bGui = false;
246                        bool bStart = false;
247                        std::wstring service_name, service_description;
248                        for (int i=2;i<argc;i++) {
249                                if (wcscasecmp( _T("gui"), argv[i]) == 0) {
250                                        bGui = true;
251                                } else if (wcscasecmp( _T("start"), argv[i]) == 0) {
252                                        bStart = true;
253                                } else {
254                                        if (service_name.empty())
255                                                service_name = argv[i];
256                                        else {
257                                                if (!service_description.empty())
258                                                        service_description += _T(" ");
259                                                service_description += argv[i];
260                                        }
261                                }
262                        }
263                        if (service_name.empty())
264                                service_name = SZSERVICENAME;
265                        if (service_description.empty())
266                                service_description = SZSERVICEDISPLAYNAME;
267                        g_bConsoleLog = true;
268                        try {
269                                serviceControll::Install(service_name.c_str(), service_description.c_str(), SZDEPENDENCIES);
270                                if (bStart)
271                                        serviceControll::Start(service_name);
272                        } catch (const serviceControll::SCException& e) {
273                                if (bGui)
274                                        display(_T("Error installing"), _T("Service installation failed; ") + e.error_);
275                                LOG_ERROR_STD(_T("Service installation failed: ") + e.error_);
276                                return -1;
277                        }
278                        try {
279                                serviceControll::SetDescription(service_name, service_description);
280                        } catch (const serviceControll::SCException& e) {
281                                if (bGui)
282                                        display(_T("Error installing"), _T("Service installation failed; ") + e.error_);
283                                LOG_MESSAGE_STD(_T("Couldn't set service description: ") + e.error_);
284                        }
285                        if (bGui)
286                                display(_T("Service installed"), _T("Service installed successfully!"));
287                        LOG_MESSAGE(_T("Service installed!"));
288                        return 0;
289                } else if ( wcscasecmp( _T("uninstall"), argv[1]+1 ) == 0 ) {
290                        bool bGui = false;
291                        bool bStop = false;
292                        std::wstring service_name;
293                        for (int i=2;i<argc;i++) {
294                                if (wcscasecmp( _T("gui"), argv[i]) == 0) {
295                                        bGui = true;
296                                } else if (wcscasecmp( _T("stop"), argv[i]) == 0) {
297                                        bStop = true;
298                                } else {
299                                        service_name = argv[i];
300                                }
301                        }
302                        if (service_name.empty())
303                                service_name = SZSERVICENAME;
304                        g_bConsoleLog = true;
305                        try {
306                                if (bStop)
307                                        serviceControll::Stop(service_name);
308                        } catch (const serviceControll::SCException& e) {
309                                LOG_MESSAGE_STD(_T("Failed to stop service (") + service_name + _T(") failed; ") + e.error_);
310                        }
311                        try {
312                                serviceControll::Uninstall(service_name);
313                        } catch (const serviceControll::SCException& e) {
314                                if (bGui)
315                                        display(_T("Error uninstalling"), _T("Service de-installation (") + service_name + _T(") failed; ") + e.error_ + _T("\nMaybe the service was not previously installed properly?"));
316                                LOG_ERROR_STD(_T("Service deinstallation failed; ") + e.error_);
317                                return 0;
318                        }
319                        if (bGui)
320                                display(_T("Service uninstalled"), _T("Service uninstalled successfully!"));
321                        LOG_MESSAGE(_T("Service uninstalled!"));
322                        return 0;
323                } else if ( wcscasecmp( _T("start"), argv[1]+1 ) == 0 ) {
324                        g_bConsoleLog = true;
325                        bool bGui = false;
326                        std::wstring service_name;
327                        for (int i=2;i<argc;i++) {
328                                if (wcscasecmp( _T("gui"), argv[i]) == 0) {
329                                        bGui = true;
330                                } else {
331                                        service_name = argv[i];
332                                }
333                        }
334                        if (service_name.empty())
335                                service_name = SZSERVICENAME;
336                        try {
337                                serviceControll::Start(service_name.c_str());
338                        } catch (const serviceControll::SCException& e) {
339                                if (bGui)
340                                        display(_T("Service failed to start"), e.error_);
341                                LOG_MESSAGE_STD(_T("Service failed to start: ") + e.error_);
342                                return -1;
343                        }
344                } else if ( wcscasecmp( _T("stop"), argv[1]+1 ) == 0 ) {
345                        g_bConsoleLog = true;
346                        bool bGui = false;
347                        std::wstring service_name;
348                        for (int i=2;i<argc;i++) {
349                                if (wcscasecmp( _T("gui"), argv[i]) == 0) {
350                                        bGui = true;
351                                } else {
352                                        service_name = argv[i];
353                                }
354                        }
355                        if (service_name.empty())
356                                service_name = SZSERVICENAME;
357                        try {
358                                serviceControll::Stop(service_name.c_str());
359                        } catch (const serviceControll::SCException& e) {
360                                if (bGui)
361                                        display(_T("Service failed to stop"), e.error_);
362                                LOG_MESSAGE_STD(_T("Service failed to stop: ") + e.error_);
363                                return -1;
364                        }
365                } else if ( wcscasecmp( _T("svc"), argv[1]+1 ) == 0 ) {
366                        g_bConsoleLog = true;
367                        try {
368                                std::wstring exe = serviceControll::get_exe_path(SZSERVICENAME);
369                                LOG_MESSAGE_STD(_T("The Service uses: ") + exe);
370                        } catch (const serviceControll::SCException& e) {
371                                LOG_ERROR_STD(_T("Failed to find service: ") + e.error_);
372                        }
373#endif
374                } else if ( wcscasecmp( _T("encrypt"), argv[1]+1 ) == 0 ) {
375                        g_bConsoleLog = true;
376                        std::wstring password;
377                        if (!settings_manager::init_settings(mainClient.getBasePath())) {
378                                std::wcout << _T("Could not find settings") << std::endl;;
379                                return 1;
380                        }
381                        std::wcout << _T("Enter password to encrypt (has to be a single word): ");
382                        std::wcin >> password;
383                        std::wstring xor_pwd = Encrypt(password);
384                        std::wcout << _T("obfuscated_password=") << xor_pwd << std::endl;
385                        std::wstring outPasswd = Decrypt(xor_pwd);
386                        if (password != outPasswd)
387                                std::wcout << _T("ERROR: Password did not match: ") << outPasswd<< std::endl;
388                        settings_manager::destroy_settings();
389                        return 0;
390                } else if ( wcscasecmp( _T("about"), argv[1]+1 ) == 0 ) {
391                        try {
392                                g_bConsoleLog = true;
393                                LOG_MESSAGE(SZAPPNAME _T(" (C) Michael Medin - michael<at>medin<dot>name"));
394                                LOG_MESSAGE(_T("Version: ") SZVERSION);
395                                LOG_MESSAGE(_T("Architecture: ") SZARCH);
396
397                                boost::filesystem::wpath pluginPath = (boost::filesystem::wpath)mainClient.getBasePath() / _T("modules");
398                                LOG_MESSAGE_STD(_T("Looking at plugins in: ") + pluginPath.string());
399
400                                boost::filesystem::wdirectory_iterator end_itr; // default construction yields past-the-end
401                                for ( boost::filesystem::wdirectory_iterator itr( pluginPath ); itr != end_itr; ++itr ) {
402                                        if ( !is_directory(itr->status()) ) {
403                                                std::wstring file= itr->leaf();
404                                                LOG_MESSAGE_STD(_T("Found: ") + file);
405                                                if (is_module(pluginPath / file)) {
406                                                        NSCPlugin *plugin = new NSCPlugin(pluginPath / file);
407                                                        std::wstring name = _T("<unknown>");
408                                                        std::wstring description = _T("<unknown>");
409                                                        try {
410                                                                plugin->load_dll();
411                                                                name = plugin->getName();
412                                                                description = plugin->getDescription();
413                                                        } catch(const NSPluginException& e) {
414                                                                LOG_ERROR_STD(_T("Exception raised: ") + e.error_ + _T(" in module: ") + e.file_);
415                                                        } catch (std::exception e) {
416                                                                LOG_ERROR_STD(_T("exception loading plugin: ") + strEx::string_to_wstring(e.what()));
417                                                        } catch (...) {
418                                                                LOG_ERROR_STD(_T("Unknown exception loading plugin"));
419                                                        }
420                                                        LOG_MESSAGE_STD(_T("* ") + name + _T(" (") + file + _T(")"));
421                                                        std::list<std::wstring> list = strEx::splitEx(description, _T("\n"));
422                                                        for (std::list<std::wstring>::const_iterator cit = list.begin(); cit != list.end(); ++cit) {
423                                                                LOG_MESSAGE_STD(_T("    ") + *cit);
424                                                        }
425                                                }
426                                        }
427                                }
428                                LOG_MESSAGE_STD(_T("Done listing plugins from: ") + pluginPath.string());
429                                return true;
430                        } catch (std::exception &e) {
431                                LOG_ERROR_STD(_T("Exception: ") + to_wstring(e.what()));
432                        } catch (...) {
433                                LOG_ERROR_STD(_T("Unknown Exception: "));
434                        }
435                        return false;
436                } else if ( wcscasecmp( _T("version"), argv[1]+1 ) == 0 ) {
437                        g_bConsoleLog = true;
438                        LOG_MESSAGE(SZAPPNAME _T(" Version: ") SZVERSION _T(", Plattform: ") SZARCH);
439                } else if ( wcscasecmp( _T("d"), argv[1]+1 ) == 0 ) {
440                        // Run command from command line (like NRPE) but with debug enabled
441                } else if ( wcscasecmp( _T("noboot"), argv[1]+1 ) == 0 ) {
442                        g_bConsoleLog = true;
443                        mainClient.enableDebug(false);
444                        mainClient.initCore(false);
445                        if (argc>=4)
446                                nRetCode = mainClient.commandLineExec(argv[2], argv[3], argc-4, &argv[4]);
447                        else
448                                nRetCode = mainClient.commandLineExec(argv[2], argv[3], 0, NULL);
449                        mainClient.exitCore(true);
450                        return nRetCode;
451                } else if ( wcscasecmp( _T("c"), argv[1]+1 ) == 0 ) {
452                        // Run command from command line (like NRPE)
453                        g_bConsoleLog = true;
454                        mainClient.enableDebug(false);
455                        mainClient.initCore(true);
456                        std::wstring command, args, msg, perf;
457                        if (argc > 2)
458                                command = argv[2];
459                        for (int i=3;i<argc;i++) {
460                                if (i!=3) args += _T(" ");
461                                args += argv[i];
462                        }
463                        nRetCode = mainClient.inject(command, args, L' ', true, msg, perf);
464                        std::wcout << msg << _T("|") << perf << std::endl;
465                        mainClient.exitCore(true);
466                        return nRetCode;
467                } else if ( wcscasecmp( _T("test"), argv[1]+1 ) == 0 ) {
468                        bool server = false;
469                        if (argc > 2 && wcscasecmp( _T("server"), argv[2] ) == 0 ) {
470                                server = true;
471                        }
472                        std::wcout << "Launching test mode - " << (server?_T("server mode"):_T("client mode")) << std::endl;
473                        LOG_MESSAGE_STD(_T("Booting: ") SZSERVICEDISPLAYNAME );
474#ifdef WIN32
475                        try {
476                                if (serviceControll::isStarted(SZSERVICENAME)) {
477                                        std::wcerr << "Service seems to be started, this is probably not a good idea..." << std::endl;
478                                }
479                        } catch (const serviceControll::SCException& e) {
480                                e;// Empty by design
481                        }
482#endif
483                        g_bConsoleLog = true;
484                        mainClient.enableDebug(true);
485                        if (!mainClient.initCore(true)) {
486                                LOG_ERROR_STD(_T("Service *NOT* started!"));
487                                return -1;
488                        }
489                        LOG_MESSAGE_STD(_T("Using settings from: ") + settings_manager::get_core()->get_settings_type_desc());
490                        LOG_MESSAGE(_T("Enter command to inject or exit to terminate..."));
491/*
492                        Settings::get_settings()->clear_cache();
493                        LOG_MESSAGE_STD( _T("test 001: ") + SETTINGS_GET_STRING(NSCLIENT_TEST1) );
494                        LOG_MESSAGE_STD( _T("test 002: ") + SETTINGS_GET_STRING(NSCLIENT_TEST2) );
495                        LOG_MESSAGE_STD( _T("test 003: ") + SETTINGS_GET_STRING(NSCLIENT_TEST3) );
496                        LOG_MESSAGE_STD( _T("test 004: ") + SETTINGS_GET_STRING(NSCLIENT_TEST4) );
497
498                        Settings::get_settings()->save_to(_T("test.ini"));
499*/
500                        std::wstring s = _T("");
501                        std::wstring buff = _T("");
502                        while (true) {
503                                std::wcin >> s;
504                                if (s == _T("exit")) {
505                                        std::wcout << _T("Exiting...") << std::endl;
506                                        break;
507                                } else if (s == _T("plugins")) {
508                                        std::wcout << _T("Listing plugins...") << std::endl;
509                                        mainClient.listPlugins();
510                                } else if (s == _T("off") && buff == _T("debug ")) {
511                                        std::wcout << _T("Setting debug log off...") << std::endl;
512                                        mainClient.enableDebug(false);
513                                } else if (s == _T("on") && buff == _T("debug ")) {
514                                        std::wcout << _T("Setting debug log on...") << std::endl;
515                                        mainClient.enableDebug(true);
516                                } else if (s == _T("reattach")) {
517                                        std::wcout << _T("Reattaching to session 0") << std::endl;
518                                        mainClient.startTrayIcon(0);
519//#ifdef DEBUG
520                                } else if (s == _T("assert")) {
521                                        throw "test";
522//#endif
523                                } else if (std::cin.peek() < 15) {
524                                        buff += s;
525                                        strEx::token t = strEx::getToken(buff, ' ');
526                                        std::wstring msg, perf;
527                                        NSCAPI::nagiosReturn ret = mainClient.inject(t.first, t.second, ' ', true, msg, perf);
528                                        if (ret == NSCAPI::returnIgnored) {
529                                                std::wcout << _T("No handler for command: ") << t.first << std::endl;
530                                        } else {
531                                                std::wcout << NSCHelper::translateReturn(ret) << _T(":");
532                                                std::cout << strEx::wstring_to_string(msg);
533                                                if (!perf.empty())
534                                                        std::cout << "|" << strEx::wstring_to_string(perf);
535                                                std::wcout << std::endl;
536                                        }
537                                        buff = _T("");
538                                } else {
539                                        buff += s + _T(" ");
540                                }
541                        }
542                        mainClient.exitCore(true);
543                        return 0;
544                } else {
545                        std::wcerr << _T("Usage: -version, -about, -install, -uninstall, -start, -stop, -encrypt -settings") << std::endl;
546                        std::wcerr << _T("Usage: [-noboot] <ModuleName> <commnd> [arguments]") << std::endl;
547                        return -1;
548                }
549                return nRetCode;
550        } else if (argc > 2) {
551                g_bConsoleLog = true;
552                mainClient.initCore(true);
553                if (argc>=3)
554                        nRetCode = mainClient.commandLineExec(argv[1], argv[2], argc-3, &argv[3]);
555                else
556                        nRetCode = mainClient.commandLineExec(argv[1], argv[2], 0, NULL);
557                mainClient.exitCore(true);
558                return nRetCode;
559        } else if (argc > 1) {
560                g_bConsoleLog = true;
561                mainClient.enableDebug(true);
562                std::wcerr << _T("Invalid command line argument: ") << argv[1] << std::endl;
563                std::wcerr << _T("Usage: -version, -about, -install, -uninstall, -start, -stop, -encrypt") << std::endl;
564                std::wcerr << _T("Usage: [-noboot] <ModuleName> <commnd> [arguments]") << std::endl;
565                return -1;
566        }
567        std::wcout << _T("Running as service...") << std::endl;
568        if (!mainClient.StartServiceCtrlDispatcher()) {
569                LOG_MESSAGE(_T("We failed to start the service"));
570        }
571        return nRetCode;
572}
573
574void migrate() {}
575
576NSClientT::plugin_info_list NSClientT::get_all_plugins() {
577        plugin_info_list ret;
578        boost::filesystem::wpath pluginPath = getBasePath() / boost::filesystem::wpath(_T("modules"));
579        boost::filesystem::wdirectory_iterator end_itr; // default construction yields past-the-end
580        for ( boost::filesystem::wdirectory_iterator itr( pluginPath ); itr != end_itr; ++itr ) {
581                if ( !is_directory(itr->status()) ) {
582                        boost::filesystem::wpath file= itr->leaf();
583                        if (is_module(pluginPath  / file)) {
584                                plugin_info_type info;
585                                info.dll = itr->leaf();
586                                try {
587                                        LOG_DEBUG_STD(_T("Attempting to fake load: ") + file.string());
588                                        NSCPlugin plugin(pluginPath / file);
589                                        plugin.load_dll();
590                                        plugin.load_plugin(NSCAPI::dontStart);
591                                        info.name = plugin.getName();
592                                        info.description = plugin.getDescription();
593                                        plugin.unload();
594                                } catch (NSPluginException e) {
595                                        LOG_CRITICAL_STD(_T("Error loading: ") + e.file_ + _T(" root cause: ") + e.error_);
596                                } catch (...) {
597                                        LOG_CRITICAL_STD(_T("Unknown Error loading: ") + file.string());
598                                }
599                                ret.push_back(info);
600                        }
601                }
602        }
603        return ret;
604}
605
606
607void NSClientT::load_all_plugins(int mode) {
608        boost::filesystem::wpath modPath = getBasePath() / boost::filesystem::wpath(_T("modules"));
609
610        boost::filesystem::wdirectory_iterator end_itr; // default construction yields past-the-end
611        for ( boost::filesystem::wdirectory_iterator itr( modPath ); itr != end_itr; ++itr ) {
612                if ( !is_directory(itr->status()) ) {
613                        boost::filesystem::wpath file= itr->leaf();
614                        if (is_module(modPath / file)) {
615                                if (settings_manager::get_settings()->has_key(MAIN_MODULES_SECTION, file.string())) {
616                                        if (settings_manager::get_settings()->get_string(MAIN_MODULES_SECTION, file.string()) == _T("disabled")) {
617                                                try {
618                                                        LOG_DEBUG_STD(_T("Attempting to fake load: ") + file.string());
619                                                        NSCPlugin plugin(modPath / file);
620                                                        plugin.load_dll();
621                                                        plugin.load_plugin(mode);
622                                                        plugin.unload();
623                                                } catch (NSPluginException e) {
624                                                        LOG_CRITICAL_STD(_T("Error loading: ") + e.file_ + _T(" root cause: ") + e.error_);
625                                                } catch (...) {
626                                                        LOG_CRITICAL_STD(_T("Unknown Error loading: ") + file.string());
627                                                }
628                                        }
629                                } else {
630                                        std::wstring desc;
631                                        try {
632                                                NSCPlugin plugin(modPath / file);
633                                                plugin.load_dll();
634                                                plugin.load_plugin(mode);
635                                                desc = plugin.getName() + _T(" - ");
636                                                desc += plugin.getDescription();
637                                                plugin.unload();
638                                        } catch (NSPluginException e) {
639                                                desc += _T("unknown module");
640                                                LOG_CRITICAL_STD(_T("Error loading: ") + e.file_ + _T(" root cause: ") + e.error_);
641                                        } catch (...) {
642                                                desc += _T("unknown module");
643                                                LOG_CRITICAL_STD(_T("Unknown Error loading: ") + file.string());
644                                        }
645                                        settings_manager::get_core()->register_key(MAIN_MODULES_SECTION, file.string(), Settings::SettingsCore::key_string, desc, desc, _T("disabled"), false);
646                                }
647                        }
648                }
649        }
650}
651
652void NSClientT::HandleSettingsCLI(wchar_t* arg, int argc, wchar_t* argv[]) {
653        std::wstring sarg = arg;
654        try {
655                if (sarg == _T("migrate")) {
656                        if (argc == 0) {
657                                LOG_ERROR_STD(_T("In correct syntax: nsclient++ -settings migrate <to>"));
658                                return;
659                        }
660                        std::wstring to = argv[0];
661                        LOG_DEBUG_STD(_T("Migrating to: ") + to);
662                        try {
663                                settings_manager::get_core()->migrate_to(Settings::SettingsCore::string_to_type(to));
664                        } catch (SettingsException e) {
665                                LOG_CRITICAL_STD(_T("Failed to migrate settings: ") + e.getError());
666                        }
667                } else if (sarg == _T("generate")) {
668                        if (argc == 0) {
669                                LOG_ERROR_STD(_T("In correct syntax: nsclient++ -settings generate <what>"));
670                                LOG_ERROR_STD(_T("     where <what> is one of ths following:"));
671                                LOG_ERROR_STD(_T("      trac"));
672                                LOG_ERROR_STD(_T("      default"));
673                                LOG_ERROR_STD(_T("      <type>"));
674                                return;
675                        }
676                        std::wstring arg1 = argv[0];
677                        if (arg1 == _T("default")) {
678                                try {
679                                        load_all_plugins(NSCAPI::dontStart);
680                                        settings_manager::get_core()->update_defaults();
681                                        settings_manager::get_core()->get()->save();
682                                } catch (SettingsException e) {
683                                        LOG_CRITICAL_STD(_T("Failed to migrate settings: ") + e.getError());
684                                }
685                        } else if (arg1 == _T("trac")) {
686                                try {
687                                        load_all_plugins(NSCAPI::dontStart);
688
689                                        Settings::string_list s = settings_manager::get_core()->get_reg_sections();
690                                        for (Settings::string_list::const_iterator cit = s.begin(); cit != s.end(); ++cit) {
691                                                std::wcout << _T("== ") << (*cit) << _T(" ==") << std::endl;
692                                                Settings::string_list k = settings_manager::get_core()->get_reg_keys(*cit);
693                                                bool first = true;
694                                                for (Settings::string_list::const_iterator citk = k.begin(); citk != k.end(); ++citk) {
695                                                        Settings::SettingsCore::key_description desc = settings_manager::get_core()->get_registred_key(*cit, *citk);
696                                                        if (!desc.advanced) {
697                                                                if (first)
698                                                                        std::wcout << _T("'''Normal settings'''") << std::endl;
699                                                                first = false;
700                                                                std::wcout << _T("||") << (*citk) << _T("||") << desc.defValue << _T("||") << desc.title << _T(": ") << desc.description
701                                                                        << std::endl;
702                                                        }
703                                                }
704                                                first = true;
705                                                for (Settings::string_list::const_iterator citk = k.begin(); citk != k.end(); ++citk) {
706                                                        Settings::SettingsCore::key_description desc = settings_manager::get_core()->get_registred_key(*cit, *citk);
707                                                        if (desc.advanced) {
708                                                                if (first)
709                                                                        std::wcout << _T("'''Advanced settings'''") << std::endl;
710                                                                first = false;
711                                                                std::wcout << _T("||") << (*citk) << _T("||") << desc.defValue << _T("||") << desc.title << _T(": ") << desc.description
712                                                                        << std::endl;
713                                                        }
714                                                }
715                                        }
716                                } catch (SettingsException e) {
717                                        LOG_CRITICAL_STD(_T("Failed to migrate settings: ") + e.getError());
718                                }
719                        } else {
720                                try {
721                                        Settings::SettingsCore::settings_type type = settings_manager::get_core()->string_to_type(arg1);
722                                        load_all_plugins(NSCAPI::dontStart);
723                                        settings_manager::get_core()->update_defaults();
724                                        settings_manager::get_core()->get(type)->save();
725                                } catch (SettingsException e) {
726                                        LOG_CRITICAL_STD(_T("Failed to migrate settings: ") + e.getError());
727                                }
728                        }
729                } else {
730                        LOG_ERROR_STD(_T("In correct syntax: nsclient++ -settings <keyword>"));
731                        LOG_ERROR_STD(_T(" <keyword> : "));
732                        LOG_ERROR_STD(_T("   migrate - migrate to a new setings subsystem"));
733                        LOG_ERROR_STD(_T("   copy    - copy settings from one subsystem to another"));
734                        LOG_ERROR_STD(_T("   set     - Set a setting system as the default store"));
735                }
736
737
738        } catch (SettingsException e) {
739                LOG_CRITICAL_STD(_T("Failed to initialize settings: ") + e.getError());
740        } catch (...) {
741                LOG_CRITICAL(_T("FATAL ERROR IN SETTINGS SUBSYTEM"));
742        }
743
744}
745
746void NSClientT::session_error(std::wstring file, unsigned int line, std::wstring msg) {
747        NSAPIMessage(NSCAPI::error, file.c_str(), line, msg.c_str());
748}
749
750void NSClientT::session_info(std::wstring file, unsigned int line, std::wstring msg) {
751        NSAPIMessage(NSCAPI::log, file.c_str(), line, msg.c_str());
752}
753
754
755
756
757//////////////////////////////////////////////////////////////////////////
758// Service functions
759
760/**
761 * Initialize the program
762 * @param boot true if we shall boot all plugins
763 * @param attachIfPossible is true we will attach to a running instance.
764 * @return success
765 * @author mickem
766 */
767bool NSClientT::initCore(bool boot) {
768        LOG_MESSAGE(_T("Attempting to start NSCLient++ - ") SZVERSION);
769        if (!settings_manager::init_settings(getBasePath())) {
770                return false;
771        }
772        try {
773                if (debug_)
774                        settings_manager::get_settings()->set_int(_T("log"), _T("debug"), 1);
775                        settings_manager::get_settings()->set_int(_T("Settings"), _T("shared_Session"), 1);
776                enable_shared_session_ = SETTINGS_GET_BOOL_CORE(settings_def::SHARED_SESSION);
777        } catch (SettingsException e) {
778                LOG_ERROR_STD(_T("Could not find settings: ") + e.getMessage());
779        }
780
781        if (enable_shared_session_) {
782                LOG_MESSAGE_STD(_T("Enabling shared session..."));
783                if (boot) {
784                        LOG_MESSAGE_STD(_T("Starting shared session..."));
785//                      try {
786//                              shared_server_.reset(new nsclient_session::shared_server_session(this));
787//                              if (!shared_server_->session_exists()) {
788//                                      shared_server_->create_new_session();
789//                              } else {
790//                                      LOG_ERROR_STD(_T("Session already exists cant create a new one!"));
791//                              }
792//                              startTrayIcons();
793//                      } catch (nsclient_session::session_exception e) {
794//                              LOG_ERROR_STD(_T("Failed to create new session: ") + e.what());
795//                              shared_server_.reset(NULL);
796//                      } catch (...) {
797//                              LOG_ERROR_STD(_T("Failed to create new session: Unknown exception"));
798//                              shared_server_.reset(NULL);
799//                      }
800                } else {
801                        LOG_MESSAGE_STD(_T("Attaching to shared session..."));
802//                      try {
803//                              std::wstring id = _T("_attached_") + strEx::itos(GetCurrentProcessId()) + _T("_");
804//                              shared_client_.reset(new nsclient_session::shared_client_session(id, this));
805//                              if (shared_client_->session_exists()) {
806//                                      shared_client_->attach_to_session(id);
807//                              } else {
808//                                      LOG_ERROR_STD(_T("No session was found cant attach!"));
809//                              }
810//                              LOG_ERROR_STD(_T("Session is: ") + shared_client_->get_client_id());
811//                      } catch (nsclient_session::session_exception e) {
812//                              LOG_ERROR_STD(_T("Failed to attach to session: ") + e.what());
813//                              shared_client_.reset(NULL);
814//                      } catch (...) {
815//                              LOG_ERROR_STD(_T("Failed to attach to session: Unknown exception"));
816//                              shared_client_.reset(NULL);
817//                      }
818                }
819        }
820/*
821        try {
822                simpleSocket::WSAStartup();
823        } catch (simpleSocket::SocketException e) {
824                LOG_ERROR_STD(_T("Socket exception: ") + e.getMessage());
825                return false;
826        } catch (...) {
827                LOG_ERROR_STD(_T("Unknown exception iniating socket..."));
828                return false;
829        }
830*/
831#ifdef WIN32
832        try {
833                com_helper_.initialize();
834        } catch (com_helper::com_exception e) {
835                LOG_ERROR_STD(_T("COM exception: ") + e.getMessage());
836                return false;
837        } catch (...) {
838                LOG_ERROR_STD(_T("Unknown exception iniating COM..."));
839                return false;
840        }
841#endif
842        if (boot) {
843                try {
844                        Settings::string_list list = settings_manager::get_settings()->get_keys(MAIN_MODULES_SECTION);
845                        for (Settings::string_list::const_iterator cit = list.begin(); cit != list.end(); ++cit) {
846                                LOG_DEBUG_STD(_T("Processing plugin: " + *cit));
847                                try {
848                                        if (settings_manager::get_settings()->get_string(MAIN_MODULES_SECTION, *cit) == _T("disabled")) {
849                                                LOG_DEBUG_STD(_T("Not booting: ") + *cit + _T(" since it is disabled."));
850                                                continue;
851                                        }
852                                } catch (...) {
853                                        // If we except we load the plugin in as-is
854                                }
855                                try {
856                                        loadPlugin(getBasePath() / boost::filesystem::wpath(_T("modules")) / boost::filesystem::wpath(*cit));
857                                } catch(const NSPluginException& e) {
858                                        LOG_ERROR_STD(_T("Exception raised: '") + e.error_ + _T("' in module: ") + e.file_);
859                                        //return false;
860                                } catch (std::exception e) {
861                                        LOG_ERROR_STD(_T("exception loading plugin: ") + (*cit) + strEx::string_to_wstring(e.what()));
862                                        return false;
863                                } catch (...) {
864                                        LOG_ERROR_STD(_T("Unknown exception loading plugin: ") + (*cit));
865                                        return false;
866                                }
867                        }
868                } catch (SettingsException e) {
869                        LOG_ERROR_STD(_T("Failed to set settings file") + e.getMessage());
870                } catch (...) {
871                        LOG_ERROR_STD(_T("Unknown exception when loading plugins"));
872                        return false;
873                }
874                try {
875                        loadPlugins(boot?NSCAPI::normalStart:NSCAPI::dontStart);
876                } catch (...) {
877                        LOG_ERROR_STD(_T("Unknown exception loading plugins"));
878                        return false;
879                }
880                LOG_DEBUG_STD(_T("NSCLient++ - ") SZVERSION _T(" Started!"));
881        }
882        LOG_MESSAGE_STD(_T("NSCLient++ - ") SZVERSION _T(" Started!"));
883        return true;
884}
885
886/**
887 * Service control handler startup point.
888 * When the program is started as a service this will be the entry point.
889 */
890bool NSClientT::InitiateService() {
891        if (!initCore(true))
892                return false;
893/*
894        DWORD dwSessionId = remote_processes::getActiveSessionId();
895        if (dwSessionId != 0xFFFFFFFF)
896                tray_starter::start(dwSessionId);
897        else
898                LOG_ERROR_STD(_T("Failed to start tray helper:" ) + error::lookup::last_error());
899                */
900        return true;
901}
902
903void NSClientT::startTrayIcons() {
904//      if (shared_server_.get() == NULL) {
905//              LOG_MESSAGE_STD(_T("No master session so tray icons not started"));
906//              return;
907//      }
908//      remote_processes::PWTS_SESSION_INFO list;
909//      DWORD count;
910//      if (!remote_processes::_WTSEnumerateSessions(WTS_CURRENT_SERVER_HANDLE , 0, 1, &list, &count)) {
911//              LOG_ERROR_STD(_T("Failed to enumerate sessions:" ) + error::lookup::last_error());
912//      } else {
913//              LOG_DEBUG_STD(_T("Found ") + strEx::itos(count) + _T(" sessions"));
914//              for (DWORD i=0;i<count;i++) {
915//                      LOG_DEBUG_STD(_T("Found session: ") + strEx::itos(list[i].SessionId) + _T(" state: ") + strEx::itos(list[i].State));
916//                      if (list[i].State == remote_processes::_WTS_CONNECTSTATE_CLASS::WTSActive) {
917//                              startTrayIcon(list[i].SessionId);
918//                      }
919//              }
920//      }
921}
922void NSClientT::startTrayIcon(DWORD dwSessionId) {
923//      if (shared_server_.get() == NULL) {
924//              LOG_MESSAGE_STD(_T("No master session so tray icons not started"));
925//              return;
926//      }
927//      if (!shared_server_->re_attach_client(dwSessionId)) {
928//              if (!tray_starter::start(dwSessionId)) {
929//                      LOG_ERROR_STD(_T("Failed to start session (") + strEx::itos(dwSessionId) + _T("): " ) + error::lookup::last_error());
930//              }
931//      }
932}
933
934bool NSClientT::exitCore(bool boot) {
935        plugins_loaded_ = false;
936        LOG_DEBUG(_T("Attempting to stop NSCLient++ - ") SZVERSION);
937        if (boot) {
938                try {
939                        LOG_DEBUG_STD(_T("Stopping: NON Message Handling Plugins"));
940                        mainClient.unloadPlugins(false);
941                } catch(NSPluginException e) {
942                        LOG_ERROR_STD(_T("Exception raised when unloading non msg plguins: ") + e.error_ + _T(" in module: ") + e.file_);
943                } catch(...) {
944                        LOG_ERROR_STD(_T("Unknown exception raised when unloading non msg plugins"));
945                }
946        }
947#ifdef WIN32
948        LOG_DEBUG_STD(_T("Stopping: COM helper"));
949        try {
950                com_helper_.unInitialize();
951        } catch (com_helper::com_exception e) {
952                LOG_ERROR_STD(_T("COM exception: ") + e.getMessage());
953        } catch (...) {
954                LOG_ERROR_STD(_T("Unknown exception uniniating COM..."));
955        }
956#endif
957        /*
958        LOG_DEBUG_STD(_T("Stopping: Socket Helpers"));
959        try {
960                simpleSocket::WSACleanup();
961        } catch (simpleSocket::SocketException e) {
962                LOG_ERROR_STD(_T("Socket exception: ") + e.getMessage());
963        } catch (...) {
964                LOG_ERROR_STD(_T("Unknown exception uniniating socket..."));
965        }
966        */
967        LOG_DEBUG_STD(_T("Stopping: Settings instance"));
968        settings_manager::destroy_settings();
969//      try {
970//              if (shared_client_.get() != NULL) {
971//                      LOG_DEBUG_STD(_T("Stopping: shared client"));
972//                      shared_client_->set_handler(NULL);
973//                      shared_client_->close_session();
974//              }
975//      } catch(nsclient_session::session_exception &e) {
976//              LOG_ERROR_STD(_T("Exception closing shared client session: ") + e.what());
977//      } catch(...) {
978//              LOG_ERROR_STD(_T("Exception closing shared client session: Unknown exception!"));
979//      }
980        try {
981//              if (shared_server_.get() != NULL) {
982//                      LOG_DEBUG_STD(_T("Stopping: shared server"));
983//                      shared_server_->set_handler(NULL);
984//                      shared_server_->close_session();
985//              }
986        } catch(...) {
987                LOG_ERROR_STD(_T("UNknown exception raised: When closing shared session"));
988        }
989        if (boot) {
990                try {
991                        LOG_DEBUG_STD(_T("Stopping: Message handling Plugins"));
992                        mainClient.unloadPlugins(true);
993                } catch(NSPluginException e) {
994                        LOG_ERROR_STD(_T("Exception raised when unloading msg plugins: ") + e.error_ + _T(" in module: ") + e.file_);
995                } catch(...) {
996                        LOG_ERROR_STD(_T("UNknown exception raised: When stopping message plguins"));
997                }
998        }
999        LOG_MESSAGE_STD(_T("NSCLient++ - ") SZVERSION _T(" Stopped succcessfully"));
1000        return true;
1001}
1002/**
1003 * Service control handler termination point.
1004 * When the program is stopped as a service this will be the "exit point".
1005 */
1006void NSClientT::TerminateService(void) {
1007        exitCore(true);
1008}
1009#ifdef WIN32x
1010/**
1011 * Forward this to the main service dispatcher helper class
1012 * @param dwArgc
1013 * @param *lpszArgv
1014 */
1015void WINAPI NSClientT::service_main_dispatch(DWORD dwArgc, LPTSTR *lpszArgv) {
1016        try {
1017                //WTF!!! mainClient.service_main(dwArgc, lpszArgv);
1018        } catch (service_helper::service_exception e) {
1019                LOG_ERROR_STD(_T("Unknown service error: ") + e.what());
1020        } catch (...) {
1021                LOG_ERROR_STD(_T("Unknown service error!"));
1022        }
1023}
1024DWORD WINAPI NSClientT::service_ctrl_dispatch_ex(DWORD dwControl, DWORD dwEventType, LPVOID lpEventData, LPVOID lpContext) {
1025        return mainClient.service_ctrl_ex(dwControl, dwEventType, lpEventData, lpContext);
1026}
1027/**
1028 * Forward this to the main service dispatcher helper class
1029 * @param dwCtrlCode
1030 */
1031void WINAPI NSClientT::service_ctrl_dispatch(unsigned long dwCtrlCode) {
1032        mainClient.service_ctrl_ex(dwCtrlCode, NULL, NULL, NULL);
1033}
1034#endif
1035
1036void NSClientT::service_on_session_changed(unsigned long dwSessionId, bool logon, unsigned long dwEventType) {
1037//      if (shared_server_.get() == NULL) {
1038//              LOG_DEBUG_STD(_T("No shared session: ignoring change event!"));
1039//              return;
1040//      }
1041        LOG_DEBUG_STD(_T("Got session change: ") + strEx::itos(dwSessionId));
1042        if (!logon) {
1043                LOG_DEBUG_STD(_T("Not a logon event: ") + strEx::itos(dwEventType));
1044                return;
1045        }
1046        tray_starter::start(dwSessionId);
1047}
1048
1049//////////////////////////////////////////////////////////////////////////
1050// Member functions
1051
1052int NSClientT::commandLineExec(const wchar_t* module, const wchar_t* command, const unsigned int argLen, wchar_t** args) {
1053        std::wstring sModule = module;
1054        std::wstring moduleList = _T("");
1055        {
1056                boost::shared_lock<boost::shared_mutex> readLock(m_mutexRW, boost::get_system_time() + boost::posix_time::seconds(5));
1057                if (!readLock.owns_lock()) {
1058                        LOG_ERROR(_T("FATAL ERROR: Could not get read-mutex."));
1059                        return -1;
1060                }
1061                for (pluginList::size_type i=0;i<plugins_.size();++i) {
1062                        NSCPlugin *p = plugins_[i];
1063                        if (!moduleList.empty())
1064                                moduleList += _T(", ");
1065                        moduleList += p->getModule();
1066                        if (p->getModule() == sModule) {
1067                                LOG_DEBUG_STD(_T("Found module: ") + p->getName() + _T("..."));
1068                                try {
1069                                        return p->commandLineExec(command, argLen, args);
1070                                } catch (NSPluginException e) {
1071                                        LOG_ERROR_STD(_T("Could not execute command: ") + e.error_ + _T(" in ") + e.file_);
1072                                        return -1;
1073                                }
1074                        }
1075                }
1076        }
1077        try {
1078                plugin_type plugin = loadPlugin(getBasePath() / boost::filesystem::wpath(_T("modules")) / boost::filesystem::wpath(module));
1079                LOG_DEBUG_STD(_T("Loading plugin: ") + plugin->getName() + _T("..."));
1080                plugin->load_plugin(NSCAPI::dontStart);
1081                return plugin->commandLineExec(command, argLen, args);
1082        } catch (NSPluginException e) {
1083                LOG_MESSAGE_STD(_T("Module (") + e.file_ + _T(") was not found: ") + e.error_);
1084        }
1085        LOG_ERROR_STD(_T("Module not found: ") + module + _T(" available modules are: ") + moduleList);
1086        return 0;
1087}
1088
1089/**
1090 * Load a list of plug-ins
1091 * @param plugins A list with plug-ins (DLL files) to load
1092 */
1093void NSClientT::addPlugins(const std::list<std::wstring> plugins) {
1094        boost::shared_lock<boost::shared_mutex> readLock(m_mutexRW, boost::get_system_time() + boost::posix_time::seconds(10));
1095        if (!readLock.owns_lock()) {
1096                LOG_ERROR(_T("FATAL ERROR: Could not get read-mutex."));
1097                return;
1098        }
1099        std::list<std::wstring>::const_iterator it;
1100        for (it = plugins.begin(); it != plugins.end(); ++it) {
1101                loadPlugin(*it);
1102        }
1103}
1104/**
1105 * Unload all plug-ins (in reversed order)
1106 */
1107void NSClientT::unloadPlugins(bool unloadLoggers) {
1108        {
1109                boost::unique_lock<boost::shared_mutex> writeLock(m_mutexRW, boost::get_system_time() + boost::posix_time::seconds(10));
1110                if (!writeLock.owns_lock()) {
1111                        LOG_ERROR(_T("FATAL ERROR: Could not get read-mutex."));
1112                        return;
1113                }
1114                commandHandlers_.clear();
1115                if (unloadLoggers)
1116                        messageHandlers_.clear();
1117        }
1118        {
1119                boost::shared_lock<boost::shared_mutex> readLock(m_mutexRW, boost::get_system_time() + boost::posix_time::milliseconds(5000));
1120                if (!readLock.owns_lock()) {
1121                        LOG_ERROR(_T("FATAL ERROR: Could not get read-mutex."));
1122                        return;
1123                }
1124                for (pluginList::reverse_iterator it = plugins_.rbegin(); it != plugins_.rend(); ++it) {
1125                        NSCPlugin *p = *it;
1126                        if (p == NULL)
1127                                continue;
1128                        try {
1129                                if (unloadLoggers || !p->hasMessageHandler()) {
1130                                        LOG_DEBUG_STD(_T("Unloading plugin: ") + p->getModule() + _T("..."));
1131                                        p->unload();
1132                                } else {
1133                                        LOG_DEBUG_STD(_T("Skipping log plugin: ") + p->getModule() + _T("..."));
1134                                }
1135                        } catch(NSPluginException e) {
1136                                LOG_ERROR_STD(_T("Exception raised when unloading plugin: ") + e.error_ + _T(" in module: ") + e.file_);
1137                        } catch(...) {
1138                                LOG_ERROR_STD(_T("Unknown exception raised when unloading plugin"));
1139                        }
1140                }
1141        }
1142        {
1143                boost::unique_lock<boost::shared_mutex> writeLock(m_mutexRW, boost::get_system_time() + boost::posix_time::seconds(10));
1144                if (!writeLock.owns_lock()) {
1145                        LOG_ERROR(_T("FATAL ERROR: Could not get read-mutex."));
1146                        return;
1147                }
1148                for (pluginList::iterator it = plugins_.begin(); it != plugins_.end();) {
1149                        NSCPlugin *p = (*it);
1150                        try {
1151                                if (p != NULL && (unloadLoggers|| !p->isLoaded())) {
1152                                        it = plugins_.erase(it);
1153                                        delete p;
1154                                        continue;
1155                                }
1156                        } catch(NSPluginException e) {
1157                                LOG_ERROR_STD(_T("Exception raised when unloading plugin: ") + e.error_ + _T(" in module: ") + e.file_);
1158                        } catch(...) {
1159                                LOG_ERROR_STD(_T("Unknown exception raised when unloading plugin"));
1160                        }
1161                        it++;
1162                }
1163        }
1164}
1165
1166void NSClientT::loadPlugins(NSCAPI::moduleLoadMode mode) {
1167        bool hasBroken = false;
1168        {
1169                boost::shared_lock<boost::shared_mutex> readLock(m_mutexRW, boost::get_system_time() + boost::posix_time::milliseconds(5000));
1170                if (!readLock.owns_lock()) {
1171                        LOG_ERROR(_T("FATAL ERROR: Could not get read-mutex."));
1172                        return;
1173                }
1174                for (pluginList::iterator it=plugins_.begin(); it != plugins_.end();) {
1175                        LOG_DEBUG_STD(_T("Loading plugin: ") + (*it)->getName() + _T("..."));
1176                        try {
1177                                if (!(*it)->load_plugin(NSCAPI::normalStart)) {
1178                                        it = plugins_.erase(it);
1179                                        LOG_ERROR_STD(_T("Plugin refused to load: ") + (*it)->getModule());
1180                                }
1181                                ++it;
1182                        } catch (NSPluginException e) {
1183                                it = plugins_.erase(it);
1184                                LOG_ERROR_STD(_T("Could not load plugin: ") + e.file_ + _T(": ") + e.error_);
1185                        } catch (...) {
1186                                it = plugins_.erase(it);
1187                                LOG_ERROR_STD(_T("Could not load plugin: ") + (*it)->getModule());
1188                        }
1189                }
1190        }
1191        for (pluginList::iterator it=plugins_.begin(); it != plugins_.end();) {
1192                LOG_DEBUG_STD(_T("Loading plugin: ") + (*it)->getName() + _T("..."));
1193                try {
1194                        (*it)->load_plugin(mode);
1195                        ++it;
1196                } catch(NSPluginException e) {
1197                        it = plugins_.erase(it);
1198                        LOG_ERROR_STD(_T("Exception raised when loading plugin: ") + e.error_ + _T(" in module: ") + e.file_ + _T(" plugin has been removed."));
1199                } catch(...) {
1200                        it = plugins_.erase(it);
1201                        LOG_ERROR_STD(_T("Unknown exception raised when unloading plugin plugin has been removed"));
1202                }
1203        }
1204        plugins_loaded_ = true;
1205}
1206/**
1207 * Load a single plug-in using a DLL filename
1208 * @param file The DLL file
1209 */
1210NSClientT::plugin_type NSClientT::loadPlugin(const boost::filesystem::wpath file) {
1211        return addPlugin(new NSCPlugin(file));
1212}
1213/**
1214 * Load and add a plugin to various internal structures
1215 * @param plugin The plug-in instance to load. The pointer is managed by the
1216 */
1217NSClientT::plugin_type NSClientT::addPlugin(plugin_type plugin) {
1218        plugin->load_dll();
1219        {
1220                boost::unique_lock<boost::shared_mutex> writeLock(m_mutexRW, boost::get_system_time() + boost::posix_time::seconds(10));
1221                if (!writeLock.owns_lock()) {
1222                        LOG_ERROR(_T("FATAL ERROR: Could not get read-mutex."));
1223                        return plugin;
1224                }
1225                plugins_.insert(plugins_.end(), plugin);
1226                if (plugin->hasCommandHandler())
1227                        commandHandlers_.insert(commandHandlers_.end(), plugin);
1228                if (plugin->hasMessageHandler())
1229                        messageHandlers_.insert(messageHandlers_.end(), plugin);
1230                settings_manager::get_core()->register_key(_T("/modules"), plugin->getFilename(), Settings::SettingsCore::key_string, plugin->getName(), plugin->getDescription(), _T(""), false);
1231        }
1232        return plugin;
1233}
1234
1235
1236std::wstring NSClientT::describeCommand(std::wstring command) {
1237        boost::shared_lock<boost::shared_mutex> readLock(m_mutexRWcmdDescriptions, boost::get_system_time() + boost::posix_time::seconds(5));
1238        if (!readLock.owns_lock()) {
1239                LOG_ERROR(_T("FATAL ERROR: Could not get read-mutex when trying to get command list."));
1240                return _T("Failed to get mutex when describing command: ") + command;
1241        }
1242        cmdMap::const_iterator cit = cmdDescriptions_.find(command);
1243        if (cit == cmdDescriptions_.end())
1244                return _T("Command not found: ") + command + _T(", maybe it has not been register?");
1245        return (*cit).second;
1246}
1247std::list<std::wstring> NSClientT::getAllCommandNames() {
1248        std::list<std::wstring> lst;
1249        boost::shared_lock<boost::shared_mutex> readLock(m_mutexRWcmdDescriptions, boost::get_system_time() + boost::posix_time::seconds(5));
1250        if (!readLock.owns_lock()) {
1251                LOG_ERROR(_T("FATAL ERROR: Could not get read-mutex when trying to get command list."));
1252                return lst;
1253        }
1254        for (cmdMap::const_iterator cit = cmdDescriptions_.begin(); cit != cmdDescriptions_.end(); ++cit) {
1255                lst.push_back((*cit).first);
1256        }
1257        return lst;
1258}
1259void NSClientT::registerCommand(std::wstring cmd, std::wstring desc) {
1260        boost::unique_lock<boost::shared_mutex> writeLock(m_mutexRWcmdDescriptions, boost::get_system_time() + boost::posix_time::seconds(10));
1261        if (!writeLock.owns_lock()) {
1262                LOG_ERROR_STD(_T("FATAL ERROR: Failed to describe command:") + cmd);
1263                return;
1264        }
1265        cmdDescriptions_[cmd] = desc;
1266}
1267
1268unsigned int NSClientT::getBufferLength() {
1269        static unsigned int len = 0;
1270        if (len == 0) {
1271                try {
1272                        len = settings_manager::get_settings()->get_int(SETTINGS_KEY(settings_def::PAYLOAD_LEN));
1273                } catch (SettingsException &e) {
1274                        LOG_DEBUG_STD(_T("Failed to get length: ") + e.getMessage());
1275                        return setting_keys::settings_def::PAYLOAD_LEN_DEFAULT;
1276                } catch (...) {
1277                        LOG_ERROR(_T("Failed to get length: :("));
1278                        return setting_keys::settings_def::PAYLOAD_LEN_DEFAULT;
1279                }
1280        }
1281        return len;
1282}
1283
1284NSCAPI::nagiosReturn NSClientT::inject(std::wstring command, std::wstring arguments, wchar_t splitter, bool escape, std::wstring &msg, std::wstring & perf) {
1285        /*if (shared_client_.get() != NULL && shared_client_->hasMaster()) {
1286                try {
1287                        return shared_client_->inject(command, arguments, splitter, escape, msg, perf);
1288                } catch (nsclient_session::session_exception &e) {
1289                        LOG_ERROR_STD(_T("Failed to inject remote command: ") + e.what());
1290                        return NSCAPI::returnCRIT;
1291                } catch (...) {
1292                        LOG_ERROR_STD(_T("Failed to inject remote command: Unknown exception"));
1293                        return NSCAPI::returnCRIT;
1294                }
1295        } else */{
1296                unsigned int aLen = 0;
1297                wchar_t ** aBuf = arrayBuffer::split2arrayBuffer(arguments, splitter, aLen, escape);
1298                unsigned int buf_len = getBufferLength();
1299                wchar_t * mBuf = new wchar_t[buf_len+1]; mBuf[0] = '\0';
1300                wchar_t * pBuf = new wchar_t[buf_len+1]; pBuf[0] = '\0';
1301                NSCAPI::nagiosReturn ret = injectRAW(command.c_str(), aLen, aBuf, mBuf, buf_len, pBuf, buf_len);
1302                arrayBuffer::destroyArrayBuffer(aBuf, aLen);
1303                if ( (ret == NSCAPI::returnInvalidBufferLen) || (ret == NSCAPI::returnIgnored) ) {
1304                        delete [] mBuf;
1305                        delete [] pBuf;
1306                        return ret;
1307                }
1308                msg = mBuf;
1309                perf = pBuf;
1310                delete [] mBuf;
1311                delete [] pBuf;
1312                return ret;
1313        }
1314}
1315
1316/**
1317 * Inject a command into the plug-in stack.
1318 *
1319 * @param command Command to inject
1320 * @param argLen Length of argument buffer
1321 * @param **argument Argument buffer
1322 * @param *returnMessageBuffer Message buffer
1323 * @param returnMessageBufferLen Length of returnMessageBuffer
1324 * @param *returnPerfBuffer Performance data buffer
1325 * @param returnPerfBufferLen Length of returnPerfBuffer
1326 * @return The command status
1327 */
1328NSCAPI::nagiosReturn NSClientT::injectRAW(const wchar_t* command, const unsigned int argLen, wchar_t **argument, wchar_t *returnMessageBuffer, unsigned int returnMessageBufferLen, wchar_t *returnPerfBuffer, unsigned int returnPerfBufferLen) {
1329        if (logDebug()) {
1330                LOG_DEBUG_STD(_T("Injecting: ") + (std::wstring) command + _T(": ") + arrayBuffer::arrayBuffer2string(argument, argLen, _T(", ")));
1331        }
1332        /*if (shared_client_.get() != NULL && shared_client_->hasMaster()) {
1333                try {
1334                        std::wstring msg, perf;
1335                        int returnCode = shared_client_->inject(command, arrayBuffer::arrayBuffer2string(argument, argLen, _T(" ")), L' ', true, msg, perf);
1336                        NSCHelper::wrapReturnString(returnMessageBuffer, returnMessageBufferLen, msg, returnCode);
1337                        return NSCHelper::wrapReturnString(returnPerfBuffer, returnPerfBufferLen, perf, returnCode);
1338                } catch (nsclient_session::session_exception &e) {
1339                        LOG_ERROR_STD(_T("Failed to inject remote command: ") + e.what());
1340                        int returnCode = NSCHelper::wrapReturnString(returnMessageBuffer, returnMessageBufferLen, _T("Failed to inject remote command: ") + e.what(), NSCAPI::returnCRIT);
1341                        return NSCHelper::wrapReturnString(returnPerfBuffer, returnPerfBufferLen, _T(""), returnCode);
1342                } catch (...) {
1343                        LOG_ERROR_STD(_T("Failed to inject remote command: Unknown exception"));
1344                        int returnCode = NSCHelper::wrapReturnString(returnMessageBuffer, returnMessageBufferLen, _T("Failed to inject remote command:  + e.what()"), NSCAPI::returnCRIT);
1345                        return NSCHelper::wrapReturnString(returnPerfBuffer, returnPerfBufferLen, _T(""), returnCode);
1346                }
1347        } else */{
1348                boost::shared_lock<boost::shared_mutex> readLock(m_mutexRW, boost::get_system_time() + boost::posix_time::milliseconds(5000));
1349                if (!readLock.owns_lock()) {
1350                        LOG_ERROR(_T("FATAL ERROR: Could not get read-mutex."));
1351                        return NSCAPI::returnUNKNOWN;
1352                }
1353                for (pluginList::size_type i = 0; i < commandHandlers_.size(); i++) {
1354                        try {
1355                                NSCAPI::nagiosReturn c = commandHandlers_[i]->handleCommand(command, argLen, argument, returnMessageBuffer, returnMessageBufferLen, returnPerfBuffer, returnPerfBufferLen);
1356                                switch (c) {
1357                                        case NSCAPI::returnInvalidBufferLen:
1358                                                LOG_ERROR(_T("UNKNOWN: Return buffer to small to handle this command."));
1359                                                return c;
1360                                        case NSCAPI::returnIgnored:
1361                                                break;
1362                                        case NSCAPI::returnOK:
1363                                        case NSCAPI::returnWARN:
1364                                        case NSCAPI::returnCRIT:
1365                                        case NSCAPI::returnUNKNOWN:
1366                                                LOG_DEBUG_STD(_T("Injected Result: ") + NSCHelper::translateReturn(c) + _T(" '") + (std::wstring)(returnMessageBuffer) + _T("'"));
1367                                                LOG_DEBUG_STD(_T("Injected Performance Result: '") +(std::wstring)(returnPerfBuffer) + _T("'"));
1368                                                return c;
1369                                        default:
1370                                                LOG_ERROR_STD(_T("Unknown error from handleCommand: ") + strEx::itos(c) + _T(" the injected command was: ") + (std::wstring)command);
1371                                                return c;
1372                                }
1373                        } catch(const NSPluginException& e) {
1374                                LOG_ERROR_STD(_T("Exception raised: ") + e.error_ + _T(" in module: ") + e.file_);
1375                                return NSCAPI::returnCRIT;
1376                        } catch(...) {
1377                                LOG_ERROR_STD(_T("Unknown exception raised in module"));
1378                                return NSCAPI::returnCRIT;
1379                        }
1380                }
1381                LOG_MESSAGE_STD(_T("No handler for command: '") + command + _T("'"));
1382                return NSCAPI::returnIgnored;
1383        }
1384}
1385
1386void NSClientT::listPlugins() {
1387        boost::shared_lock<boost::shared_mutex> readLock(m_mutexRW, boost::get_system_time() + boost::posix_time::milliseconds(5000));
1388        if (!readLock.owns_lock()) {
1389                LOG_ERROR(_T("FATAL ERROR: Could not get read-mutex."));
1390                return;
1391        }
1392        for (pluginList::iterator it=plugins_.begin(); it != plugins_.end(); ++it) {
1393                try {
1394                        if ((*it)->isBroken()) {
1395                                std::wcout << (*it)->getModule() << _T(": ") << _T("broken") << std::endl;
1396                        } else {
1397                                std::wcout << (*it)->getModule() << _T(": ") << (*it)->getName() << std::endl;
1398                        }
1399                } catch (NSPluginException e) {
1400                        LOG_ERROR_STD(_T("Could not load plugin: ") + e.file_ + _T(": ") + e.error_);
1401                }
1402        }
1403
1404}
1405
1406bool NSClientT::logDebug() {
1407        if (debug_ == log_unknown) {
1408                debug_ = log_looking;
1409                try {
1410                        if (settings_manager::get_settings()->get_int(_T("log"), _T("debug"), 0) == 1)
1411                                debug_ = log_debug;
1412                        else
1413                                debug_ = log_nodebug;
1414                } catch (SettingsException e) {
1415                        return true;
1416                }
1417        } else if (debug_ == log_looking)
1418                return true;
1419        return (debug_ == log_debug);
1420}
1421
1422void log_broken_message(std::wstring msg) {
1423#ifdef WIN32
1424        OutputDebugString(msg.c_str());
1425#endif
1426        std::wcout << msg << std::endl;
1427}
1428/**
1429 * Report a message to all logging enabled modules.
1430 *
1431 * @param msgType Message type
1432 * @param file Filename generally __FILE__
1433 * @param line  Line number, generally __LINE__
1434 * @param message The message as a human readable string.
1435 */
1436void NSClientT::reportMessage(int msgType, const wchar_t* file, const int line, std::wstring message) {
1437        try {
1438                strEx::replace(message, _T("\n"), _T(" "));
1439                strEx::replace(message, _T("\r"), _T(" "));
1440                if ((msgType == NSCAPI::debug)&&(!logDebug())) {
1441                        return;
1442                }
1443//              if (shared_server_.get() != NULL && shared_server_->hasClients()) {
1444//                      try {
1445//                              shared_server_->sendLogMessageToClients(msgType, file, line, message);
1446//                      } catch (nsclient_session::session_exception e) {
1447//                              log_broken_message(_T("Failed to send message to clients: ") + e.what());
1448//                      }
1449//              }
1450                std::wstring file_stl = file;
1451                std::wstring::size_type pos = file_stl.find_last_of(_T("\\"));
1452                if (pos != std::wstring::npos)
1453                        file_stl = file_stl.substr(pos);
1454                {
1455                        boost::shared_lock<boost::shared_mutex> readLock(m_mutexRW, boost::get_system_time() + boost::posix_time::milliseconds(5000));
1456                        if (!readLock.owns_lock()) {
1457                                log_broken_message(_T("Message was lost as the (mutexRW) core was locked: ") + message);
1458                                return;
1459                        }
1460                        boost::unique_lock<boost::timed_mutex> lock(messageMutex, boost::get_system_time() + boost::posix_time::seconds(5));
1461                        if (!lock.owns_lock()) {
1462                                log_broken_message(_T("Message was lost as the core was locked: ") + message);
1463                                return;
1464                        }
1465                        if (g_bConsoleLog) {
1466                                std::string k = "?";
1467                                switch (msgType) {
1468                                case NSCAPI::critical:
1469                                        k ="c";
1470                                        break;
1471                                case NSCAPI::warning:
1472                                        k ="w";
1473                                        break;
1474                                case NSCAPI::error:
1475                                        k ="e";
1476                                        break;
1477                                case NSCAPI::log:
1478                                        k ="l";
1479                                        break;
1480                                case NSCAPI::debug:
1481                                        k ="d";
1482                                        break;
1483                                }       
1484                                std::cout << k << " " << strEx::wstring_to_string(file_stl) << "(" << line << ") " << strEx::wstring_to_string(message) << std::endl;
1485                        }
1486                        if (!plugins_loaded_) {
1487                                log_broken_message(message);
1488                                cached_log_entry entry(msgType, file, line, message);
1489                                log_cache_.push_back(entry);
1490                        } else {
1491                                if (log_cache_.size() > 0) {
1492                                        for (log_cache_type::const_iterator cit=log_cache_.begin();cit!=log_cache_.end();++cit) {
1493                                                for (pluginList::size_type i = 0; i< messageHandlers_.size(); i++) {
1494                                                        try {
1495                                                                messageHandlers_[i]->handleMessage((*cit).msgType, (_T("CACHE") + (*cit).file).c_str(), (*cit).line, (*cit).message.c_str());
1496                                                        } catch(const NSPluginException& e) {
1497                                                                log_broken_message(_T("Caught: ") + e.error_ + _T(" when trying to log a message..."));
1498                                                                return;
1499                                                        } catch(...) {
1500                                                                log_broken_message(_T("Caught: Unknown Exception when trying to log a message..."));
1501                                                                return;
1502                                                        }
1503                                                }
1504                                        }
1505                                        log_cache_.clear();
1506                                }
1507                                for (pluginList::size_type i = 0; i< messageHandlers_.size(); i++) {
1508                                        try {
1509                                                messageHandlers_[i]->handleMessage(msgType, file, line, message.c_str());
1510                                        } catch(const NSPluginException& e) {
1511                                                log_broken_message(_T("Caught: ") + e.error_ + _T(" when trying to log a message..."));
1512                                                return;
1513                                        } catch(...) {
1514                                                log_broken_message(_T("Caught: Unknown Exception when trying to log a message..."));
1515                                                return;
1516                                        }
1517                                }
1518                        }
1519                }
1520        } catch (...) {
1521                log_broken_message(_T("Caught UNKNOWN Exception when trying to log a message: ") + message);
1522        }
1523}
1524boost::filesystem::wpath NSClientT::getBasePath(void) {
1525        boost::unique_lock<boost::timed_mutex> lock(internalVariables, boost::get_system_time() + boost::posix_time::seconds(5));
1526        if (!lock.owns_lock()) {
1527                LOG_ERROR(_T("FATAL ERROR: Could not get mutex."));
1528                return _T("FATAL ERROR");
1529        }
1530        if (!basePath.empty())
1531                return basePath;
1532        unsigned int buf_len = 4096;
1533#ifdef WIN32
1534        wchar_t* buffer = new wchar_t[buf_len+1];
1535        GetModuleFileName(NULL, buffer, buf_len);
1536        std::wstring path = buffer;
1537        std::wstring::size_type pos = path.rfind('\\');
1538        basePath = path.substr(0, pos) + _T("\\");
1539        delete [] buffer;
1540#else
1541        basePath = to_wstring(boost::filesystem::initial_path().string());
1542#endif
1543        try {
1544                settings_manager::get_core()->set_base(basePath);
1545        } catch (SettingsException e) {
1546                LOG_ERROR_STD(_T("Failed to set settings file: ") + e.getMessage());
1547        } catch (...) {
1548                LOG_ERROR_STD(_T("Failed to set settings file"));
1549        }
1550        return basePath;
1551}
1552
1553
1554std::wstring Encrypt(std::wstring str, unsigned int algorithm) {
1555        unsigned int len = 0;
1556        NSAPIEncrypt(algorithm, str.c_str(), static_cast<unsigned int>(str.size()), NULL, &len);
1557        len+=2;
1558        wchar_t *buf = new wchar_t[len+1];
1559        NSCAPI::errorReturn ret = NSAPIEncrypt(algorithm, str.c_str(), static_cast<unsigned int>(str.size()), buf, &len);
1560        if (ret == NSCAPI::isSuccess) {
1561                std::wstring ret = buf;
1562                delete [] buf;
1563                return ret;
1564        }
1565        return _T("");
1566}
1567std::wstring Decrypt(std::wstring str, unsigned int algorithm) {
1568        unsigned int len = 0;
1569        NSAPIDecrypt(algorithm, str.c_str(), static_cast<unsigned int>(str.size()), NULL, &len);
1570        len+=2;
1571        wchar_t *buf = new wchar_t[len+1];
1572        NSCAPI::errorReturn ret = NSAPIDecrypt(algorithm, str.c_str(), static_cast<unsigned int>(str.size()), buf, &len);
1573        if (ret == NSCAPI::isSuccess) {
1574                std::wstring ret = buf;
1575                delete [] buf;
1576                return ret;
1577        }
1578        return _T("");
1579}
Note: See TracBrowser for help on using the repository browser.