You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
2362 lines
58 KiB
2362 lines
58 KiB
//-----------------------------------------------------------------------------
|
|
//
|
|
//
|
|
// File: aqadmcli.cpp
|
|
//
|
|
// Description:
|
|
// Unit test for AQAdmin interface
|
|
//
|
|
// Author:
|
|
// Aldrin Teganeanu (aldrint)
|
|
// Mike Swafford (MikeSwa)
|
|
//
|
|
// History:
|
|
// 6/5/99 - MikeSwa Updated to new AQAdmin interface
|
|
//
|
|
// Copyright (C) 1998 Microsoft Corporation
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
#include "stdinc.h"
|
|
|
|
const CLSID CLSID_MAQAdmin = {0x0427FFA4,0xAF27,0x11d2,{0x8F,0xAF,0x00,0xC0,0x4F,0xA3,0x78,0xFF}};
|
|
|
|
//Utility for converting To UNICODE... uses LocalAlloc()
|
|
LPWSTR wszGetUnicodeArg(LPSTR szSrc, DWORD cSrc)
|
|
{
|
|
LPWSTR wszDest = NULL;
|
|
CHAR chSave = '\0';
|
|
if (!szSrc || !cSrc)
|
|
return NULL;
|
|
|
|
wszDest = (LPWSTR) LocalAlloc(LPTR, (cSrc+1)*sizeof(WCHAR));
|
|
if (!wszDest)
|
|
return NULL;
|
|
|
|
chSave = szSrc[cSrc];
|
|
szSrc[cSrc] = '\0';
|
|
MultiByteToWideChar(CP_ACP,
|
|
0,
|
|
szSrc,
|
|
-1,
|
|
wszDest,
|
|
cSrc+1);
|
|
szSrc[cSrc] = chSave;
|
|
|
|
return wszDest;
|
|
}
|
|
|
|
|
|
//prints queue link info if it has it
|
|
void PrintQueueLinkInfo(IUnknown *pIUnknown)
|
|
{
|
|
|
|
HRESULT hr = S_OK;
|
|
IUniqueId *pIUniqueId = NULL;
|
|
QUEUELINK_ID *pqlid = NULL;
|
|
CHAR szGuid[100] = "";
|
|
|
|
hr = pIUnknown->QueryInterface(IID_IUniqueId,
|
|
(void **) &pIUniqueId);
|
|
if (FAILED(hr))
|
|
goto Exit;
|
|
|
|
hr = pIUniqueId->GetUniqueId(&pqlid);
|
|
if (FAILED(hr)) {
|
|
printf ("GetQueueLinkId failied with hr 0x%08X\n", hr);
|
|
goto Exit;
|
|
}
|
|
|
|
//
|
|
// Get string-ized form of GUID
|
|
//
|
|
StringFromGUID2(pqlid->uuid, (LPOLESTR) szGuid, sizeof(szGuid)-1);
|
|
|
|
|
|
printf("QLID:: type %s : Name %S : ID 0x%08X : Guid %S\n",
|
|
(pqlid->qltType == QLT_LINK) ? "link" : ((pqlid->qltType == QLT_QUEUE) ? "queue" : "none"),
|
|
pqlid->szName, pqlid->dwId, szGuid);
|
|
|
|
Exit:
|
|
if (pIUniqueId)
|
|
pIUniqueId->Release();
|
|
|
|
}
|
|
//Helper function qo QI and call ApplyActionToMessages
|
|
HRESULT ApplyActionToMessages(IUnknown *pIUnknown,
|
|
MESSAGE_FILTER *pFilter,
|
|
MESSAGE_ACTION Action,
|
|
DWORD *pcMsgs)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
IAQMessageAction *pIAQMessageAction = NULL;
|
|
if (!pIUnknown)
|
|
return E_POINTER;
|
|
|
|
hr = pIUnknown->QueryInterface(IID_IAQMessageAction,
|
|
(void **) &pIAQMessageAction);
|
|
if (FAILED(hr))
|
|
return hr;
|
|
if (!pIAQMessageAction)
|
|
return E_FAIL;
|
|
|
|
hr = pIAQMessageAction->ApplyActionToMessages(pFilter, Action, pcMsgs);
|
|
pIAQMessageAction->Release();
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CAQAdminCli::SetMsgAction(MESSAGE_ACTION *pAction, CCmdInfo *pCmd)
|
|
{
|
|
char buf[64];
|
|
HRESULT hr = S_OK;
|
|
|
|
hr = pCmd->GetValue("ma", buf);
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
// set the action
|
|
if(!lstrcmpi(buf, "DEL"))
|
|
(*pAction) = MA_DELETE;
|
|
else if(!lstrcmpi(buf, "DEL_S"))
|
|
(*pAction) = MA_DELETE_SILENT;
|
|
else if(!lstrcmpi(buf, "FREEZE"))
|
|
(*pAction) = MA_FREEZE_GLOBAL;
|
|
else if(!lstrcmpi(buf, "THAW"))
|
|
(*pAction) = MA_THAW_GLOBAL;
|
|
else if(!lstrcmpi(buf, "COUNT"))
|
|
(*pAction) = MA_COUNT;
|
|
else
|
|
hr = E_FAIL;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
//---[ CAQAdminCli::SetServer ]------------------------------------------------
|
|
//
|
|
//
|
|
// Description:
|
|
// Sets the remote server and virtual server to connect to
|
|
// Parameters:
|
|
// IN szServerName The name of the server to connect to
|
|
// IN szVSNumber The stringized version number of the virtual
|
|
// server to connect to.
|
|
// Returns:
|
|
// S_OK on success
|
|
// Error code from GetVirtualServerAdminITF
|
|
// History:
|
|
// 6/5/99 - MikeSwa Updated to supply UNICODE arguments
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
HRESULT CAQAdminCli::SetServer(LPSTR szServerName, LPSTR szVSNumber)
|
|
{
|
|
IVSAQAdmin *pTmpVS = NULL;
|
|
WCHAR wszServerName[200];
|
|
WCHAR wszVSNumber[200] = L"1";
|
|
DWORD cServerName = 0;
|
|
DWORD cVSNumber = 0;
|
|
HRESULT hr = S_OK;
|
|
|
|
*wszServerName = L'\0';
|
|
if (szServerName && *szServerName)
|
|
{
|
|
cServerName = strlen(szServerName);
|
|
if (cServerName*sizeof(WCHAR) < sizeof(wszServerName))
|
|
{
|
|
MultiByteToWideChar(CP_ACP,
|
|
0,
|
|
szServerName,
|
|
-1,
|
|
wszServerName,
|
|
cServerName+1);
|
|
}
|
|
}
|
|
|
|
if (szVSNumber && *szVSNumber)
|
|
{
|
|
cVSNumber = strlen(szVSNumber);
|
|
if (cVSNumber*sizeof(WCHAR) < sizeof(wszVSNumber))
|
|
{
|
|
MultiByteToWideChar(CP_ACP,
|
|
0,
|
|
szVSNumber,
|
|
-1,
|
|
wszVSNumber,
|
|
cVSNumber+1);
|
|
}
|
|
}
|
|
|
|
// not going to release the old server until I'm sure
|
|
// that I got the new one.
|
|
hr = m_pAdmin->GetVirtualServerAdminITF(wszServerName, wszVSNumber, &pTmpVS);
|
|
if(FAILED(hr))
|
|
{
|
|
printf("Error: GetVirtualServerAdminITF for \"%s\" failed with 0x%x\n", szServerName, hr);
|
|
}
|
|
else
|
|
{
|
|
if(NULL != m_pVS)
|
|
m_pVS->Release();
|
|
|
|
m_pVS = pTmpVS;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
BOOL CAQAdminCli::StringToUTCTime(LPSTR szTime, SYSTEMTIME *pstUTCTime)
|
|
{
|
|
// read the date
|
|
WORD wMonth, wDay, wYear, wHour, wMinute, wSecond, wMilliseconds;
|
|
BOOL res;
|
|
|
|
int n = sscanf(szTime, "%d/%d/%d %d:%d:%d:%d",
|
|
&(wMonth),
|
|
&(wDay),
|
|
&(wYear),
|
|
&(wHour),
|
|
&(wMinute),
|
|
&(wSecond),
|
|
&(wMilliseconds));
|
|
|
|
if(n == 7)
|
|
{
|
|
// check if it's GMT or UTC time
|
|
if(NULL == strstr(szTime, "UTC") && NULL == strstr(szTime, "GMT"))
|
|
{
|
|
// this is local time
|
|
SYSTEMTIME stLocTime;
|
|
ZeroMemory(&stLocTime, sizeof(SYSTEMTIME));
|
|
|
|
stLocTime.wMonth = wMonth;
|
|
stLocTime.wDay = wDay;
|
|
stLocTime.wYear = wYear;
|
|
stLocTime.wHour = wHour;
|
|
stLocTime.wMinute = wMinute;
|
|
stLocTime.wSecond = wSecond;
|
|
stLocTime.wMilliseconds = wMilliseconds;
|
|
|
|
// convert from local time to UTC time
|
|
if(!LocalTimeToUTC(&stLocTime, pstUTCTime))
|
|
{
|
|
printf("Cannot convert from local time to UTC\n");
|
|
res = FALSE;
|
|
goto Exit;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// it's already UTC time
|
|
pstUTCTime->wMonth = wMonth;
|
|
pstUTCTime->wDay = wDay;
|
|
pstUTCTime->wYear = wYear;
|
|
pstUTCTime->wHour = wHour;
|
|
pstUTCTime->wMinute = wMinute;
|
|
pstUTCTime->wSecond = wSecond;
|
|
pstUTCTime->wMilliseconds = wMilliseconds;
|
|
}
|
|
}
|
|
|
|
Exit:
|
|
return res;
|
|
}
|
|
|
|
|
|
BOOL CAQAdminCli::LocalTimeToUTC(SYSTEMTIME *pstLocTime, SYSTEMTIME *pstUTCTime)
|
|
{
|
|
// the only way I know how to do it is:
|
|
// - convert local system time to local file time
|
|
// - convert local file time to UTC file time
|
|
// - convert UTC file time to UTC system time
|
|
|
|
FILETIME ftLocTime, ftUTCTime;
|
|
BOOL res;
|
|
|
|
res = SystemTimeToFileTime(pstLocTime, &ftLocTime);
|
|
res = res && LocalFileTimeToFileTime(&ftLocTime, &ftUTCTime);
|
|
res = res && FileTimeToSystemTime(&ftUTCTime, pstUTCTime);
|
|
|
|
return res;
|
|
}
|
|
|
|
void CAQAdminCli::FreeStruct(LINK_INFO *pStruct)
|
|
{
|
|
if(NULL != pStruct->szLinkName)
|
|
{
|
|
pStruct->szLinkName = NULL;
|
|
}
|
|
}
|
|
|
|
void CAQAdminCli::FreeStruct(QUEUE_INFO *pStruct)
|
|
{
|
|
if(NULL != pStruct->szQueueName)
|
|
{
|
|
pStruct->szQueueName = NULL;
|
|
}
|
|
if(NULL != pStruct->szLinkName)
|
|
{
|
|
pStruct->szLinkName = NULL;
|
|
}
|
|
}
|
|
|
|
void CAQAdminCli::FreeStruct(MESSAGE_INFO *pStruct)
|
|
{
|
|
if(NULL != pStruct->szMessageId)
|
|
{
|
|
pStruct->szMessageId = NULL;
|
|
}
|
|
if(NULL != pStruct->szSender)
|
|
{
|
|
pStruct->szSender = NULL;
|
|
}
|
|
if(NULL != pStruct->szSubject)
|
|
{
|
|
pStruct->szSubject = NULL;
|
|
}
|
|
if(NULL != pStruct->szRecipients)
|
|
{
|
|
pStruct->szRecipients = NULL;
|
|
}
|
|
if(NULL != pStruct->szCCRecipients)
|
|
{
|
|
pStruct->szCCRecipients = NULL;
|
|
}
|
|
if(NULL != pStruct->szBCCRecipients)
|
|
{
|
|
pStruct->szBCCRecipients = NULL;
|
|
}
|
|
}
|
|
|
|
|
|
void CAQAdminCli::FreeStruct(MESSAGE_FILTER *pStruct)
|
|
{
|
|
if(NULL != pStruct->szMessageId)
|
|
{
|
|
LocalFree((void*)pStruct->szMessageId);
|
|
pStruct->szMessageId = NULL;
|
|
}
|
|
if(NULL != pStruct->szMessageSender)
|
|
{
|
|
LocalFree((void*)pStruct->szMessageSender);
|
|
pStruct->szMessageSender = NULL;
|
|
}
|
|
if(NULL != pStruct->szMessageRecipient)
|
|
{
|
|
LocalFree((void*)pStruct->szMessageRecipient);
|
|
pStruct->szMessageRecipient = NULL;
|
|
}
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// Method: SetMsgFilter()
|
|
// Member of:
|
|
// Arguments:
|
|
// Returns:
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////////////
|
|
HRESULT CAQAdminCli::SetMsgFilter(MESSAGE_FILTER *pFilter, CCmdInfo *pCmd)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
char *buf = NULL;
|
|
int nFlagsOK = 0;
|
|
|
|
ZeroMemory(pFilter, sizeof(MESSAGE_FILTER));
|
|
pFilter->dwVersion = CURRENT_QUEUE_ADMIN_VERSION;
|
|
hr = pCmd->AllocValue("flags", &buf);
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
// set the filter type
|
|
char *token = strtok(buf, "|");
|
|
while(token != NULL)
|
|
{
|
|
// strip the spaces
|
|
char *st, *en;
|
|
for(st = token; isspace(*st); st++);
|
|
for(en = st; *en; en++);
|
|
for(--en; en > st && isspace(*en); en--);
|
|
|
|
if(en - st + 1 > 0)
|
|
{
|
|
// found a flag
|
|
char flag[64];
|
|
ZeroMemory(flag, sizeof(flag));
|
|
CopyMemory(flag, st, en - st + 1);
|
|
|
|
if(!lstrcmpi(flag, "MSGID"))
|
|
{
|
|
nFlagsOK++;
|
|
pFilter->fFlags |= MF_MESSAGEID;
|
|
}
|
|
else if(!lstrcmpi(flag, "SENDER"))
|
|
{
|
|
nFlagsOK++;
|
|
pFilter->fFlags |= MF_SENDER;
|
|
}
|
|
else if(!lstrcmpi(flag, "RCPT"))
|
|
{
|
|
nFlagsOK++;
|
|
pFilter->fFlags |= MF_RECIPIENT;
|
|
}
|
|
else if(!lstrcmpi(flag, "SIZE"))
|
|
{
|
|
nFlagsOK++;
|
|
pFilter->fFlags |= MF_SIZE;
|
|
}
|
|
else if(!lstrcmpi(flag, "TIME"))
|
|
{
|
|
nFlagsOK++;
|
|
pFilter->fFlags |= MF_TIME;
|
|
}
|
|
else if(!lstrcmpi(flag, "FROZEN"))
|
|
{
|
|
nFlagsOK++;
|
|
pFilter->fFlags |= MF_FROZEN;
|
|
}
|
|
else if(!lstrcmpi(flag, "NOT"))
|
|
{
|
|
nFlagsOK++;
|
|
pFilter->fFlags |= MF_INVERTSENSE;
|
|
}
|
|
else if(!lstrcmpi(flag, "ALL"))
|
|
{
|
|
nFlagsOK++;
|
|
pFilter->fFlags |= MF_ALL;
|
|
}
|
|
}
|
|
|
|
token = strtok(NULL, "|");
|
|
}
|
|
}
|
|
|
|
// if no valid flags or no flags at all fail
|
|
if(0 == nFlagsOK)
|
|
{
|
|
printf("Error: no flags specified for the filter\n");
|
|
hr = E_FAIL;
|
|
goto Exit;
|
|
}
|
|
|
|
// set the message id
|
|
nFlagsOK = 0;
|
|
hr = pCmd->AllocValue("id", &buf);
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
// strip the spaces
|
|
char *st, *en;
|
|
for(st = buf; isspace(*st); st++);
|
|
for(en = st; *en; en++);
|
|
for(--en; en > st && isspace(*en); en--);
|
|
|
|
if(en - st + 1 > 0)
|
|
{
|
|
// found a string
|
|
pFilter->szMessageId = wszGetUnicodeArg(st, (DWORD) (en-st+1));
|
|
if(NULL == pFilter->szMessageId)
|
|
{
|
|
printf("Error: LocalAlloc failed\n");
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
nFlagsOK++;
|
|
}
|
|
}
|
|
|
|
// set the message sender
|
|
nFlagsOK = 0;
|
|
hr = pCmd->AllocValue("sender", &buf);
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
// strip the spaces
|
|
char *st, *en;
|
|
for(st = buf; isspace(*st); st++);
|
|
for(en = st; *en; en++);
|
|
for(--en; en > st && isspace(*en); en--);
|
|
|
|
if(en - st + 1 > 0)
|
|
{
|
|
// found a string
|
|
pFilter->szMessageSender = wszGetUnicodeArg(st, (DWORD) (en-st+1));
|
|
if(NULL == pFilter->szMessageSender)
|
|
{
|
|
printf("Error: LocalAlloc failed\n");
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
nFlagsOK++;
|
|
}
|
|
}
|
|
|
|
// set the message recipient
|
|
nFlagsOK = 0;
|
|
hr = pCmd->AllocValue("rcpt", &buf);
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
// strip the spaces
|
|
char *st, *en;
|
|
for(st = buf; isspace(*st); st++);
|
|
for(en = st; *en; en++);
|
|
for(--en; en > st && isspace(*en); en--);
|
|
|
|
if(en - st + 1 > 0)
|
|
{
|
|
// found a string
|
|
pFilter->szMessageRecipient = wszGetUnicodeArg(st, (DWORD) (en-st+1));
|
|
if(NULL == pFilter->szMessageRecipient)
|
|
{
|
|
printf("Error: LocalAlloc failed\n");
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
nFlagsOK++;
|
|
}
|
|
}
|
|
|
|
// set the min message size
|
|
nFlagsOK = 0;
|
|
hr = pCmd->AllocValue("size", &buf);
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
// strip the spaces
|
|
char *st, *en;
|
|
for(st = buf; isspace(*st); st++);
|
|
for(en = st; *en; en++);
|
|
for(--en; en > st && isspace(*en); en--);
|
|
|
|
if(en - st + 1 > 0)
|
|
{
|
|
// found a string
|
|
char aux[64];
|
|
CopyMemory(aux, st, en - st + 1);
|
|
int n = atoi(aux);
|
|
pFilter->dwLargerThanSize = n;
|
|
nFlagsOK++;
|
|
}
|
|
}
|
|
|
|
// set the message date
|
|
nFlagsOK = 0;
|
|
hr = pCmd->AllocValue("date", &buf);
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
if(StringToUTCTime(buf, &(pFilter->stOlderThan)))
|
|
nFlagsOK++;
|
|
}
|
|
|
|
// if no valid no. or no no. at all, set the default
|
|
if(0 == nFlagsOK)
|
|
{
|
|
ZeroMemory(&(pFilter->stOlderThan), sizeof(SYSTEMTIME));
|
|
}
|
|
|
|
// if we came this far all is well
|
|
hr = S_OK;
|
|
Exit:
|
|
if(NULL != buf)
|
|
delete [] buf;
|
|
|
|
// TODO: validate the filter
|
|
return hr;
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// Method: SetMsgEnumFilter()
|
|
// Member of:
|
|
// Arguments:
|
|
// Returns:
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
//1/18/99: AldrinT: updated flag parsing for SENDER and RCPT
|
|
HRESULT CAQAdminCli::SetMsgEnumFilter(MESSAGE_ENUM_FILTER *pFilter, CCmdInfo *pCmd)
|
|
{
|
|
HRESULT hr;
|
|
char *buf = NULL;
|
|
int nFlagsOK = 0;
|
|
|
|
ZeroMemory(pFilter, sizeof(MESSAGE_ENUM_FILTER));
|
|
pFilter->dwVersion = CURRENT_QUEUE_ADMIN_VERSION;
|
|
hr = pCmd->AllocValue("ft", &buf);
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
// set the filter type
|
|
char *token = strtok(buf, "|");
|
|
while(token != NULL)
|
|
{
|
|
// strip the spaces
|
|
char *st, *en;
|
|
for(st = token; isspace(*st); st++);
|
|
for(en = st; *en; en++);
|
|
for(--en; en > st && isspace(*en); en--);
|
|
|
|
if(en - st + 1 > 0)
|
|
{
|
|
// found a flag
|
|
char flag[64];
|
|
ZeroMemory(flag, sizeof(flag));
|
|
CopyMemory(flag, st, en - st + 1);
|
|
|
|
if(!lstrcmpi(flag, "FIRST_N"))
|
|
{
|
|
nFlagsOK++;
|
|
pFilter->mefType |= MEF_FIRST_N_MESSAGES;
|
|
}
|
|
else if(!lstrcmpi(flag, "OLDER"))
|
|
{
|
|
nFlagsOK++;
|
|
pFilter->mefType |= MEF_OLDER_THAN;
|
|
}
|
|
else if(!lstrcmpi(flag, "OLDEST"))
|
|
{
|
|
nFlagsOK++;
|
|
pFilter->mefType |= MEF_N_OLDEST_MESSAGES;
|
|
}
|
|
else if(!lstrcmpi(flag, "LARGER"))
|
|
{
|
|
nFlagsOK++;
|
|
pFilter->mefType |= MEF_LARGER_THAN;
|
|
}
|
|
else if(!lstrcmpi(flag, "LARGEST"))
|
|
{
|
|
nFlagsOK++;
|
|
pFilter->mefType |= MEF_N_LARGEST_MESSAGES;
|
|
}
|
|
else if(!lstrcmpi(flag, "FROZEN"))
|
|
{
|
|
nFlagsOK++;
|
|
pFilter->mefType |= MEF_FROZEN;
|
|
}
|
|
else if(!lstrcmpi(flag, "NOT"))
|
|
{
|
|
nFlagsOK++;
|
|
pFilter->mefType |= MEF_INVERTSENSE;
|
|
}
|
|
else if(!lstrcmpi(flag, "ALL"))
|
|
{
|
|
nFlagsOK++;
|
|
pFilter->mefType |= MEF_ALL;
|
|
}
|
|
else if(!lstrcmpi(flag, "SENDER"))
|
|
{
|
|
nFlagsOK++;
|
|
pFilter->mefType |= MEF_SENDER;
|
|
}
|
|
else if(!lstrcmpi(flag, "RCPT"))
|
|
{
|
|
nFlagsOK++;
|
|
pFilter->mefType |= MEF_RECIPIENT;
|
|
}
|
|
}
|
|
|
|
token = strtok(NULL, "|");
|
|
}
|
|
}
|
|
|
|
|
|
// Ifdef'd code because this is actually a valid state for skipping messages
|
|
// 12/13/98 - MikeSwa
|
|
#ifdef NEVER
|
|
// if no valid flags or no flags at all, fail
|
|
if(0 == nFlagsOK)
|
|
{
|
|
printf("Error: no flags specified for the filter\n");
|
|
hr = E_FAIL;
|
|
goto Exit;
|
|
}
|
|
#endif
|
|
|
|
// set the message number
|
|
nFlagsOK = 0;
|
|
hr = pCmd->AllocValue("mn", &buf);
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
// strip the spaces
|
|
char *st, *en;
|
|
for(st = buf; isspace(*st); st++);
|
|
for(en = st; *en; en++);
|
|
for(--en; en > st && isspace(*en); en--);
|
|
|
|
if(en - st + 1 > 0)
|
|
{
|
|
// found a flag
|
|
char flag[64];
|
|
ZeroMemory(flag, sizeof(flag));
|
|
CopyMemory(flag, st, en - st + 1);
|
|
int n = atoi(flag);
|
|
if(0 == n)
|
|
{
|
|
printf("Error: message no. is 0 or not an integer. Using default.\n");
|
|
}
|
|
else
|
|
{
|
|
nFlagsOK++;
|
|
pFilter->cMessages = n;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// set the message size
|
|
nFlagsOK = 0;
|
|
hr = pCmd->AllocValue("ms", &buf);
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
// strip the spaces
|
|
char *st, *en;
|
|
for(st = buf; isspace(*st); st++);
|
|
for(en = st; *en; en++);
|
|
for(--en; en > st && isspace(*en); en--);
|
|
|
|
if(en - st + 1 > 0)
|
|
{
|
|
// found a flag
|
|
char flag[64];
|
|
ZeroMemory(flag, sizeof(flag));
|
|
CopyMemory(flag, st, en - st + 1);
|
|
int n = atoi(flag);
|
|
nFlagsOK++;
|
|
pFilter->cbSize = n;
|
|
}
|
|
}
|
|
|
|
// if no valid no. or no no. at all, set the default
|
|
if(0 == nFlagsOK)
|
|
pFilter->cbSize = 0;
|
|
|
|
// set the message date
|
|
nFlagsOK = 0;
|
|
hr = pCmd->AllocValue("md", &buf);
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
if(StringToUTCTime(buf, &(pFilter->stDate)))
|
|
nFlagsOK++;
|
|
}
|
|
|
|
// if no valid no. or no no. at all, set the default
|
|
if(0 == nFlagsOK)
|
|
{
|
|
ZeroMemory(&(pFilter->stDate), sizeof(SYSTEMTIME));
|
|
}
|
|
|
|
// set the skip message number
|
|
nFlagsOK = 0;
|
|
hr = pCmd->AllocValue("sk", &buf);
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
// strip the spaces
|
|
char *st, *en;
|
|
for(st = buf; isspace(*st); st++);
|
|
for(en = st; *en; en++);
|
|
for(--en; en > st && isspace(*en); en--);
|
|
|
|
if(en - st + 1 > 0)
|
|
{
|
|
// found a flag
|
|
char flag[64];
|
|
ZeroMemory(flag, sizeof(flag));
|
|
CopyMemory(flag, st, en - st + 1);
|
|
int n = atoi(flag);
|
|
nFlagsOK++;
|
|
pFilter->cSkipMessages = n;
|
|
}
|
|
}
|
|
|
|
// if no valid no. or no no. at all, set the default
|
|
if(0 == nFlagsOK)
|
|
{
|
|
pFilter->cSkipMessages = 0;
|
|
}
|
|
|
|
// set the sender value
|
|
nFlagsOK = 0;
|
|
hr = pCmd->AllocValue("msndr", &buf);
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
// strip the spaces
|
|
char *st, *en;
|
|
for(st = buf; isspace(*st); st++);
|
|
for(en = st; *en; en++);
|
|
for(--en; en > st && isspace(*en); en--);
|
|
|
|
if(en - st + 1 > 0)
|
|
{
|
|
// found a string
|
|
pFilter->szMessageSender = wszGetUnicodeArg(st, (DWORD) (en-st+1));
|
|
if(NULL == pFilter->szMessageSender)
|
|
{
|
|
printf("Error: LocalAlloc failed\n");
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
nFlagsOK++;
|
|
}
|
|
}
|
|
|
|
// set the recipient value
|
|
nFlagsOK = 0;
|
|
hr = pCmd->AllocValue("mrcpt", &buf);
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
// strip the spaces
|
|
char *st, *en;
|
|
for(st = buf; isspace(*st); st++);
|
|
for(en = st; *en; en++);
|
|
for(--en; en > st && isspace(*en); en--);
|
|
|
|
if(en - st + 1 > 0)
|
|
{
|
|
// found a string
|
|
pFilter->szMessageRecipient = wszGetUnicodeArg(st, (DWORD) (en-st+1));
|
|
if(NULL == pFilter->szMessageRecipient)
|
|
{
|
|
printf("Error: LocalAlloc failed\n");
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
nFlagsOK++;
|
|
}
|
|
}
|
|
|
|
if(!pFilter->mefType)
|
|
{
|
|
pFilter->cMessages = 1;
|
|
pFilter->mefType |= MEF_FIRST_N_MESSAGES;
|
|
}
|
|
|
|
// if we came this far all is well
|
|
hr = S_OK;
|
|
// TODO: validate the filter
|
|
if(NULL != buf)
|
|
delete [] buf;
|
|
return hr;
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// Method: IsContinue()
|
|
// Member of:
|
|
// Arguments:
|
|
// Returns:
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////////////
|
|
BOOL CAQAdminCli::IsContinue(LPSTR pszTag, LPWSTR wszVal)
|
|
{
|
|
int nValidTags = 0;
|
|
CHAR szVal[200] = "";
|
|
|
|
for(CCmdInfo::CArgList *p = m_pFilterCmd->pArgs; NULL != p; p = p->pNext)
|
|
{
|
|
// set the tag to the default value if not already set
|
|
if(p->szTag[0] == 0 && m_pFilterCmd->szDefTag[0] != 0)
|
|
lstrcpy(p->szTag, m_pFilterCmd->szDefTag);
|
|
// count valid tags
|
|
if(!lstrcmpi(p->szTag, pszTag))
|
|
nValidTags++;
|
|
}
|
|
|
|
if(!nValidTags)
|
|
return TRUE;
|
|
|
|
//Convert in param to ASCII
|
|
WideCharToMultiByte(CP_ACP, 0, wszVal, -1, szVal,
|
|
sizeof(szVal), NULL, NULL);
|
|
|
|
for(p = m_pFilterCmd->pArgs; NULL != p; p = p->pNext)
|
|
{
|
|
if(pszTag && lstrcmpi(p->szTag, pszTag))
|
|
continue;
|
|
|
|
if(szVal && lstrcmpi(p->szVal, szVal))
|
|
continue;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// Method: PrintMsgInfo()
|
|
// Member of:
|
|
// Arguments:
|
|
// Returns:
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////////////
|
|
HRESULT CAQAdminCli::PrintMsgInfo()
|
|
{
|
|
HRESULT hr;
|
|
int nCrtLink, nCrtQueue, nCrtMsg;
|
|
|
|
IEnumVSAQLinks *pLinkEnum = NULL;
|
|
IEnumLinkQueues *pQueueEnum = NULL;
|
|
IAQEnumMessages *pMsgEnum = NULL;
|
|
|
|
IVSAQLink *pLink = NULL;
|
|
ILinkQueue *pQueue = NULL;
|
|
IAQMessage *pMsg = NULL;
|
|
|
|
LINK_INFO linkInf;
|
|
QUEUE_INFO queueInf;
|
|
MESSAGE_INFO msgInf;
|
|
ZeroMemory(&linkInf, sizeof(LINK_INFO));
|
|
ZeroMemory(&queueInf, sizeof(QUEUE_INFO));
|
|
ZeroMemory(&msgInf, sizeof(MESSAGE_INFO));
|
|
|
|
hr = m_pVS->GetLinkEnum(&pLinkEnum);
|
|
if(FAILED(hr))
|
|
{
|
|
printf("GetLinkEnum failed with 0x%x\n", hr);
|
|
goto Exit;
|
|
}
|
|
|
|
for(nCrtLink = 1; TRUE; nCrtLink++)
|
|
{
|
|
if(NULL != pLink)
|
|
{
|
|
pLink->Release();
|
|
pLink = NULL;
|
|
}
|
|
FreeStruct(&linkInf);
|
|
hr = GetLink(pLinkEnum, &pLink, &linkInf);
|
|
if(hr == S_FALSE)
|
|
{
|
|
if(nCrtLink == 1)
|
|
puts("No links.");
|
|
goto Exit;
|
|
}
|
|
else if(FAILED(hr))
|
|
{
|
|
break;
|
|
}
|
|
else if(hr == S_OK)
|
|
{
|
|
// check if we want messages for this link
|
|
if(!IsContinue("ln", linkInf.szLinkName))
|
|
continue;
|
|
|
|
hr = pLink->GetQueueEnum(&pQueueEnum);
|
|
if(FAILED(hr))
|
|
{
|
|
printf("Error: Link %d: pLink->GetQueueEnum failed with 0x%x\n", nCrtLink, hr);
|
|
continue;
|
|
}
|
|
|
|
for(nCrtQueue = 1; TRUE; nCrtQueue++)
|
|
{
|
|
if(NULL != pQueue)
|
|
{
|
|
pQueue->Release();
|
|
pQueue = NULL;
|
|
}
|
|
FreeStruct(&queueInf);
|
|
hr = GetQueue(pQueueEnum, &pQueue, &queueInf);
|
|
if(hr == S_FALSE)
|
|
{
|
|
if(nCrtQueue == 1)
|
|
puts("No queues.");
|
|
break;
|
|
}
|
|
else if(FAILED(hr))
|
|
break;
|
|
|
|
// check if we want messages for this queue
|
|
if(!IsContinue("qn", queueInf.szQueueName))
|
|
continue;
|
|
|
|
if(!lstrcmpi(m_pActionCmd->szCmdKey, "MSG_INFO"))
|
|
{
|
|
MESSAGE_ENUM_FILTER Filter;
|
|
|
|
// enum the messages
|
|
SetMsgEnumFilter(&Filter, m_pFilterCmd);
|
|
|
|
hr = pQueue->GetMessageEnum(&Filter, &pMsgEnum);
|
|
if(FAILED(hr))
|
|
{
|
|
printf("Error: Link %d, Queue %d: pQueue->GetMessageEnum failed with 0x%x\n", nCrtLink, nCrtQueue, hr);
|
|
continue;
|
|
}
|
|
|
|
printf("---- Messages in queue %S ----\n", queueInf.szQueueName);
|
|
|
|
for(nCrtMsg = 1; TRUE; nCrtMsg++)
|
|
{
|
|
FreeStruct(&msgInf);
|
|
hr = GetMsg(pMsgEnum, &pMsg, &msgInf);
|
|
if(NULL != pMsg)
|
|
{
|
|
pMsg->Release();
|
|
pMsg = NULL;
|
|
}
|
|
if(hr == S_FALSE)
|
|
{
|
|
if(nCrtMsg == 1)
|
|
puts("No messages.");
|
|
break;
|
|
}
|
|
else if(hr == S_OK)
|
|
{
|
|
PInfo(nCrtMsg, msgInf);
|
|
}
|
|
else if(FAILED(hr))
|
|
break;
|
|
}
|
|
}
|
|
else if(!lstrcmpi(m_pActionCmd->szCmdKey, "DEL_MSG"))
|
|
{
|
|
MESSAGE_FILTER Filter;
|
|
DWORD cMsgs = 0;
|
|
|
|
hr = SetMsgFilter(&Filter, m_pFilterCmd);
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
hr = ApplyActionToMessages(pQueue, &Filter, MA_DELETE_SILENT, &cMsgs);
|
|
if(FAILED(hr))
|
|
printf("Error: Link %d, Queue %d: pQueue->ApplyActionToMessages failed with 0x%x\n", nCrtLink, nCrtQueue, hr);
|
|
else
|
|
printf("Operation succeeded on %d messages\n", cMsgs);
|
|
}
|
|
|
|
FreeStruct(&Filter);
|
|
}
|
|
}
|
|
if(NULL != pQueue)
|
|
{
|
|
pQueue->Release();
|
|
pQueue = NULL;
|
|
}
|
|
if(NULL != pQueueEnum)
|
|
{
|
|
pQueueEnum->Release();
|
|
pQueueEnum = NULL;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
Exit:
|
|
FreeStruct(&linkInf);
|
|
FreeStruct(&queueInf);
|
|
FreeStruct(&msgInf);
|
|
|
|
if(NULL != pLink)
|
|
{
|
|
pLink->Release();
|
|
pLink = NULL;
|
|
}
|
|
if(NULL != pLinkEnum)
|
|
{
|
|
pLinkEnum->Release();
|
|
}
|
|
if(NULL != pMsgEnum)
|
|
{
|
|
pMsgEnum->Release();
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// Method: PrintQueueInfo()
|
|
// Member of: CAQAdminCli
|
|
// Arguments: none
|
|
// Returns: S_OK
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////////////
|
|
HRESULT CAQAdminCli::PrintQueueInfo()
|
|
{
|
|
HRESULT hr;
|
|
int nCrtLink, nCrtQueue;
|
|
|
|
IEnumVSAQLinks *pLinkEnum = NULL;
|
|
IEnumLinkQueues *pQueueEnum = NULL;
|
|
IVSAQLink *pLink = NULL;
|
|
ILinkQueue *pQueue = NULL;
|
|
|
|
LINK_INFO linkInf;
|
|
QUEUE_INFO queueInf;
|
|
ZeroMemory(&linkInf, sizeof(LINK_INFO));
|
|
ZeroMemory(&queueInf, sizeof(QUEUE_INFO));
|
|
|
|
|
|
hr = m_pVS->GetLinkEnum(&pLinkEnum);
|
|
if(FAILED(hr))
|
|
{
|
|
printf("Error: GetLinkEnum failed with 0x%x\n", hr);
|
|
goto Exit;
|
|
}
|
|
|
|
for(nCrtLink = 1; TRUE; nCrtLink++)
|
|
{
|
|
if(NULL != pLink)
|
|
{
|
|
pLink->Release();
|
|
pLink = NULL;
|
|
}
|
|
FreeStruct(&linkInf);
|
|
hr = GetLink(pLinkEnum, &pLink, &linkInf);
|
|
if(hr == S_FALSE)
|
|
{
|
|
if(nCrtLink == 1)
|
|
puts("No links.");
|
|
break;
|
|
}
|
|
else if(FAILED(hr))
|
|
{
|
|
break;
|
|
}
|
|
else if(hr == S_OK)
|
|
{
|
|
// check if we want queues for this link
|
|
if(!IsContinue("ln", linkInf.szLinkName))
|
|
continue;
|
|
|
|
hr = pLink->GetQueueEnum(&pQueueEnum);
|
|
if(FAILED(hr))
|
|
{
|
|
printf("Error: Link %d: pLink->GetQueueEnum failed with 0x%x\n", nCrtLink, hr);
|
|
continue;
|
|
}
|
|
|
|
PrintQueueLinkInfo(pLink);
|
|
printf("---- Queues for link %S ----\n", linkInf.szLinkName);
|
|
|
|
for(nCrtQueue = 1; TRUE; nCrtQueue++)
|
|
{
|
|
if(NULL != pQueue)
|
|
{
|
|
pQueue->Release();
|
|
pQueue = NULL;
|
|
}
|
|
FreeStruct(&queueInf);
|
|
hr = GetQueue(pQueueEnum, &pQueue, &queueInf);
|
|
|
|
if(hr == S_FALSE)
|
|
{
|
|
if(nCrtQueue == 1)
|
|
puts("No queues.");
|
|
break;
|
|
}
|
|
else if(FAILED(hr))
|
|
{
|
|
break;
|
|
}
|
|
else if(hr == S_OK)
|
|
{
|
|
// check if we want this queue
|
|
if(!IsContinue("qn", queueInf.szQueueName))
|
|
continue;
|
|
|
|
PrintQueueLinkInfo(pQueue);
|
|
if(!lstrcmpi(m_pActionCmd->szCmdKey, "QUEUE_INFO"))
|
|
PInfo(nCrtQueue, queueInf);
|
|
else if(!lstrcmpi(m_pActionCmd->szCmdKey, "MSGACTION"))
|
|
{
|
|
MESSAGE_ACTION Action;
|
|
MESSAGE_FILTER Filter;
|
|
char buf[64];
|
|
ZeroMemory(buf, sizeof(buf));
|
|
|
|
hr = SetMsgAction(&Action, m_pFilterCmd);
|
|
if(FAILED(hr))
|
|
{
|
|
printf("Error: must specify a message action\n");
|
|
}
|
|
else
|
|
{
|
|
DWORD cMsgs = 0;
|
|
// set the filter
|
|
hr = SetMsgFilter(&Filter, m_pFilterCmd);
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
hr = ApplyActionToMessages(pQueue, &Filter, Action, &cMsgs);
|
|
if(FAILED(hr))
|
|
{
|
|
printf("Link %S, Queue %S: pLink->ApplyActionToMessages failed with 0x%x\n", linkInf.szLinkName, queueInf.szQueueName, hr);
|
|
}
|
|
else
|
|
printf("Link %S, Queue %S: pLink->ApplyActionToMessages succeeded on %d Messages\n", linkInf.szLinkName, queueInf.szQueueName, cMsgs);
|
|
}
|
|
FreeStruct(&Filter);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if(NULL != pQueueEnum)
|
|
{
|
|
pQueueEnum->Release();
|
|
pQueueEnum = NULL;
|
|
}
|
|
if(NULL != pQueue)
|
|
{
|
|
pQueue->Release();
|
|
pQueue = NULL;
|
|
}
|
|
}
|
|
|
|
if(NULL != pLink)
|
|
{
|
|
pLink->Release();
|
|
pLink = NULL;
|
|
}
|
|
}
|
|
|
|
Exit:
|
|
FreeStruct(&linkInf);
|
|
FreeStruct(&queueInf);
|
|
if(NULL != pLinkEnum)
|
|
{
|
|
pLinkEnum->Release();
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// Method: PrintLinkInfo()
|
|
// Member of: CAQAdminCli
|
|
// Arguments: none
|
|
// Returns: S_OK
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////////////
|
|
HRESULT CAQAdminCli::PrintLinkInfo()
|
|
{
|
|
HRESULT hr;
|
|
IEnumVSAQLinks *pLinkEnum = NULL;
|
|
int nCrt = 0;
|
|
|
|
LINK_INFO linkInf;
|
|
ZeroMemory(&linkInf, sizeof(LINK_INFO));
|
|
|
|
hr = m_pVS->GetLinkEnum(&pLinkEnum);
|
|
if(FAILED(hr))
|
|
{
|
|
printf("Error: GetLinkEnum failed with 0x%x\n", hr);
|
|
goto Exit;
|
|
}
|
|
|
|
for(nCrt = 1; TRUE; nCrt++)
|
|
{
|
|
IVSAQLink *pLink = NULL;
|
|
FreeStruct(&linkInf);
|
|
hr = GetLink(pLinkEnum, &pLink, &linkInf);
|
|
|
|
if(hr == S_FALSE)
|
|
{
|
|
if(nCrt == 1)
|
|
puts("No links.");
|
|
break;
|
|
}
|
|
else if(FAILED(hr))
|
|
{
|
|
break;
|
|
}
|
|
else if(hr == S_OK)
|
|
{
|
|
// check if we want link info. for this link
|
|
if(!IsContinue("ln", linkInf.szLinkName))
|
|
{
|
|
pLink->Release();
|
|
pLink = NULL;
|
|
continue;
|
|
}
|
|
|
|
if(!lstrcmpi(m_pActionCmd->szCmdKey, "LINK_INFO"))
|
|
PInfo(nCrt, linkInf);
|
|
else if(!lstrcmpi(m_pActionCmd->szCmdKey, "FREEZE"))
|
|
{
|
|
hr = pLink->SetLinkState(LA_FREEZE);
|
|
if(SUCCEEDED(hr))
|
|
printf("Link %S was frozen\n", linkInf.szLinkName);
|
|
else
|
|
printf("Link %S: SetLinkState() failed with 0x%x\n", linkInf.szLinkName, hr);
|
|
}
|
|
else if(!lstrcmpi(m_pActionCmd->szCmdKey, "THAW"))
|
|
{
|
|
hr = pLink->SetLinkState(LA_THAW);
|
|
if(SUCCEEDED(hr))
|
|
printf("Link %S was un-frozen\n", linkInf.szLinkName);
|
|
else
|
|
printf("Link %S: SetLinkState() failed with 0x%x\n", linkInf.szLinkName, hr);
|
|
}
|
|
else if(!lstrcmpi(m_pActionCmd->szCmdKey, "KICK"))
|
|
{
|
|
hr = pLink->SetLinkState(LA_KICK);
|
|
if(SUCCEEDED(hr))
|
|
printf("Link %S was kicked\n", linkInf.szLinkName);
|
|
else
|
|
printf("Link %S: SetLinkState() failed with 0x%x\n", linkInf.szLinkName, hr);
|
|
}
|
|
else if(!lstrcmpi(m_pActionCmd->szCmdKey, "MSGACTION"))
|
|
{
|
|
MESSAGE_ACTION Action;
|
|
MESSAGE_FILTER Filter;
|
|
char buf[64];
|
|
ZeroMemory(buf, sizeof(buf));
|
|
|
|
hr = SetMsgAction(&Action, m_pFilterCmd);
|
|
if(FAILED(hr))
|
|
{
|
|
printf("Error: must specify a message action\n");
|
|
}
|
|
else
|
|
{
|
|
DWORD cMsgs = 0;
|
|
// set the filter
|
|
hr = SetMsgFilter(&Filter, m_pFilterCmd);
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
hr = ApplyActionToMessages(pLink, &Filter, Action, &cMsgs);
|
|
if(FAILED(hr))
|
|
{
|
|
printf("Link %S: pLink->ApplyActionToMessages failed with 0x%x\n", linkInf.szLinkName, hr);
|
|
}
|
|
else
|
|
printf("Link %S: pLink->ApplyActionToMessages succeeded on %d Messages\n", linkInf.szLinkName, cMsgs);
|
|
}
|
|
FreeStruct(&Filter);
|
|
}
|
|
}
|
|
}
|
|
|
|
if(NULL != pLink)
|
|
{
|
|
pLink->Release();
|
|
pLink = NULL;
|
|
}
|
|
}
|
|
Exit:
|
|
FreeStruct(&linkInf);
|
|
if(NULL != pLinkEnum)
|
|
{
|
|
pLinkEnum->Release();
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// Method: PInfo()
|
|
// Member of:
|
|
// Arguments:
|
|
// Returns:
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////////////
|
|
void CAQAdminCli::PInfo(int nCrt, MESSAGE_INFO msgInf)
|
|
{
|
|
// convert the UTC time to local time
|
|
SYSTEMTIME stLocSubmit, stLocRecv, stLocExpire;
|
|
BOOL res;
|
|
CHAR szTimeSuffix[] = " UTC";
|
|
LPWSTR wszCurrent = NULL;
|
|
SYSTEMTIME *pstSubmit = &msgInf.stSubmission;
|
|
SYSTEMTIME *pstReceived = &msgInf.stReceived;
|
|
SYSTEMTIME *pstExpire = &msgInf.stExpiry;
|
|
|
|
res = SystemTimeToTzSpecificLocalTime(NULL, &msgInf.stSubmission, &stLocSubmit);
|
|
res = res && SystemTimeToTzSpecificLocalTime(NULL, &msgInf.stReceived, &stLocRecv);
|
|
res = res && SystemTimeToTzSpecificLocalTime(NULL, &msgInf.stExpiry, &stLocExpire);
|
|
|
|
if(res)
|
|
{
|
|
//Use localized times
|
|
pstSubmit = &stLocSubmit;
|
|
pstReceived = &stLocRecv;
|
|
pstExpire = &stLocExpire;
|
|
szTimeSuffix[1] = '\0'; //" \0TC"
|
|
}
|
|
|
|
printf("%d.Message ID: %S, Priority: %s %s, Version: %ld, Size: %ld\n"
|
|
" Flags 0x%08X\n"
|
|
" %ld EnvRecipients (%ld bytes): \n",
|
|
nCrt,
|
|
msgInf.szMessageId,
|
|
msgInf.fMsgFlags & MP_HIGH ? "High" : (msgInf.fMsgFlags & MP_NORMAL ? "Normal" : "Low"),
|
|
msgInf.fMsgFlags & MP_MSG_FROZEN ? "(frozen)" : "",
|
|
msgInf.dwVersion,
|
|
msgInf.cbMessageSize,
|
|
msgInf.fMsgFlags,
|
|
msgInf.cEnvRecipients,
|
|
msgInf.cbEnvRecipients);
|
|
|
|
//spit out recipients
|
|
wszCurrent = msgInf.mszEnvRecipients;
|
|
while (wszCurrent && *wszCurrent)
|
|
{
|
|
printf("\t%S\n", wszCurrent);
|
|
while (*wszCurrent)
|
|
wszCurrent++;
|
|
wszCurrent++;
|
|
}
|
|
|
|
//print error if msgInf.mszEnvRecipients is malformed
|
|
if ((1+wszCurrent-msgInf.mszEnvRecipients)*sizeof(WCHAR) != msgInf.cbEnvRecipients)
|
|
{
|
|
printf("\tERROR mszEnvRecipients malformatted (found %ld instead of %ld bytes)\n",
|
|
(wszCurrent-msgInf.mszEnvRecipients)*sizeof(WCHAR),
|
|
msgInf.cbEnvRecipients);
|
|
}
|
|
|
|
|
|
printf(" %ld Recipients: %S\n"
|
|
" %ld Cc recipients: %S\n"
|
|
" %ld Bcc recipients: %S\n"
|
|
" Sender: %S\n"
|
|
" Subject: %S\n"
|
|
" Submitted: %d/%d/%d at %d:%02d:%02d:%03d%s\n"
|
|
" Received: %d/%d/%d at %d:%02d:%02d:%03d%s\n"
|
|
" Expires: %d/%d/%d at %d:%02d:%02d:%03d%s\n"
|
|
" %ld Failed Delivery attempts\n",
|
|
msgInf.cRecipients,
|
|
msgInf.szRecipients,
|
|
msgInf.cCCRecipients,
|
|
msgInf.szCCRecipients,
|
|
msgInf.cBCCRecipients,
|
|
msgInf.szBCCRecipients,
|
|
msgInf.szSender,
|
|
msgInf.szSubject,
|
|
pstSubmit->wMonth,
|
|
pstSubmit->wDay,
|
|
pstSubmit->wYear,
|
|
pstSubmit->wHour,
|
|
pstSubmit->wMinute,
|
|
pstSubmit->wSecond,
|
|
pstSubmit->wMilliseconds,
|
|
szTimeSuffix,
|
|
pstReceived->wMonth,
|
|
pstReceived->wDay,
|
|
pstReceived->wYear,
|
|
pstReceived->wHour,
|
|
pstReceived->wMinute,
|
|
pstReceived->wSecond,
|
|
pstReceived->wMilliseconds,
|
|
szTimeSuffix,
|
|
pstExpire->wMonth,
|
|
pstExpire->wDay,
|
|
pstExpire->wYear,
|
|
pstExpire->wHour,
|
|
pstExpire->wMinute,
|
|
pstExpire->wSecond,
|
|
pstExpire->wMilliseconds,
|
|
szTimeSuffix,
|
|
msgInf.cFailures);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// Method: PInfo()
|
|
// Member of:
|
|
// Arguments:
|
|
// Returns:
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////////////
|
|
void CAQAdminCli::PInfo(int nCrt, QUEUE_INFO queueInf)
|
|
{
|
|
printf( "%d.Name: %S, Version: %ld, No. of messages: %ld\n"
|
|
" Link name: %S, Volume: %ld\n",
|
|
nCrt,
|
|
queueInf.szQueueName,
|
|
queueInf.dwVersion,
|
|
queueInf.cMessages,
|
|
queueInf.szLinkName,
|
|
queueInf.cbQueueVolume);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// Method: PInfo()
|
|
// Member of:
|
|
// Arguments:
|
|
// Returns:
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////////////
|
|
void CAQAdminCli::PInfo(int nCrt, LINK_INFO linkInf)
|
|
{
|
|
// convert the UTC time to local time
|
|
SYSTEMTIME stLocNextConn, stLocOldest;
|
|
BOOL res;
|
|
char *pszFormat, *pszState;
|
|
SYSTEMTIME *pstNext, *pstOld;
|
|
char szSupportedLinkActions[50] = "";
|
|
|
|
if (linkInf.fStateFlags & LI_ACTIVE )
|
|
pszState = "Active";
|
|
else if (linkInf.fStateFlags & LI_READY)
|
|
pszState = "Ready";
|
|
else if (linkInf.fStateFlags & LI_RETRY)
|
|
pszState = "Retry";
|
|
else if (linkInf.fStateFlags & LI_SCHEDULED)
|
|
pszState = "Scheduled";
|
|
else if (linkInf.fStateFlags & LI_REMOTE)
|
|
pszState = "Remote";
|
|
else if (linkInf.fStateFlags & LI_FROZEN)
|
|
pszState = "Frozen";
|
|
else
|
|
pszState = "Unknown";
|
|
|
|
if (linkInf.dwSupportedLinkActions & LA_FREEZE)
|
|
strcpy(szSupportedLinkActions, "Freeze");
|
|
if (linkInf.dwSupportedLinkActions & LA_THAW)
|
|
strcat(szSupportedLinkActions, " Thaw");
|
|
if (linkInf.dwSupportedLinkActions & LA_KICK)
|
|
strcat(szSupportedLinkActions, " Kick");
|
|
|
|
if (!szSupportedLinkActions[0])
|
|
strcpy(szSupportedLinkActions, "Link can only be viewed.");
|
|
|
|
res = SystemTimeToTzSpecificLocalTime(NULL, &linkInf.stNextScheduledConnection, &stLocNextConn);
|
|
res = res && SystemTimeToTzSpecificLocalTime(NULL, &linkInf.stOldestMessage, &stLocOldest);
|
|
|
|
if(res)
|
|
{
|
|
pszFormat = "%d.Name: %S, Version: %ld\n"
|
|
" No. of messages: %ld, State: %s [0x%08X], Volume: %ld\n"
|
|
" Next scheduled connection: %d/%d/%d at %d:%02d:%02d:%03d\n"
|
|
" Oldest message: %d/%d/%d at %d:%02d:%02d:%03d\n"
|
|
" Supported Link Actions: %s\n"
|
|
" Link Diagnostic: %S\n";
|
|
pstNext = &stLocNextConn;
|
|
pstOld = &stLocOldest;
|
|
}
|
|
else
|
|
{
|
|
pszFormat = "%d.Name: %S, Version: %ld\n"
|
|
" No. of messages: %ld, State: %s [0x%08X], Volume: %ld\n"
|
|
" Next scheduled connection: %d/%d/%d at %d:%02d:%02d:%03d UTC\n"
|
|
" Oldest message: %d/%d/%d at %d:%02d:%02d:%03d UTC\n"
|
|
" Supported Link Actions: %s\n"
|
|
" Link Diagnostic: %S\n";
|
|
pstNext = &linkInf.stNextScheduledConnection;
|
|
pstOld = &linkInf.stOldestMessage;
|
|
}
|
|
|
|
printf(pszFormat,
|
|
nCrt,
|
|
linkInf.szLinkName,
|
|
linkInf.dwVersion,
|
|
linkInf.cMessages,
|
|
pszState,
|
|
linkInf.fStateFlags,
|
|
linkInf.cbLinkVolume.LowPart,
|
|
pstNext->wMonth,
|
|
pstNext->wDay,
|
|
pstNext->wYear,
|
|
pstNext->wHour,
|
|
pstNext->wMinute,
|
|
pstNext->wSecond,
|
|
pstNext->wMilliseconds,
|
|
pstOld->wMonth,
|
|
pstOld->wDay,
|
|
pstOld->wYear,
|
|
pstOld->wHour,
|
|
pstOld->wMinute,
|
|
pstOld->wSecond,
|
|
pstOld->wMilliseconds,
|
|
szSupportedLinkActions,
|
|
linkInf.szExtendedStateInfo);
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// Method: GetMsg()
|
|
// Member of:
|
|
// Arguments:
|
|
// Returns:
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////////////
|
|
HRESULT CAQAdminCli::GetMsg(IN IAQEnumMessages *pMsgEnum, OUT IAQMessage **ppMsg, IN OUT MESSAGE_INFO *pMsgInf)
|
|
{
|
|
HRESULT hr;
|
|
DWORD cFetched;
|
|
|
|
hr = pMsgEnum->Next(1, ppMsg, &cFetched);
|
|
if(hr == S_FALSE)
|
|
{
|
|
goto Exit;
|
|
}
|
|
else if(FAILED(hr))
|
|
{
|
|
printf("pMsgEnum->Next failed with 0x%x\n", hr);
|
|
goto Exit;
|
|
}
|
|
else if(NULL == (*ppMsg))
|
|
{
|
|
printf("pMsg is NULL.\n", hr);
|
|
goto Exit;
|
|
}
|
|
else
|
|
{
|
|
ZeroMemory(pMsgInf, sizeof(MESSAGE_INFO));
|
|
pMsgInf->dwVersion = CURRENT_QUEUE_ADMIN_VERSION;
|
|
hr = (*ppMsg)->GetInfo(pMsgInf);
|
|
if(FAILED(hr))
|
|
{
|
|
printf("pMsg->GetInfo failed with 0x%x\n", hr);
|
|
goto Exit;
|
|
}
|
|
}
|
|
|
|
Exit:
|
|
return hr;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// Method: GetQueue()
|
|
// Member of: CAQAdminCli
|
|
// Arguments:
|
|
// Returns: S_FALSE - no more links
|
|
// S_OK - success
|
|
// Description: Caller must allocate pQueueInf
|
|
////////////////////////////////////////////////////////////////////////////
|
|
HRESULT CAQAdminCli::GetQueue(IN IEnumLinkQueues *pQueueEnum, OUT ILinkQueue **ppQueue, IN OUT QUEUE_INFO *pQueueInf)
|
|
{
|
|
HRESULT hr;
|
|
DWORD cFetched;
|
|
|
|
if (NULL == pQueueEnum)
|
|
return S_FALSE;
|
|
|
|
hr = pQueueEnum->Next(1, ppQueue, &cFetched);
|
|
if(hr == S_FALSE)
|
|
{
|
|
goto Exit;
|
|
}
|
|
else if(FAILED(hr))
|
|
{
|
|
printf("pQueueEnum->Next failed with 0x%x\n", hr);
|
|
goto Exit;
|
|
}
|
|
else if(NULL == (*ppQueue))
|
|
{
|
|
printf("pQueue is NULL.\n", hr);
|
|
goto Exit;
|
|
}
|
|
else
|
|
{
|
|
ZeroMemory(pQueueInf, sizeof(QUEUE_INFO));
|
|
pQueueInf->dwVersion = CURRENT_QUEUE_ADMIN_VERSION;
|
|
hr = (*ppQueue)->GetInfo(pQueueInf);
|
|
if(FAILED(hr))
|
|
{
|
|
printf("pQueue->GetInfo failed with 0x%x\n", hr);
|
|
goto Exit;
|
|
}
|
|
}
|
|
|
|
Exit:
|
|
return hr;
|
|
}
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// Method: GetLink()
|
|
// Member of: CAQAdminCli
|
|
// Arguments:
|
|
// Returns: S_FALSE - no more links
|
|
// S_OK - success
|
|
// Description: Caller must allocate pLinkInf
|
|
////////////////////////////////////////////////////////////////////////////
|
|
HRESULT CAQAdminCli::GetLink(IN IEnumVSAQLinks *pLinkEnum, OUT IVSAQLink **ppLink, IN OUT LINK_INFO *pLinkInf)
|
|
{
|
|
HRESULT hr;
|
|
DWORD cFetched;
|
|
|
|
hr = pLinkEnum->Next(1, ppLink, &cFetched);
|
|
if(hr == S_FALSE)
|
|
{
|
|
goto Exit;
|
|
}
|
|
else if(FAILED(hr))
|
|
{
|
|
printf("pLinkEnum->Next failed with 0x%x\n", hr);
|
|
goto Exit;
|
|
}
|
|
else if(NULL == (*ppLink))
|
|
{
|
|
printf("pLink is NULL.\n", hr);
|
|
goto Exit;
|
|
}
|
|
else
|
|
{
|
|
ZeroMemory(pLinkInf, sizeof(LINK_INFO));
|
|
pLinkInf->dwVersion = CURRENT_QUEUE_ADMIN_VERSION;
|
|
hr = (*ppLink)->GetInfo(pLinkInf);
|
|
if(FAILED(hr))
|
|
{
|
|
printf("pLink->GetInfo failed with 0x%x\n", hr);
|
|
if (HRESULT_FROM_WIN32(RPC_S_SERVER_UNAVAILABLE) == hr)
|
|
printf("RPC Server Unavailable.\n");
|
|
else if ( hr == E_POINTER )
|
|
printf("Null pointer.\n");
|
|
else if ( hr == E_OUTOFMEMORY )
|
|
printf("Out of memory.\n");
|
|
else if ( hr == E_INVALIDARG )
|
|
printf("Invalid argument.\n");
|
|
else
|
|
printf("Unknown error.\n");
|
|
goto Exit;
|
|
}
|
|
}
|
|
|
|
Exit:
|
|
return hr;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// Method: ~CAQAdminCli()
|
|
// Member of:
|
|
// Arguments:
|
|
// Returns:
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////////////
|
|
CAQAdminCli::~CAQAdminCli()
|
|
{
|
|
if(NULL != m_pFilterCmd)
|
|
delete (CCmdInfo*) m_pFilterCmd;
|
|
if(NULL != m_pActionCmd)
|
|
delete (CCmdInfo*) m_pActionCmd;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// Method: Cleanup()
|
|
// Member of:
|
|
// Arguments:
|
|
// Returns:
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////////////
|
|
void CAQAdminCli::Cleanup()
|
|
{
|
|
if(m_pAdmin)
|
|
m_pAdmin->Release();
|
|
if(m_pVS)
|
|
m_pVS->Release();
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// Method: CAQAdminCli()
|
|
// Member of:
|
|
// Arguments:
|
|
// Returns:
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////////////
|
|
CAQAdminCli::CAQAdminCli()
|
|
{
|
|
m_pAdmin = NULL;
|
|
m_pVS = NULL;
|
|
m_dwDispFlags = (DispFlags) (DF_LINK | DF_QUEUE | DF_MSG);
|
|
m_pFilterCmd = NULL;
|
|
m_pActionCmd = NULL;
|
|
m_fUseMTA = FALSE;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// Method: StopAllLinks()
|
|
// Member of:
|
|
// Arguments:
|
|
// Returns:
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////////////
|
|
HRESULT CAQAdminCli::StopAllLinks()
|
|
{
|
|
HRESULT hr;
|
|
|
|
hr = m_pVS->StopAllLinks();
|
|
if(FAILED(hr))
|
|
{
|
|
printf("m_pAdmin->StopAllLinks failed with 0x%x\n", hr);
|
|
}
|
|
else
|
|
printf("StopAllLinks succeeded\n", hr);
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// Method: StartAllLinks()
|
|
// Member of:
|
|
// Arguments:
|
|
// Returns:
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////////////
|
|
HRESULT CAQAdminCli::StartAllLinks()
|
|
{
|
|
HRESULT hr;
|
|
|
|
hr = m_pVS->StartAllLinks();
|
|
if(FAILED(hr))
|
|
{
|
|
printf("StartAllLinks failed with 0x%x\n", hr);
|
|
}
|
|
else
|
|
printf("StartAllLinks succeeded\n", hr);
|
|
|
|
return hr;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// Method: GetGlobalLinkState()
|
|
// Member of:
|
|
// Arguments:
|
|
// Returns:
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////////////
|
|
HRESULT CAQAdminCli::GetGlobalLinkState()
|
|
{
|
|
HRESULT hr;
|
|
|
|
hr = m_pVS->GetGlobalLinkState();
|
|
if(FAILED(hr))
|
|
{
|
|
printf("GetGlobalLinkState failed with 0x%x\n", hr);
|
|
}
|
|
else if (S_OK == hr)
|
|
{
|
|
printf("Links UP\n");
|
|
}
|
|
else
|
|
{
|
|
printf("Links STOPPED by admin\n");
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CAQAdminCli::MessageAction(MESSAGE_FILTER *pFilter, MESSAGE_ACTION action)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
DWORD cMsgs = 0;
|
|
|
|
hr = ApplyActionToMessages(m_pVS, pFilter, action, &cMsgs);
|
|
if(FAILED(hr))
|
|
{
|
|
printf("m_pAdmin->ApplyActionToMessages failed with 0x%x\n", hr);
|
|
}
|
|
else
|
|
printf("ApplyActionToMessages succeeded on %d Messages\n", cMsgs);
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// Method: Help()
|
|
// Member of:
|
|
// Arguments:
|
|
// Returns:
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////////////
|
|
void CAQAdminCli::Help()
|
|
{
|
|
puts( "\n Commands:\n"
|
|
"====================\n"
|
|
"setserver [sn] [,vs=VSnumber] - sets the server to administer. Default is localhost,\n"
|
|
" first virtual server\n"
|
|
"linkinfo [ln,ln,...] - prints link information for specified links or\n"
|
|
" for all links (no arguments)\n"
|
|
"queueinfo [ln,ln,...] - prints queue information for specified links or\n"
|
|
" for all links (no arguments)\n"
|
|
"msginfo [qn,qn,...,] eflt - prints message information for specified queues or\n"
|
|
" for all queues (no 'qn' arguments)\n"
|
|
"delmsg [qn,qn,...,] flt - deletes messages from specified queues or\n"
|
|
" from all queues (no 'qn' arguments)\n"
|
|
"msgaction mac, flt - applies msg. action to specified messages\n"
|
|
"linkaction ln [,ln,...], lac - applies link action to specified links\n"
|
|
" [, mac, flt] if action is \"MSGACTION\", must specify mac and flt\n"
|
|
"queueaction qn [,qn,...], qac - applies queue action to specified queues\n"
|
|
" [, mac, flt] if action is \"MSGACTION\", must specify mac and flt\n"
|
|
"stopalllinks - stops all the links\n"
|
|
"startalllinks - starts all the links\n"
|
|
"checklinks - checks the global status of the links\n"
|
|
"freezelink ln [,ln,...] - freezes the specified links\n"
|
|
"meltlink ln [,ln,...] - un-freezes the specified links\n"
|
|
"kicklink ln [,ln,...] - kicks (forces a connect) for the specified links\n"
|
|
"useMTA - uses the MTA AQ administrator\n"
|
|
"useSMTP - uses the SMTP AQ administrator\n"
|
|
"?, help - this help\n"
|
|
"quit - exits the program\n"
|
|
"!cmd - executes shell command 'cmd'\n"
|
|
"\nwhere\n\n"
|
|
"ln = link name\n"
|
|
"qn = queue name\n"
|
|
"sn = server name\n"
|
|
"mac = \"ma=<action>\" message action. Actions are: \"DEL\"|\"DEL_S\"|\"FREEZE\"|\"THAW\"|\"COUNT\"\n"
|
|
"lac = \"la=<action>\" link action. Actions: \"KICK\"|\"FREEZE\"|\"THAW\"|\"MSGACTION\"\n"
|
|
"qac = \"qa=<action>\" queue action. Actions: \"MSGACTION\"\n"
|
|
"eflt = \"token,token,...\" msg. enum. filter. Following tokens are suported:\n"
|
|
" \"ft=<flags>\" Flags are: \"FIRST_N\"|\"OLDER\"|\"OLDEST\"|\"LARGER\"|\"LARGEST\"|\"NOT\"|\"SENDER\"|\"RCPT\"|\"ALL\"\n"
|
|
" (filter type. Flags can be or'ed)\n"
|
|
" \"mn=<number>\" (number of messages)\n"
|
|
" \"ms=<number>\" (message size)\n"
|
|
" \"md=<date>\" (message date mm/dd/yy hh:mm:ss:mil [UTC])\n"
|
|
" \"sk=<number>\" (skip messages)\n"
|
|
" \"msndr=<string>\" (message sender)\n"
|
|
" \"mrcpt=<string>\" (message recipient)\n"
|
|
"flt = \"token,token,...\" msg. filter. Following tokens are suported:\n"
|
|
" \"flags=<flags>\" Flags are: \"MSGID\"|\"SENDER\"|\"RCPT\"|\"SIZE\"|\"TIME\"|\"FROZEN\"|\"NOT\"|\"ALL\"\n"
|
|
" (filter flags. Flags can be or'ed)\n"
|
|
" \"id=<string>\" (message id as shown by msginfo)\n"
|
|
" \"sender=<string>\" (the sender of the message)\n"
|
|
" \"rcpt=<string>\" (the recipient of the message)\n"
|
|
" \"size=<number>\" (the minimum message size)\n"
|
|
" \"date=<date>\" (oldest message date mm/dd/yy hh:mm:ss:mil [UTC])\n"
|
|
);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// Method: Init()
|
|
// Member of:
|
|
// Arguments:
|
|
// Returns:
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////////////
|
|
HRESULT CAQAdminCli::Init()
|
|
{
|
|
HRESULT hr;
|
|
|
|
hr = CoCreateInstance(CLSID_AQAdmin,
|
|
NULL,
|
|
CLSCTX_INPROC_SERVER,
|
|
IID_IAQAdmin,
|
|
(void **) &m_pAdmin);
|
|
if(FAILED(hr))
|
|
{
|
|
printf("CoCreateInstance failed with 0x%x\n", hr);
|
|
goto Exit;
|
|
}
|
|
|
|
hr = m_pAdmin->GetVirtualServerAdminITF(NULL, L"1", &m_pVS);
|
|
if(FAILED(hr))
|
|
{
|
|
printf("GetVirtualServerAdminITF failed with 0x%x\n", hr);
|
|
goto Exit;
|
|
}
|
|
Exit:
|
|
return hr;
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// Method: Init()
|
|
// Member of:
|
|
// Arguments:
|
|
// Returns:
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////////////
|
|
HRESULT CAQAdminCli::UseMTA(BOOL fUseMTA)
|
|
{
|
|
HRESULT hr;
|
|
IAQAdmin *pAdminTmp = NULL;
|
|
|
|
// don't release the old one unless you can create the new one.
|
|
if(fUseMTA)
|
|
hr = CoCreateInstance(CLSID_MAQAdmin,
|
|
NULL,
|
|
CLSCTX_INPROC_SERVER,
|
|
IID_IAQAdmin,
|
|
(void **) &pAdminTmp);
|
|
else
|
|
hr = CoCreateInstance(CLSID_AQAdmin,
|
|
NULL,
|
|
CLSCTX_INPROC_SERVER,
|
|
IID_IAQAdmin,
|
|
(void **) &pAdminTmp);
|
|
|
|
if(FAILED(hr))
|
|
{
|
|
printf("CoCreateInstance failed with 0x%x\n", hr);
|
|
goto Exit;
|
|
}
|
|
else
|
|
{
|
|
if(NULL != m_pAdmin)
|
|
{
|
|
m_pAdmin->Release();
|
|
m_pAdmin = NULL;
|
|
}
|
|
|
|
m_pAdmin = pAdminTmp;
|
|
m_fUseMTA = fUseMTA;
|
|
|
|
printf("AQ Admin is %s.\n", fUseMTA ? "MTA" : "SMTP");
|
|
}
|
|
|
|
hr = m_pAdmin->GetVirtualServerAdminITF(NULL, L"1", &m_pVS);
|
|
if(FAILED(hr))
|
|
{
|
|
printf("GetVirtualServerAdminITF failed with 0x%x\n", hr);
|
|
goto Exit;
|
|
}
|
|
Exit:
|
|
return hr;
|
|
}
|
|
|
|
HRESULT ExecuteCmd(CAQAdminCli& Admcli, LPSTR szCmd)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
BOOL fQuit = FALSE;
|
|
|
|
// see if it's a system command
|
|
if(szCmd[0] == '!')
|
|
{
|
|
system(szCmd + 1);
|
|
goto Exit;
|
|
}
|
|
|
|
Admcli.m_pFilterCmd = new CCmdInfo(szCmd);
|
|
if(NULL == Admcli.m_pFilterCmd)
|
|
{
|
|
printf("Cannot allocate command info.\n");
|
|
hr = E_OUTOFMEMORY;
|
|
goto Exit;
|
|
}
|
|
|
|
if(!lstrcmpi(Admcli.m_pFilterCmd->szCmdKey, "quit"))
|
|
{
|
|
fQuit = TRUE;
|
|
goto Exit;
|
|
}
|
|
else if(!lstrcmpi(Admcli.m_pFilterCmd->szCmdKey, "freezelink"))
|
|
{
|
|
// set default tag to 'ln'
|
|
Admcli.m_pFilterCmd->SetDefTag("ln");
|
|
// check there's at least one link name
|
|
hr = Admcli.m_pFilterCmd->GetValue("ln", NULL);
|
|
if(FAILED(hr))
|
|
{
|
|
printf("Error: must have at least one link name\n");
|
|
}
|
|
else
|
|
{
|
|
Admcli.m_pActionCmd = new CCmdInfo("FREEZE");
|
|
Admcli.PrintLinkInfo();
|
|
delete (CCmdInfo*) Admcli.m_pActionCmd;
|
|
Admcli.m_pActionCmd = NULL;
|
|
}
|
|
}
|
|
else if(!lstrcmpi(Admcli.m_pFilterCmd->szCmdKey, "meltlink"))
|
|
{
|
|
// set default tag to 'ln'
|
|
Admcli.m_pFilterCmd->SetDefTag("ln");
|
|
// check there's at least one link name
|
|
hr = Admcli.m_pFilterCmd->GetValue("ln", NULL);
|
|
if(FAILED(hr))
|
|
{
|
|
printf("Error: must have at least one link name\n");
|
|
}
|
|
else
|
|
{
|
|
Admcli.m_pActionCmd = new CCmdInfo("THAW");
|
|
Admcli.PrintLinkInfo();
|
|
delete (CCmdInfo*) Admcli.m_pActionCmd;
|
|
Admcli.m_pActionCmd = NULL;
|
|
}
|
|
}
|
|
else if(!lstrcmpi(Admcli.m_pFilterCmd->szCmdKey, "kicklink"))
|
|
{
|
|
// set default tag to 'ln'
|
|
Admcli.m_pFilterCmd->SetDefTag("ln");
|
|
// check there's at least one link name
|
|
hr = Admcli.m_pFilterCmd->GetValue("ln", NULL);
|
|
if(FAILED(hr))
|
|
{
|
|
printf("Error: must have at least one link name\n");
|
|
}
|
|
else
|
|
{
|
|
Admcli.m_pActionCmd = new CCmdInfo("KICK");
|
|
Admcli.PrintLinkInfo();
|
|
delete (CCmdInfo*) Admcli.m_pActionCmd;
|
|
Admcli.m_pActionCmd = NULL;
|
|
}
|
|
}
|
|
else if(!lstrcmpi(Admcli.m_pFilterCmd->szCmdKey, "linkaction"))
|
|
{
|
|
char buf[64];
|
|
|
|
// set default tag to 'ln'
|
|
Admcli.m_pFilterCmd->SetDefTag("ln");
|
|
// check there's at least one link name
|
|
hr = Admcli.m_pFilterCmd->GetValue("ln", NULL);
|
|
if(FAILED(hr))
|
|
{
|
|
printf("Error: must have at least one link name\n");
|
|
}
|
|
else
|
|
{
|
|
// check there's an action
|
|
hr = Admcli.m_pFilterCmd->GetValue("la", buf);
|
|
if(FAILED(hr))
|
|
{
|
|
printf("Error: must have a link action\n");
|
|
}
|
|
else
|
|
{
|
|
Admcli.m_pActionCmd = new CCmdInfo(buf);
|
|
Admcli.PrintLinkInfo();
|
|
delete (CCmdInfo*) Admcli.m_pActionCmd;
|
|
Admcli.m_pActionCmd = NULL;
|
|
}
|
|
}
|
|
}
|
|
else if(!lstrcmpi(Admcli.m_pFilterCmd->szCmdKey, "queueaction"))
|
|
{
|
|
char buf[64];
|
|
|
|
// set default tag to 'ln'
|
|
Admcli.m_pFilterCmd->SetDefTag("qn");
|
|
// check there's at least one link name
|
|
hr = Admcli.m_pFilterCmd->GetValue("qn", NULL);
|
|
if(FAILED(hr))
|
|
{
|
|
printf("Error: must have at least one queue name\n");
|
|
}
|
|
else
|
|
{
|
|
// check there's an action
|
|
hr = Admcli.m_pFilterCmd->GetValue("qa", buf);
|
|
if(FAILED(hr))
|
|
{
|
|
printf("Error: must have a queue action\n");
|
|
}
|
|
else
|
|
{
|
|
Admcli.m_pActionCmd = new CCmdInfo(buf);
|
|
Admcli.PrintQueueInfo();
|
|
delete (CCmdInfo*) Admcli.m_pActionCmd;
|
|
Admcli.m_pActionCmd = NULL;
|
|
}
|
|
}
|
|
}
|
|
else if(!lstrcmpi(Admcli.m_pFilterCmd->szCmdKey, "linkinfo"))
|
|
{
|
|
//Admcli.m_dwDispFlags = CAQAdminCli::DF_LINK;
|
|
// set default tag to 'ln'
|
|
Admcli.m_pFilterCmd->SetDefTag("ln");
|
|
Admcli.m_pActionCmd = new CCmdInfo("LINK_INFO");
|
|
Admcli.PrintLinkInfo();
|
|
delete (CCmdInfo*) Admcli.m_pActionCmd;
|
|
Admcli.m_pActionCmd = NULL;
|
|
}
|
|
else if(!lstrcmpi(Admcli.m_pFilterCmd->szCmdKey, "queueinfo"))
|
|
{
|
|
//Admcli.m_dwDispFlags = CAQAdminCli::DF_QUEUE;
|
|
// set default tag to 'ln'
|
|
Admcli.m_pFilterCmd->SetDefTag("ln");
|
|
Admcli.m_pActionCmd = new CCmdInfo("QUEUE_INFO");
|
|
Admcli.PrintQueueInfo();
|
|
delete (CCmdInfo*) Admcli.m_pActionCmd;
|
|
Admcli.m_pActionCmd = NULL;
|
|
}
|
|
else if(!lstrcmpi(Admcli.m_pFilterCmd->szCmdKey, "msginfo"))
|
|
{
|
|
//Admcli.m_dwDispFlags = CAQAdminCli::DF_MSG;
|
|
//Admcli.GetLinkInfo();
|
|
// set default tag to 'qn'
|
|
Admcli.m_pFilterCmd->SetDefTag("qn");
|
|
Admcli.m_pActionCmd = new CCmdInfo("MSG_INFO");
|
|
Admcli.PrintMsgInfo();
|
|
delete (CCmdInfo*) Admcli.m_pActionCmd;
|
|
Admcli.m_pActionCmd = NULL;
|
|
}
|
|
else if(!lstrcmpi(Admcli.m_pFilterCmd->szCmdKey, "delmsg"))
|
|
{
|
|
// set default tag to 'qn'
|
|
Admcli.m_pFilterCmd->SetDefTag("qn");
|
|
Admcli.m_pActionCmd = new CCmdInfo("DEL_MSG");
|
|
Admcli.PrintMsgInfo();
|
|
delete (CCmdInfo*) Admcli.m_pActionCmd;
|
|
Admcli.m_pActionCmd = NULL;
|
|
}
|
|
else if(!lstrcmpi(Admcli.m_pFilterCmd->szCmdKey, "useMTA"))
|
|
{
|
|
Admcli.UseMTA(TRUE);
|
|
}
|
|
else if(!lstrcmpi(Admcli.m_pFilterCmd->szCmdKey, "useSMTP"))
|
|
{
|
|
Admcli.UseMTA(FALSE);
|
|
}
|
|
else if(!lstrcmpi(Admcli.m_pFilterCmd->szCmdKey, "msgaction"))
|
|
{
|
|
MESSAGE_ACTION Action;
|
|
MESSAGE_FILTER Filter;
|
|
char buf[64];
|
|
BOOL fActOK = TRUE;
|
|
ZeroMemory(buf, sizeof(buf));
|
|
|
|
// set default tag to 'ma'
|
|
Admcli.m_pFilterCmd->SetDefTag("ma");
|
|
Admcli.m_pFilterCmd->GetValue("ma", buf);
|
|
|
|
// set the action
|
|
hr = Admcli.SetMsgAction(&Action, Admcli.m_pFilterCmd);
|
|
if(FAILED(hr))
|
|
{
|
|
printf("Error: must specify an action\n");
|
|
fActOK = FALSE;
|
|
}
|
|
|
|
if(fActOK)
|
|
{
|
|
// set the filter
|
|
hr = Admcli.SetMsgFilter(&Filter, Admcli.m_pFilterCmd);
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
Admcli.MessageAction(&Filter, Action);
|
|
}
|
|
Admcli.FreeStruct(&Filter);
|
|
}
|
|
}
|
|
else if(!lstrcmpi(Admcli.m_pFilterCmd->szCmdKey, "stopalllinks"))
|
|
{
|
|
Admcli.StopAllLinks();
|
|
}
|
|
else if(!lstrcmpi(Admcli.m_pFilterCmd->szCmdKey, "startalllinks"))
|
|
{
|
|
Admcli.StartAllLinks();
|
|
}
|
|
else if(!lstrcmpi(Admcli.m_pFilterCmd->szCmdKey, "setserver"))
|
|
{
|
|
char buf[MAX_SERVER_NAME];
|
|
char vsn[32];
|
|
char *pServer = NULL;
|
|
Admcli.m_pFilterCmd->SetDefTag("sn");
|
|
hr = Admcli.m_pFilterCmd->GetValue("sn", buf);
|
|
if(FAILED(hr))
|
|
pServer = NULL;
|
|
else
|
|
pServer = (LPSTR)buf;
|
|
|
|
hr = Admcli.m_pFilterCmd->GetValue("vs", vsn);
|
|
if(FAILED(hr))
|
|
lstrcpy(vsn, "1");
|
|
|
|
hr = Admcli.SetServer(pServer, (LPSTR)vsn);
|
|
if(FAILED(hr))
|
|
printf("setserver failed. Using the old server.\n");
|
|
else
|
|
printf("setserver succeeded.\n");
|
|
}
|
|
else if (!lstrcmpi(Admcli.m_pFilterCmd->szCmdKey, "checklinks"))
|
|
{
|
|
Admcli.GetGlobalLinkState();
|
|
}
|
|
else if(!lstrcmpi(Admcli.m_pFilterCmd->szCmdKey, "?") ||
|
|
!lstrcmpi(Admcli.m_pFilterCmd->szCmdKey, "help"))
|
|
{
|
|
Admcli.Help();
|
|
}
|
|
else
|
|
{
|
|
puts("Unknown command. Type '?' for on-line help");
|
|
}
|
|
|
|
if(Admcli.m_pFilterCmd)
|
|
{
|
|
delete Admcli.m_pFilterCmd;
|
|
Admcli.m_pFilterCmd = NULL;
|
|
}
|
|
|
|
Exit:
|
|
// S_FALSE means "quit" for the main command loop. Return S_OK
|
|
// (or error) unless fQuit is true
|
|
if(fQuit)
|
|
return S_FALSE;
|
|
else if(S_FALSE == hr)
|
|
return S_OK;
|
|
else
|
|
return hr;
|
|
}
|
|
|
|
int __cdecl main(int argc, char **argv)
|
|
{
|
|
HRESULT hr;
|
|
char szCmd[4096];
|
|
char szCmdTmp[MAX_CMD_LEN];
|
|
|
|
CAQAdminCli Admcli;
|
|
|
|
hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
|
|
if(FAILED(hr))
|
|
{
|
|
printf("CoInitializeEx failed w/ 0x%x\n", hr);
|
|
return hr;
|
|
}
|
|
|
|
hr = Admcli.Init();
|
|
if(FAILED(hr))
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
// check if we have cmd line commands
|
|
if(argc > 1)
|
|
{
|
|
for(int i = 1; i < argc; i++)
|
|
{
|
|
if(!lstrcmpi(argv[i], "-?") || !lstrcmpi(argv[i], "/?"))
|
|
{
|
|
Admcli.Help();
|
|
goto Exit;
|
|
}
|
|
else
|
|
{
|
|
// this is a command
|
|
ZeroMemory(szCmd, sizeof(szCmd));
|
|
|
|
if(argv[i][0] == '\"' && argv[i][lstrlen(argv[i])-1] == '\"')
|
|
{
|
|
// strip quotes
|
|
CopyMemory(szCmd, argv[i]+1, lstrlen(argv[i])-2);
|
|
}
|
|
else
|
|
CopyMemory(szCmd, argv[i], lstrlen(argv[i]));
|
|
|
|
ExecuteCmd(Admcli, szCmd);
|
|
}
|
|
}
|
|
|
|
goto Exit;
|
|
}
|
|
|
|
puts("\nAQ administrator tool v 1.0\nType '?' or 'help' for list of commands.\n");
|
|
while(TRUE)
|
|
{
|
|
char *cmd = NULL;
|
|
printf(">");
|
|
|
|
ZeroMemory(szCmd, sizeof(szCmd));
|
|
if(!Admcli.m_fUseMTA)
|
|
{
|
|
szCmd[0] = 127;
|
|
cmd = _cgets(szCmd);
|
|
}
|
|
else
|
|
{
|
|
// read line by line until CRLF.CRLF
|
|
do
|
|
{
|
|
ZeroMemory(szCmdTmp, sizeof(szCmdTmp));
|
|
szCmdTmp[0] = 127;
|
|
cmd = _cgets(szCmdTmp);
|
|
if(!lstrcmp(cmd, "."))
|
|
break;
|
|
lstrcat(szCmd, cmd);
|
|
}
|
|
while(TRUE);
|
|
|
|
cmd = szCmd;
|
|
}
|
|
|
|
hr = ExecuteCmd(Admcli, cmd);
|
|
if(S_FALSE == hr)
|
|
break;
|
|
}
|
|
|
|
Exit:
|
|
Admcli.Cleanup();
|
|
CoUninitialize();
|
|
|
|
return hr;
|
|
}
|
|
|
|
#include "aqadmin.c"
|
|
|