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>
* modules/pandora_module.[cc,h]: Added an async property. Added

View File

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

View File

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

View File

@ -18,15 +18,19 @@
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "pandora_module_proc.h"
#include "../windows/pandora_wmi.h"
#include "../pandora_strutils.h"
#include "pandora_module_proc.h"
#include "pandora_module_list.h"
#include "../windows/pandora_wmi.h"
#include "../windows/pandora_windows_info.h"
#include "../pandora_strutils.h"
#include "../pandora_windows_service.h"
#include <algorithm>
#include <cctype>
using namespace Pandora;
using namespace Pandora_Modules;
using namespace Pandora_Strutils;
using namespace Pandora_Strutils;
using namespace Pandora_Windows_Info;
/**
* Creates a Pandora_Module_Proc object.
@ -43,6 +47,73 @@ Pandora_Module_Proc::Pandora_Module_Proc (string name, string process_name)
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
Pandora_Module_Proc::run () {
@ -52,9 +123,16 @@ Pandora_Module_Proc::run () {
Pandora_Module::run ();
} catch (Interval_Not_Fulfilled e) {
return;
}
}
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

@ -29,11 +29,14 @@ namespace Pandora_Modules {
*/
class Pandora_Module_Proc : public Pandora_Module {
private:
string process_name;
string process_name;
HANDLE thread;
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

@ -58,19 +58,19 @@ Pandora_Module_Service::getServiceName () const {
void
async_run (Pandora_Module_Service *module) {
HANDLE event_log;
HANDLE event;
DWORD result;
int res;
string str_res;
BYTE buffer[BUFFER_SIZE];
EVENTLOGRECORD *record;
DWORD read;
DWORD needed;
int event_id;
bool service_event;
string prev_res;
Pandora_Module_List *modules;
HANDLE event_log;
HANDLE event;
DWORD result;
int res;
string str_res;
BYTE buffer[BUFFER_SIZE];
EVENTLOGRECORD *record;
DWORD read;
DWORD needed;
int event_id;
bool service_event;
string prev_res;
Pandora_Module_List *modules;
prev_res = module->getLatestOutput ();
modules = new Pandora_Module_List ();
@ -87,35 +87,41 @@ async_run (Pandora_Module_Service *module) {
NotifyChangeEventLog (event_log, event);
result = WaitForSingleObject (event, 10000);
if (result == 0) {
service_event = false;
record = (EVENTLOGRECORD *) buffer;
/* No event happened */
if (result != WAIT_OBJECT_0) {
CloseHandle (event);
CloseEventLog (event_log);
continue;
}
/* An event happened */
service_event = false;
record = (EVENTLOGRECORD *) buffer;
/* Read events and check if any was relative to service */
while (ReadEventLog (event_log,
EVENTLOG_FORWARDS_READ | EVENTLOG_SEQUENTIAL_READ,
0, record, BUFFER_SIZE, &read, &needed)) {
while (ReadEventLog (event_log,
EVENTLOG_FORWARDS_READ | EVENTLOG_SEQUENTIAL_READ,
0, record, BUFFER_SIZE, &read, &needed)) {
if (record->EventType != EVENTLOG_INFORMATION_TYPE)
continue;
event_id = record->EventID & 0x0000ffff;
/* Those numbers are the code for service start/stopping */
if (event_id == 7035 || event_id == 7036) {
service_event = true;
break;
}
if (record->EventType != EVENTLOG_INFORMATION_TYPE)
continue;
event_id = record->EventID & 0x0000ffff;
/* Those numbers are the code for service start/stopping */
if (event_id == 7035 || event_id == 7036) {
service_event = true;
break;
}
if (service_event) {
res = Pandora_Wmi::isServiceRunning (module->getServiceName ());
str_res = inttostr (res);
if (str_res != prev_res) {
module->setOutput (str_res);
prev_res = str_res;
pandoraLog ("Service \"%s\" changed status to: %d",
module->getServiceName ().c_str (), res);
Pandora_Windows_Service::getInstance ()->sendXml (modules);
}
}
/* A start/stop action was thrown */
if (service_event) {
res = Pandora_Wmi::isServiceRunning (module->getServiceName ());
str_res = inttostr (res);
if (str_res != prev_res) {
module->setOutput (str_res);
prev_res = str_res;
Pandora_Windows_Service::getInstance ()->sendXml (modules);
}
}
CloseHandle (event);

View File

@ -50,24 +50,24 @@ Key_Value::parseLine (string str) {
list<string> tokens;
list<string>::iterator iter;
string trimmedstr;
trimmedstr = trim (str);
/* Check if the string has " */
/* Check if the string has " */
pos = trimmedstr.find ("\"");
if (pos == string::npos) {
stringtok (tokens, trimmedstr, " \t");
} else {
stringtok (tokens, trimmedstr, "\"");
}
/* Pick the first and the last value of the token list */
/* Pick the first and the last value of the token list */
iter = tokens.begin ();
key = trim (*iter);
transform (key.begin(), key.end(), key.begin(), (int(*)(int)) tolower);
iter = tokens.end ();
iter--;
/* Check if the line has only one token */
/* Check if the line has only one token */
if (iter != tokens.begin ()) {
value = trim (*iter);
} else {
@ -102,16 +102,16 @@ pandoraWriteLog (string filename, string line) {
FILE *file;
string filepath;
SYSTEMTIME st;
GetSystemTime(&st);
sprintf (str_time, "%d-%02d-%02d %02d:%02d:%02d ", st.wYear, st.wMonth, st.wDay,
st.wHour, st.wMinute, st.wSecond);
sprintf (str_time, "%d-%02d-%02d %02d:%02d:%02d ", st.wYear, st.wMonth, st.wDay,
st.wHour, st.wMinute, st.wSecond);
buffer = (char *) str_time;
buffer += line;
filepath = pandora_dir + filename;
file = fopen (filepath.c_str (), "a+");
if (file != NULL) {
fprintf (file, "%s\n", buffer.c_str ());
@ -132,11 +132,11 @@ void
Pandora::pandoraLog (char *format, ...) {
va_list args;
char msg[5000];
va_start (args, format);
vsprintf (msg, format, args);
va_end (args);
pandoraWriteLog ("pandora_agent.log", (char *) msg);
}
@ -154,11 +154,11 @@ Pandora::pandoraDebug (char *format, ...) {
if (pandora_debug) {
va_list args;
char msg[5000];
va_start (args, format);
vsprintf (msg, format, args);
va_end (args);
pandoraWriteLog ("pandora_debug.log", (char *) msg);
}
return;

View File

@ -641,10 +641,10 @@ Pandora_Windows_Service::sendXml (Pandora_Module_List *modules) {
if (mutex == 0) {
mutex = CreateMutex (NULL, FALSE, NULL);
}
/* Wait for the mutex to be opened */
WaitForSingleObject (mutex, INFINITE);
pandoraLog ("aasdfasdf");
agent = getXmlHeader ();
if (modules != NULL) {
@ -686,7 +686,7 @@ Pandora_Windows_Service::sendXml (Pandora_Module_List *modules) {
}
pandoraDebug ("Copying XML on %s", tmp_filepath.c_str ());
decl = new TiXmlDeclaration( "1.0", encoding.c_str(), "" );
decl = new TiXmlDeclaration ("1.0", encoding.c_str(), "");
doc = new TiXmlDocument (tmp_filepath);
doc->InsertEndChild (*decl);
doc->InsertEndChild (*agent);
@ -696,7 +696,8 @@ Pandora_Windows_Service::sendXml (Pandora_Module_List *modules) {
if (!saved) {
pandoraLog ("Error when saving the XML in %s",
tmp_filepath.c_str ());
tmp_filepath.c_str ());
ReleaseMutex (mutex);
return;
}

View File

@ -19,7 +19,8 @@
*/
#include "pandora_windows_info.h"
#include "../pandora_strutils.h"
#include "../pandora_strutils.h"
#include <psapi.h>
#define MAX_KEY_LENGTH 255
@ -80,4 +81,52 @@ Pandora_Windows_Info::getSystemPath () {
string str_path = buffer;
str_path = trim (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

@ -34,10 +34,11 @@ using namespace std;
* Windows information functions.
*/
namespace Pandora_Windows_Info {
string getOSName ();
string getOSVersion ();
string getOSBuild ();
string getSystemName ();
string getSystemPath ();
string getOSName ();
string getOSVersion ();
string getOSBuild ();
string getSystemName ();
string getSystemPath ();
HANDLE *getProcessHandles (string name);
}
#endif