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:
parent
9843334767
commit
0059aad758
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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 ();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 ();
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue