| // OBBAgent.cpp : Defines the initialization routines for the DLL.
//
#include "stdafx.h"
#include "Agent.h"
#include <afxdllx.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
static AFX_EXTENSION_MODULE OBBAgentDLL = { NULL, NULL };
extern "C" int APIENTRY
DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
{
if (dwReason == DLL_PROCESS_ATTACH)
{
TRACE0("OBBAGENT.DLL Initializing!\n");
// Extension DLL one-time initialization
AfxInitExtensionModule(OBBAgentDLL, hInstance);
// Insert this DLL into the resource chain
new CDynLinkLibrary(OBBAgentDLL);
}
else if (dwReason == DLL_PROCESS_DETACH)
{
TRACE0("OBBAGENT.DLL Terminating!\n");
}
return 1; // ok
}
IMPLEMENT_DYNAMIC(CImplEntry, CObject)
CImplEntry::CImplEntry()
{
}
CImplEntry::~CImplEntry()
{
}
IMPLEMENT_DYNAMIC(CAgent, CObject)
CAgent::CAgent()
{
m_objAgent = NULL;
}
CAgent::~CAgent()
{
DeleteAgent();
}
BOOL CAgent::GetAgent(char* pszNodeName)
{
OBB_MGT_get_agent(pszNodeName, &m_Env, &m_objAgent);
if (m_Env.IsException())
{
m_Env.ReportSystemException("Exception raised getting agent object");
m_objAgent = NULL;
return FALSE;
}
m_pListCtrl->EnableWindow();
return TRUE;
}
void CAgent::DeleteAgent(void)
{
DeleteImplList();
if (m_objAgent != NULL)
{
CORBA_Object_release(m_objAgent, &m_Env);
m_objAgent = NULL;
}
// Need to clear list control and disable it to
// let user now ...
}
void CAgent::DeleteImplList()
{
while (!m_ImplList.IsEmpty())
delete m_ImplList.RemoveHead();
ASSERT(m_ImplList.IsEmpty());
}
BOOL CAgent::GetAgentStatus(CStringList& rCmdRespList)
{
// This is a quick hack for now - but it does the job
return (SpawnCommand("obbmsho -A", rCmdRespList));
}
BOOL CAgent::StartAgent(CStringList& rCmdRespList)
{
// Start the agent - we "assume" it is started for now
// If it isn't GetAgent will throw an exception
if (!SpawnCommand("net start objectbroker", rCmdRespList))
return FALSE;
return TRUE;
}
BOOL CAgent::StopAgent(CStringList& rCmdRespList)
{
BOOL bStatus = SpawnCommand("net stop objectbroker", rCmdRespList);
// Need to release the current agent object since it will no
// longer be valid if a new agent is started.
CORBA_Object_release(m_objAgent, &m_Env);
if (m_Env.IsException())
{
m_Env.ReportSystemException("Failed to release agent object");
bStatus = FALSE;
}
m_objAgent = NULL;
// DeleteImplList();
// m_pListCtrl->EnableWindow(FALSE);
return bStatus;
}
BOOL CAgent::SpawnCommand(CString strCmdLine, CStringList& rCmdRespList)
{
const int DATA_BUFFER_SIZE = 80;
SECURITY_ATTRIBUTES sa = {0};
STARTUPINFO si = {0};
PROCESS_INFORMATION pi = {0};
HANDLE hPipeWrite1 = NULL, hPipeWrite2 = NULL;
HANDLE hPipeRead1 = NULL, hPipeRead2 = NULL;
char szReadBuffer[2];
CString strDataBuffer;
sa.nLength = sizeof(sa);
sa.bInheritHandle = TRUE;
sa.lpSecurityDescriptor = NULL;
// Create pipe for output redirection
if (!(CreatePipe(&hPipeRead1, &hPipeWrite1, &sa, 0)))
{
TRACE("Failed to create pipe.\n");
return FALSE;
}
// Create pipe for input redirection. Need the handle to set
// up the hStdInput field of the STARTUPINFO struct
if (!(CreatePipe(&hPipeRead2, &hPipeWrite2, &sa, 0)))
{
TRACE("Failed to create pipe.\n");
return FALSE;
}
// Make sure child uses hPipeWrite1 as stdout. Also don't want
// it to show on the screen.
si.cb = sizeof(si);
si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
si.wShowWindow = SW_HIDE;
si.hStdInput = hPipeWrite2;
si.hStdOutput = hPipeWrite1;
si.hStdError = hPipeWrite1;
if (!(CreateProcess(NULL, strCmdLine.GetBuffer(strCmdLine.GetLength()),
NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi)))
{
TRACE("Failed to create process.\n");
return FALSE;
}
// Close write handle so we don't use it accidently
CloseHandle(hPipeWrite1);
DWORD dwBytesRead = 0;
BOOL bDataInPipe = TRUE;
while (bDataInPipe)
{
char* pData = strDataBuffer.GetBuffer(DATA_BUFFER_SIZE);
ZeroMemory(pData, DATA_BUFFER_SIZE);
while (TRUE)
{
ZeroMemory(szReadBuffer, 2);
if(ReadFile(hPipeRead1, szReadBuffer, 1, &dwBytesRead, NULL))
{
if (strncmp(szReadBuffer, "\n", 1) != 0)
strncat(pData, szReadBuffer, dwBytesRead);
else
break;
}
if (dwBytesRead == 0)
{
bDataInPipe = FALSE;
break;
}
}
strDataBuffer.ReleaseBuffer();
strDataBuffer.TrimRight();
if (strDataBuffer.GetLength() > 0)
rCmdRespList.AddTail(strDataBuffer);
}
WaitForSingleObject(pi.hProcess, INFINITE);
CloseHandle(pi.hProcess);
CloseHandle(hPipeRead1);
return TRUE;
}
BOOL CAgent::StopImpl(CImplEntry* pImplEntry)
{
if (m_objAgent == NULL)
return FALSE;
BOOL bStatus = TRUE;
CString strMsg = "Are you sure you want to stop ";
strMsg += pImplEntry->m_strImplName + "?";
if (AfxMessageBox (strMsg, MB_YESNO) == IDYES)
{
CORBA_Object objImpl;
objImpl = CORBA_Object_duplicate(pImplEntry->m_objRunningImpl, &m_Env);
if (m_Env.IsException())
{
m_Env.ReportSystemException("Could not duplicate running impl object");
bStatus = FALSE;
}
OBB_MGT_RunningImpl_stop(objImpl, &m_Env, OBB_MGT_FLAG_NOTIFY_IMPL);
if (m_Env.IsException())
{
if (m_Env.GetStatus() == OBB_MGT_NOMORIMPLS)
{
bStatus = TRUE;
}
else if (m_Env.GetStatus() == OBB_INV_MSINSTNOTFND)
{
m_Env.ReportSystemException("Could not not stop running impl");
bStatus = FALSE;
}
}
if (!bStatus)
return bStatus;
return (GetImpls());
}
return TRUE;
}
BOOL CAgent::PurgeImpls(void)
{
if (m_objAgent == NULL)
return FALSE;
OBB_MGT_Agent_purge_impls(m_objAgent, &m_Env, (OBB_MGT_Flags) 0);
if (m_Env.IsException())
{
m_Env.ReportSystemException("Exception raised purging dead impls");
return FALSE;
}
return TRUE;
}
BOOL CAgent::GetIterator(OBB_MGT_RIIterator* pIterator)
{
if (m_objAgent == NULL)
return FALSE;
OBB_MGT_Agent_get_ri_iterator(m_objAgent, &m_Env, pIterator);
if (m_Env.IsException())
{
m_Env.ReportSystemException("Exception raised getting iterator");
return FALSE;
}
return TRUE;
}
OBB_MGT_RIIterator_RIInfo* CAgent::GetNextImpl(OBB_MGT_RIIterator Iterator,
OBB_MGT_RIIterator_ImplInfoSeq* pImplSeq)
{
if (m_objAgent == NULL)
return (OBB_MGT_RIIterator_RIInfo*) NULL;
OBB_MGT_RIIterator_next_n(Iterator, &m_Env, 1, pImplSeq);
if (m_Env.IsException())
{
if (m_Env.GetStatus() == OBB_MGT_NOMORIMPLS)
{
return (OBB_MGT_RIIterator_RIInfo*) NULL;
}
m_Env.ReportSystemException("Exception raised getting iterator");
return (OBB_MGT_RIIterator_RIInfo*) NULL;
}
return (OBB_MGT_RIIterator_RIInfo*) pImplSeq->_buffer;
}
BOOL CAgent::GetImplAttributes(CORBA_Object objRunningImpl, CImplEntry* pEntry)
{
if (m_objAgent == NULL)
return FALSE;
OBB_MGT_NamedUnionSeq Attributes;
Attributes._buffer = NULL;
OBB_MGT_RunningImpl_get_attrs(objRunningImpl, &m_Env, (OBB_MGT_Flags) 0,
(OBB_MGT_NamedUnionSeq*) NULL, &Attributes);
if (m_Env.IsException())
{
if (m_Env.GetStatus() == OBB_INV_MSINSTNOTFND)
{
TRACE("Could not get attributes for implementation!\n");
}
else
{
m_Env.ReportSystemException("Exception raised getting impl attributes");
return FALSE;
}
if (Attributes._buffer != NULL)
CORBA_free(Attributes._buffer);
return FALSE;
}
// Check to see if the impl is "Executing" (i.e., running)
OBB_MGT_NamedUnion* pImplAttr = Attributes._buffer;
// Get what we need out of the attributes structure
unsigned int unIndex;
for (unIndex = 0; unIndex < Attributes._length; unIndex++, pImplAttr++)
{
if (strcmp(pImplAttr->Name, OBB_MGT_ATTR_State) == 0)
{
switch (pImplAttr->Value._u.ULongVal)
{
case OBB_MGT_RunningImpl_STARTING:
pEntry->m_strState = "Starting";
break;
case OBB_MGT_RunningImpl_RUNNING:
pEntry->m_strState = "Executing";
break;
case OBB_MGT_RunningImpl_TERMINATING:
pEntry->m_strState = "Terminating";
break;
case OBB_MGT_RunningImpl_DEAD:
pEntry->m_strState = "Dead";
break;
default:
pEntry->m_strState = "Unknown";
}
}
if (strcmp(pImplAttr->Name, OBB_MGT_ATTR_TimeRegistered) == 0)
{
pEntry->m_strTimeReg = pImplAttr->Value._u.IdVal;
}
if (strcmp(pImplAttr->Name, OBB_MGT_ATTR_SelectState) == 0)
{
switch (pImplAttr->Value._u.ULongVal)
{
case OBB_MGT_RunningImpl_ENABLED:
pEntry->m_strSelectState = "Enabled";
break;
case OBB_MGT_RunningImpl_DISABLED:
pEntry->m_strSelectState = "Disabled";
break;
default:
pEntry->m_strSelectState = "Unknown";
}
}
}
if (Attributes._buffer != NULL)
CORBA_free(Attributes._buffer);
return TRUE;
}
BOOL CAgent::GetImpls(void)
{
if (m_objAgent == NULL)
return FALSE;
// Delete the old list of impls and clear the list control
DeleteImplList();
m_pListCtrl->DeleteAllItems();
// The first thing to do is get an RI Iterator
OBB_MGT_RIIterator Iterator;
if (!GetIterator(&Iterator))
return FALSE;
BOOL bStatus = TRUE;
// Now loop until we run out of impls
OBB_MGT_RIIterator_ImplInfoSeq ImplSeq;
OBB_MGT_RIIterator_RIInfo* pImplInfo = NULL;
while (1)
{
// Get the next impl (includes name and uuids)
if ( (pImplInfo = GetNextImpl(Iterator, &ImplSeq)) == NULL)
{
// If we're here we either ran out of impls
// or an exception occured.
bStatus = TRUE;
break;
}
// Add impl info data to list
CImplEntry* pEntry = new CImplEntry;
pEntry->m_strImplName = pImplInfo->Name;
pEntry->m_strInstUUID = pImplInfo->InstUUID;
pEntry->m_strImplUUID = pImplInfo->ImplUUID;
pEntry->m_objRunningImpl = pImplInfo->RunningImpl;
// Get the attributes for the impl just returned
if (!GetImplAttributes(pImplInfo->RunningImpl, pEntry))
{
// This shouldn't happen?
bStatus = FALSE;
break;
}
#if 0
TRACE("\n Implementation Name\n");
TRACE("-------------------------------------------\n");
TRACE(" %s\n", pEntry->m_strImplName);
TRACE(" Inst UUID: %s\n", pEntry->m_strInstUUID);
TRACE(" Impl UUID: %s\n", pEntry->m_strImplUUID);
TRACE(" State: %s\n", pEntry->m_strState);
#endif
m_ImplList.AddTail(pEntry);
} // while (TRUE)
// Free memory for sequence buffer
CORBA_free(pImplInfo);
// Destroy the iterator
OBB_MGT_RIIterator_destroy(Iterator, NULL);
DisplayImpls();
return bStatus;
}
#define NUMBER_COLUMNS 4
char* grColumnNames[] = { "Impl Name", "State", "Select State", "PID" };
int grColumnWidths[] = { 250, 100, 100, 100 };
void CAgent::InitializeListCtrl(CListCtrl* pListCtrl)
{
// Save for future use
m_pListCtrl = pListCtrl;
// Initialize the list control to hold the implementations
int nResult = 0;
LV_COLUMN lvC;
// Use same mask for all columns
lvC.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
lvC.fmt = LVCFMT_LEFT;
for (int nIndex = 0; nIndex < NUMBER_COLUMNS; nIndex++)
{
lvC.iSubItem = nIndex;
lvC.pszText = grColumnNames[nIndex];
lvC.cx = grColumnWidths[nIndex];
nResult = m_pListCtrl->InsertColumn(nIndex, &lvC);
}
}
void CAgent::DisplayImpls(void)
{
if (m_objAgent == NULL)
return;
POSITION Position = 0;
int nIndex = 0;
for (Position = m_ImplList.GetHeadPosition(); Position != NULL; nIndex++)
{
LV_ITEM lvI;
CImplEntry* pImplEntry = NULL;
pImplEntry = (CImplEntry *) m_ImplList.GetNext(Position);
lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE | LVIF_PARAM;
lvI.iItem = nIndex;
lvI.iSubItem = 0;
lvI.state = 0;
lvI.stateMask = 0;
lvI.pszText = LPSTR_TEXTCALLBACK;
lvI.cchTextMax = 256;
lvI.lParam = (LPARAM) pImplEntry;
ASSERT(m_pListCtrl->InsertItem(&lvI) != -1);
ASSERT(m_pListCtrl->SetItemText(nIndex, 1, LPSTR_TEXTCALLBACK));
ASSERT(m_pListCtrl->SetItemText(nIndex, 2, LPSTR_TEXTCALLBACK));
ASSERT(m_pListCtrl->SetItemText(nIndex, 3, LPSTR_TEXTCALLBACK));
}
}
void CAgent::GetDisplayInfo(NMHDR* pNMHDR)
{
if (m_objAgent == NULL)
return;
LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR;
CImplEntry* pEntry = (CImplEntry*)(pDispInfo->item.lParam);
switch (pDispInfo->item.iSubItem)
{
case 0:
strcpy(m_szSelText, pEntry->m_strImplName);
pDispInfo->item.pszText = m_szSelText;
break;
case 1:
strcpy(m_szSelText, pEntry->m_strState);
pDispInfo->item.pszText = m_szSelText;
break;
case 2:
strcpy(m_szSelText, pEntry->m_strSelectState);
pDispInfo->item.pszText = m_szSelText;
break;
case 3:
// Not implemented yet
//strcpy(m_szSelText, pEntry->m_strPID);
//pDispInfo->item.pszText = m_szSelText;
break;
default:
break;
}
}
|