2008-12-01 Esteban Sanchez <estebans@artica.es>

* pandora_windows_service.cc: Removed debug output. Release mutex on
        sendXml()

        * modules/pandora_module.[cc,h]: Save latest output in a new property.
        It's used on generic_proc modules to check the value better.

        * modules/pandora_module_proc.[cc,h]: Added support for asynchronous
        mode. It checks process in a separeted thread and report the status
        quicker. Added getProcessName()

        * modules/pandora_module_service.cc: Style correction. Removed an
        indentation level.

        * windows/pandora_windows_info.[cc,h]: Added getProcessHandles() to
        get a list of handles of a running process, giving the process name.




git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@1270 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
This commit is contained in:
Esteban Sanchez 2008-12-01 13:40:19 +00:00
parent 9843334767
commit 0059aad758
10 changed files with 239 additions and 86 deletions

View File

@ -1,3 +1,21 @@
2008-12-01 Esteban Sanchez <estebans@artica.es>
* pandora_windows_service.cc: Removed debug output. Release mutex on
sendXml()
* modules/pandora_module.[cc,h]: Save latest output in a new property.
It's used on generic_proc modules to check the value better.
* modules/pandora_module_proc.[cc,h]: Added support for asynchronous
mode. It checks process in a separeted thread and report the status
quicker. Added getProcessName()
* modules/pandora_module_service.cc: Style correction. Removed an
indentation level.
* windows/pandora_windows_info.[cc,h]: Added getProcessHandles() to
get a list of handles of a running process, giving the process name.
2008-11-28 Esteban Sanchez <estebans@artica.es> 2008-11-28 Esteban Sanchez <estebans@artica.es>
* modules/pandora_module.[cc,h]: Added an async property. Added * modules/pandora_module.[cc,h]: Added an async property. Added

View File

@ -184,12 +184,7 @@ Pandora_Module::getModuleKind () const {
*/ */
string string
Pandora_Module::getLatestOutput () const { Pandora_Module::getLatestOutput () const {
list<Pandora_Data *>::iterator iter; return this->latest_output;
if (this->data_list == NULL)
return "";
iter = this->data_list->begin ();
return (*iter)->getValue ();
} }
/** /**
@ -257,6 +252,7 @@ Pandora_Module::setOutput (string output) {
this->data_list = new list<Pandora_Data *> (); this->data_list = new list<Pandora_Data *> ();
data = new Pandora_Data (output); data = new Pandora_Data (output);
this->data_list->push_back (data); this->data_list->push_back (data);
this->latest_output = output;
} }
/** /**

View File

@ -118,6 +118,7 @@ namespace Pandora_Modules {
string module_kind_str; string module_kind_str;
Module_Kind module_kind; Module_Kind module_kind;
list<Pandora_Data *> *data_list; list<Pandora_Data *> *data_list;
string latest_output;
string getDataOutput (Pandora_Data *data); string getDataOutput (Pandora_Data *data);
void cleanDataList (); void cleanDataList ();

View File

@ -19,14 +19,18 @@
*/ */
#include "pandora_module_proc.h" #include "pandora_module_proc.h"
#include "pandora_module_list.h"
#include "../windows/pandora_wmi.h" #include "../windows/pandora_wmi.h"
#include "../windows/pandora_windows_info.h"
#include "../pandora_strutils.h" #include "../pandora_strutils.h"
#include "../pandora_windows_service.h"
#include <algorithm> #include <algorithm>
#include <cctype> #include <cctype>
using namespace Pandora; using namespace Pandora;
using namespace Pandora_Modules; using namespace Pandora_Modules;
using namespace Pandora_Strutils; using namespace Pandora_Strutils;
using namespace Pandora_Windows_Info;
/** /**
* Creates a Pandora_Module_Proc object. * Creates a Pandora_Module_Proc object.
@ -44,6 +48,73 @@ Pandora_Module_Proc::Pandora_Module_Proc (string name, string process_name)
this->setKind (module_proc_str); this->setKind (module_proc_str);
} }
string
Pandora_Module_Proc::getProcessName () const {
return this->process_name;
}
void
async_run (Pandora_Module_Proc *module) {
HANDLE *processes = NULL;
int nprocess;
DWORD result;
Pandora_Module_List *modules;
string str_res;
string prev_res;
int res;
int i;
prev_res = module->getLatestOutput ();
modules = new Pandora_Module_List ();
modules->addModule (module);
Sleep (2000);
while (1) {
processes = getProcessHandles (module->getProcessName ());
if (processes == NULL) {
Sleep (2000);
continue;
}
/* There are opened processes */
res = Pandora_Wmi::isProcessRunning (module->getProcessName ());
str_res = inttostr (res);
if (str_res != prev_res) {
module->setOutput (str_res);
prev_res = str_res;
Pandora_Windows_Service::getInstance ()->sendXml (modules);
}
/* Wait for this processes */
nprocess = res;
result = WaitForMultipleObjects (nprocess, processes, FALSE, 10000);
if (result > (WAIT_OBJECT_0 + nprocess - 1)) {
/* No event happened */
for (i = 0; i < nprocess; i++)
CloseHandle (processes[i]);
pandoraFree (processes);
continue;
}
/* Some event happened, probably the process was closed */
res = Pandora_Wmi::isProcessRunning (module->getProcessName ());
str_res = inttostr (res);
if (str_res != prev_res) {
module->setOutput (str_res);
prev_res = str_res;
Pandora_Windows_Service::getInstance ()->sendXml (modules);
}
/* Free handles */
for (i = 0; i < nprocess; i++)
CloseHandle (processes[i]);
pandoraFree (processes);
}
delete modules;
}
void void
Pandora_Module_Proc::run () { Pandora_Module_Proc::run () {
int res; int res;
@ -55,6 +126,13 @@ Pandora_Module_Proc::run () {
} }
res = Pandora_Wmi::isProcessRunning (this->process_name); res = Pandora_Wmi::isProcessRunning (this->process_name);
this->setOutput (inttostr (res)); this->setOutput (inttostr (res));
/* Launch thread if it's asynchronous */
if (this->async) {
this->thread = CreateThread (NULL, 0,
(LPTHREAD_START_ROUTINE) async_run,
this, 0, NULL);
this->async = false;
}
} }

View File

@ -30,9 +30,12 @@ namespace Pandora_Modules {
class Pandora_Module_Proc : public Pandora_Module { class Pandora_Module_Proc : public Pandora_Module {
private: private:
string process_name; string process_name;
HANDLE thread;
public: public:
Pandora_Module_Proc (string name, string process_name); Pandora_Module_Proc (string name, string process_name);
string getProcessName () const;
void run (); void run ();
}; };
} }

View File

@ -87,10 +87,18 @@ async_run (Pandora_Module_Service *module) {
NotifyChangeEventLog (event_log, event); NotifyChangeEventLog (event_log, event);
result = WaitForSingleObject (event, 10000); result = WaitForSingleObject (event, 10000);
if (result == 0) { /* No event happened */
if (result != WAIT_OBJECT_0) {
CloseHandle (event);
CloseEventLog (event_log);
continue;
}
/* An event happened */
service_event = false; service_event = false;
record = (EVENTLOGRECORD *) buffer; record = (EVENTLOGRECORD *) buffer;
/* Read events and check if any was relative to service */
while (ReadEventLog (event_log, while (ReadEventLog (event_log,
EVENTLOG_FORWARDS_READ | EVENTLOG_SEQUENTIAL_READ, EVENTLOG_FORWARDS_READ | EVENTLOG_SEQUENTIAL_READ,
0, record, BUFFER_SIZE, &read, &needed)) { 0, record, BUFFER_SIZE, &read, &needed)) {
@ -106,18 +114,16 @@ async_run (Pandora_Module_Service *module) {
} }
} }
/* A start/stop action was thrown */
if (service_event) { if (service_event) {
res = Pandora_Wmi::isServiceRunning (module->getServiceName ()); res = Pandora_Wmi::isServiceRunning (module->getServiceName ());
str_res = inttostr (res); str_res = inttostr (res);
if (str_res != prev_res) { if (str_res != prev_res) {
module->setOutput (str_res); module->setOutput (str_res);
prev_res = str_res; prev_res = str_res;
pandoraLog ("Service \"%s\" changed status to: %d",
module->getServiceName ().c_str (), res);
Pandora_Windows_Service::getInstance ()->sendXml (modules); Pandora_Windows_Service::getInstance ()->sendXml (modules);
} }
} }
}
CloseHandle (event); CloseHandle (event);
CloseEventLog (event_log); CloseEventLog (event_log);
} }

View File

@ -641,10 +641,10 @@ Pandora_Windows_Service::sendXml (Pandora_Module_List *modules) {
if (mutex == 0) { if (mutex == 0) {
mutex = CreateMutex (NULL, FALSE, NULL); mutex = CreateMutex (NULL, FALSE, NULL);
} }
/* Wait for the mutex to be opened */ /* Wait for the mutex to be opened */
WaitForSingleObject (mutex, INFINITE); WaitForSingleObject (mutex, INFINITE);
pandoraLog ("aasdfasdf");
agent = getXmlHeader (); agent = getXmlHeader ();
if (modules != NULL) { if (modules != NULL) {
@ -697,6 +697,7 @@ Pandora_Windows_Service::sendXml (Pandora_Module_List *modules) {
if (!saved) { if (!saved) {
pandoraLog ("Error when saving the XML in %s", pandoraLog ("Error when saving the XML in %s",
tmp_filepath.c_str ()); tmp_filepath.c_str ());
ReleaseMutex (mutex);
return; return;
} }

View File

@ -20,6 +20,7 @@
#include "pandora_windows_info.h" #include "pandora_windows_info.h"
#include "../pandora_strutils.h" #include "../pandora_strutils.h"
#include <psapi.h>
#define MAX_KEY_LENGTH 255 #define MAX_KEY_LENGTH 255
@ -81,3 +82,51 @@ Pandora_Windows_Info::getSystemPath () {
str_path = trim (str_path); str_path = trim (str_path);
return str_path; return str_path;
} }
HANDLE *
Pandora_Windows_Info::getProcessHandles (string name) {
HANDLE handle;
HANDLE handles[128];
HANDLE *retval;
DWORD pids[1024], needed, npids;
int i;
int count;
HMODULE modules;
bool success;
TCHAR process_name[MAX_PATH];
if (! EnumProcesses (pids, sizeof (pids), &needed))
return NULL;
count = 0;
npids = needed / sizeof (DWORD);
for (i = 0; i < npids; i++) {
if (pids[i] == 0)
continue;
/* Open process handle and find module base name (which is
supposed to be process name) */
handle = OpenProcess (PROCESS_ALL_ACCESS, FALSE, pids[i]);
if (handle == NULL)
continue;
success = EnumProcessModules (handle, &modules, sizeof (modules), &needed);
if (! success) {
CloseHandle (handle);
continue;
}
GetModuleBaseName (handle, modules, process_name, sizeof (process_name) / sizeof (TCHAR));
if (stricmp (process_name, name.c_str ()) == 0) {
/* Process found */
handles[count++] = handle;
}
}
if (count == 0)
return NULL;
retval = (HANDLE *) malloc (count * sizeof (HANDLE));
for (i = 0; i < count; i++)
retval[i] = handles[i];
return retval;
}

View File

@ -39,5 +39,6 @@ namespace Pandora_Windows_Info {
string getOSBuild (); string getOSBuild ();
string getSystemName (); string getSystemName ();
string getSystemPath (); string getSystemPath ();
HANDLE *getProcessHandles (string name);
} }
#endif #endif