2025-11-28 00:35:46 +09:00

2126 lines
86 KiB
C++

// --------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// --------------------------------------------------------------------
/* ************************************************************************ */
/* */
/* Main file of the application MQ API test. */
/* */
/* ************************************************************************ */
//
// MainFrm.cpp : implementation of the CMainFrame class
//
#include "stdafx.h"
#include "MQApitst.h"
#include <afxtempl.h>
#include "MainFrm.h"
#include "CrQDlg.h"
#include "DelQDlg.h"
#include "OpenQDlg.h"
#include "ClosQDlg.h"
#include "SendMDlg.h"
#include "RecvMDlg.h"
#include "RecWDlg.h"
#include "LocatDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
LPSTR UnicodeStringToAnsiString(LPCWSTR lpcsUnicode)
{
LPSTR lpAnsiString = NULL;
if (lpcsUnicode)
{
size_t dwSize=0;
wcstombs_s(&dwSize, NULL, 0, lpcsUnicode, 0);
lpAnsiString = new char[dwSize];
size_t nResultedStringSize=0;
size_t rc = wcstombs_s(
&nResultedStringSize,
lpAnsiString,
dwSize,
lpcsUnicode,
dwSize
);
if (rc != (size_t)(0) )
{
AfxMessageBox(_T("An unsupported wide character was encountered. Exiting..."));
exit(1);
}
}
return lpAnsiString;
}
void AnsiStringToUnicode(LPWSTR lpsUnicode, LPSTR lpsAnsi, DWORD nSize)
{
if (lpsUnicode == NULL)
{
return;
}
ASSERT(lpsAnsi != NULL);
size_t nResultedStringSize=0;
size_t rc = mbstowcs_s(
&nResultedStringSize,
lpsUnicode,
nSize,
lpsAnsi,
nSize);
if (rc != (size_t)(0))
{
AfxMessageBox(_T("An unsupported wide character was encountered. Exiting..."));
exit(1);
}
}
#ifdef UNICODE
#define _mqscpy(dest, src) ASSERT(src != NULL); \
wcsncpy_s(dest, BUFFERSIZE, src, _TRUNCATE);
#else
#define _mqscpy(dest, src) ASSERT(src != NULL); \
AnsiStringToUnicode(dest, src, _tcslen(src)+1);
#endif
BOOL GetTextualSid(
PSID pSid, // Binary SID
LPTSTR TextualSID, // Buffer for textual representation of an SID
LPDWORD dwBufferLen // Required/provided size of the textual SID buffer
)
{
PSID_IDENTIFIER_AUTHORITY psia;
DWORD dwSubAuthorities;
DWORD dwSidRev = SID_REVISION;
DWORD dwCounter;
DWORD dwSidSize;
// Obtain the identifier-authority value in the SID.
psia = &((SID *)pSid)->IdentifierAuthority;
// Obtain the number of subauthorities in the SID.
dwSubAuthorities = (DWORD)((SID *)pSid)->SubAuthorityCount;
//
// Compute the buffer length.
// S-SID_REVISION + identifier authority + subauthorities + NULL
//
dwSidSize = (15 + 12 + (12 * dwSubAuthorities) + 1) * sizeof(TCHAR);
//
// Check the buffer length provided.
// If it is not large enough, indicate the proper size and call SetLastError.
//
if (*dwBufferLen < dwSidSize)
{
*dwBufferLen = dwSidSize;
SetLastError(ERROR_INSUFFICIENT_BUFFER);
return FALSE;
}
//
// Obtain a textual representation of S-SID_REVISION.
//
TextualSID += _stprintf_s(TextualSID, *dwBufferLen, TEXT("S-%lu-"), dwSidRev );
//
// Obtain a textual representation of the identifier-authority value.
//
if ( (psia->Value[0] != 0) || (psia->Value[1] != 0) )
{
TextualSID += _stprintf_s(TextualSID,
*dwBufferLen,
TEXT("0x%02hx%02hx%02hx%02hx%02hx%02hx"),
(USHORT)psia->Value[0],
(USHORT)psia->Value[1],
(USHORT)psia->Value[2],
(USHORT)psia->Value[3],
(USHORT)psia->Value[4],
(USHORT)psia->Value[5]);
}
else
{
TextualSID += _stprintf_s(TextualSID,
*dwBufferLen,
TEXT("%lu"),
(ULONG)(psia->Value[5] ) +
(ULONG)(psia->Value[4] << 8) +
(ULONG)(psia->Value[3] << 16) +
(ULONG)(psia->Value[2] << 24) );
}
//
// Loop through the subauthorities.
//
for (dwCounter=0 ; dwCounter < dwSubAuthorities ; dwCounter++)
{
TextualSID += _stprintf_s(TextualSID, *dwBufferLen, TEXT("-%lu"),
((SID *)pSid)->SubAuthority[ dwCounter] );
}
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////
// CMainFrame
IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd)
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
//{{AFX_MSG_MAP(CMainFrame)
ON_WM_CREATE()
ON_COMMAND(ID_API_CREATE_QUEUE, OnApiCreateQueue)
ON_COMMAND(ID_API_DELETE_QUEUE, OnApiDeleteQueue)
ON_COMMAND(ID_API_OPEN_QUEUE, OnApiOpenQueue)
ON_COMMAND(ID_API_CLOSE_QUEUE, OnApiCloseQueue)
ON_COMMAND(ID_API_SEND_MESSAGE, OnApiSendMessage)
ON_COMMAND(ID_API_RECEIVE_MESSAGE, OnApiReceiveMessage)
ON_COMMAND(ID_API_LOCATE, OnApiLocate)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
static UINT indicators[] =
{
ID_SEPARATOR, // status line indicator
ID_INDICATOR_CAPS,
ID_INDICATOR_NUM,
ID_INDICATOR_SCRL,
};
/////////////////////////////////////////////////////////////////////////////
// CMainFrame construction/destruction
CMainFrame::CMainFrame()
{
// TODO: Add member initialization code here.
}
CMainFrame::~CMainFrame()
{
}
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
return -1;
if (!m_wndToolBar.Create(this) ||
!m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
{
TRACE0("The attempt to load the toolbar failed.\n");
return -1;
}
if (!m_wndStatusBar.Create(this) ||
!m_wndStatusBar.SetIndicators(indicators,
sizeof(indicators)/sizeof(UINT)))
{
TRACE0("The attempt to create the toolbar or set its indicators failed.\n");
return -1;
}
// TODO: Remove this if you don't want tool tips or a resizeable toolbar.
m_wndToolBar.SetBarStyle(m_wndToolBar.GetBarStyle() |
CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);
// TODO: Delete these three lines if you don't want the toolbar to
// be dockable.
m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
EnableDocking(CBRS_ALIGN_ANY);
DockControlBar(&m_wndToolBar);
return 0;
}
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs.
return CFrameWnd::PreCreateWindow(cs);
}
/////////////////////////////////////////////////////////////////////////////
// CMainFrame diagnostics
#ifdef _DEBUG
void CMainFrame::AssertValid() const
{
CFrameWnd::AssertValid();
}
void CMainFrame::Dump(CDumpContext& dc) const
{
CFrameWnd::Dump(dc);
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CMainFrame message handlers
#define MAXINDEX 31
/* ************************************************************************ */
/* RemoveFromPathNameArray */
/* ************************************************************************ */
/* This function goes through the path name array and compares a given */
/* path name to the path names of the items in the array. */
/* If a match is found, the item is removed from the array and the function */
/* returns a pointer to the item; otherwise, a NULL pointer is returned. */
/* ************************************************************************ */
ARRAYQ* CMainFrame::RemoveFromPathNameArray(TCHAR *szFormatPathName)
{
int Index;
int MaxIndex = m_PathNameArray.GetSize();
ARRAYQ* pQueue;
//
// Loop through the path name array.
//
for (Index=0; Index<MaxIndex; Index++)
{
if (m_PathNameArray[Index]->bFormatNameOnly==TRUE)
{
if (_tcscmp(szFormatPathName, m_PathNameArray[Index]->szFormatName) == 0)
{
//
// A match was found.
//
pQueue = m_PathNameArray[Index];
m_PathNameArray.RemoveAt(Index);
return pQueue;
}
}
else
{
if (_tcscmp(szFormatPathName, m_PathNameArray[Index]->szPathName) == 0)
{
//
// A match was found.
//
pQueue = m_PathNameArray[Index];
m_PathNameArray.RemoveAt(Index);
return pQueue;
}
}
}
return NULL; // No match was found.
}
/* ************************************************************************ */
/* CleanPathNameArray */
/* ************************************************************************ */
/* This function goes through the path name array and deletes all the */
/* items in it. The function frees the allocated memory. */
/* ************************************************************************ */
void CMainFrame::CleanPathNameArray()
{
ARRAYQ* pQueue;
while (m_PathNameArray.GetSize() > 0)
{
pQueue = m_PathNameArray[0];
m_PathNameArray.RemoveAt(0);
delete pQueue;
}
}
/* ************************************************************************ */
/* RemoveFromOpenedQueuePathNameArray */
/* ************************************************************************ */
/* This function goes through the open queue path name array and compares */
/* a given path name to the path names of the items in the array. */
/* If a match is found, the item is removed from the array and the function */
/* returns a pointer to the item; otherwise, a NULL pointer is returned. */
/* ************************************************************************ */
ARRAYQ* CMainFrame::RemoveFromOpenedQueuePathNameArray(TCHAR *szFormatPathName)
{
int Index;
int MaxIndex = m_OpenedQueuePathNameArray.GetSize();
ARRAYQ* pQueue;
//
// Loop through the open queue path name array.
//
for (Index=0; Index<MaxIndex; Index++)
{
if (m_OpenedQueuePathNameArray[Index]->bFormatNameOnly==TRUE)
{
if (_tcscmp(szFormatPathName, m_OpenedQueuePathNameArray[Index]->szFormatName) == 0)
{
pQueue = m_OpenedQueuePathNameArray[Index];
m_OpenedQueuePathNameArray.RemoveAt(Index);
return pQueue;
}
}
else
{
if (_tcscmp(szFormatPathName, m_OpenedQueuePathNameArray[Index]->szPathName) == 0)
{
//
// A match was found.
//
pQueue = m_OpenedQueuePathNameArray[Index];
m_OpenedQueuePathNameArray.RemoveAt(Index);
return pQueue;
}
}
}
return NULL; // No match was found.
}
/* ************************************************************************ */
/* IsOpenedQueueArrayEmpty */
/* ************************************************************************ */
/* This function checks whether the size of the open queue path name array */
/* is equal to or less than zero and, if so, it returns TRUE; otherwise, */
/* it returns FALSE. */
/* ************************************************************************ */
BOOL CMainFrame::IsOpenedQueueArrayEmpty()
{
if (m_OpenedQueuePathNameArray.GetSize() <= 0)
{
return TRUE;
}
else
{
return FALSE;
}
}
/* ************************************************************************ */
/* MoveToOpenedQueuePathNameArray */
/* ************************************************************************ */
/* This function moves an item from the path name array to the open queue */
/* path name array. It also it updates the handle and the access rights to */
/* the moved queue. */
/* ************************************************************************ */
void CMainFrame::MoveToOpenedQueuePathNameArray(TCHAR *szPathName,TCHAR *szFormatName,
QUEUEHANDLE hQueue, DWORD dwAccess)
{
ARRAYQ* pQueue=NULL;
//check whether pQueue is listed in the Located Queue.
pQueue = RemoveFromPathNameArray(szPathName);
//if not found in located Q:Allocated new ARRAYQ.
if (pQueue==NULL)
{
pQueue=new ARRAYQ;
if (pQueue==NULL)
{
AfxMessageBox(_T("Could not Allocate memory in function CMainFrame::MoveToOpenedQueuePathNameArray. Exiting"));
exit (1);
}
_tcsncpy_s(
pQueue->szFormatName,
sizeof(pQueue->szFormatName)/sizeof(pQueue->szFormatName[0]),
szFormatName,
sizeof(pQueue->szFormatName)/sizeof(pQueue->szFormatName[0])-1
);
_tcsncpy_s(
pQueue->szPathName,
sizeof(pQueue->szPathName)/sizeof(pQueue->szPathName[0]),
szPathName,
sizeof(pQueue->szPathName)/sizeof(pQueue->szPathName[0])-1
);
if (_tcscmp(pQueue->szPathName,_T(""))==0)
{
pQueue->bFormatNameOnly=true;
}
}
pQueue->hHandle = hQueue; // add Queue Handle.
pQueue->dwAccess = dwAccess; // add Queue Access rights.
Add2OpenedQueuePathNameArray(pQueue);
}
/* ************************************************************************ */
/* MoveToPathNameArray */
/* ************************************************************************ */
/* This function moves an item from the open queue path name array to the */
/* path name array. */
/* ************************************************************************ */
void CMainFrame::MoveToPathNameArray(TCHAR *pszPathName)
{
ARRAYQ* pQueue;
pQueue = RemoveFromOpenedQueuePathNameArray(pszPathName);
Add2PathNameArray(pQueue);
}
/* ************************************************************************ */
/* UpdatePathNameArrays */
/* ************************************************************************ */
/* This function goes through the open queue path name array, and for every */
/* item in it, it checks whether the item is found in the path name array */
/* as well. If so, the function removes the item from the path name array. */
/* ************************************************************************ */
void CMainFrame::UpdatePathNameArrays()
{
int PathNameIndex;
int OpenedPathNameIndex;
int MaxOpenedPathNameIndex = m_OpenedQueuePathNameArray.GetSize();
ARRAYQ* pQueue;
//
// Loop through the open queue path name array.
//
for (OpenedPathNameIndex=0; OpenedPathNameIndex<MaxOpenedPathNameIndex; OpenedPathNameIndex++)
{
for (PathNameIndex=0; PathNameIndex<m_PathNameArray.GetSize(); PathNameIndex++)
{
if (_tcscmp(m_OpenedQueuePathNameArray[OpenedPathNameIndex]->szPathName,
m_PathNameArray[PathNameIndex]->szPathName) == 0)
{
//
// A match was found, so remove it from path name array.
//
pQueue = m_PathNameArray[PathNameIndex];
m_PathNameArray.RemoveAt(PathNameIndex);
delete pQueue;
//
// Get out of the inner for loop.
//
break;
}
}
}
}
/* ************************************************************************ */
/* GetQueueHandle */
/* ************************************************************************ */
/* This function goes through the open queue path name array and retrieves */
/* the handle to the queue which matches a given path name. If no mathch */
/* is found, the function returns FALSE. */
/* ************************************************************************ */
BOOL CMainFrame::GetQueueHandle(TCHAR *szPathFormatName,QUEUEHANDLE* phClosedQueueHandle)
{
int Index;
int MaxIndex = m_OpenedQueuePathNameArray.GetSize();
ARRAYQ* pQueue;
//
// Loop through the open queue path name array.
//
for (Index = 0; Index<MaxIndex; Index++)
{
if (m_OpenedQueuePathNameArray[Index]->bFormatNameOnly==TRUE)
{
if (_tcscmp(szPathFormatName, m_OpenedQueuePathNameArray[Index]->szFormatName)==0)
{
//
// A match was found.
//
pQueue = m_OpenedQueuePathNameArray[Index];
*phClosedQueueHandle = pQueue->hHandle;
return TRUE;
}
}
else
{
if (_tcscmp(szPathFormatName, m_OpenedQueuePathNameArray[Index]->szPathName)==0)
{
//
// A match was found.
//
pQueue = m_OpenedQueuePathNameArray[Index];
*phClosedQueueHandle = pQueue->hHandle;
return TRUE;
}
}
}
return FALSE; // No match was found.
}
/* ************************************************************************ */
/* TranslatePathNameToFormatName */
/* ************************************************************************ */
/* This function goes retrieves the Format Name using the MSMQ API */
/* MQPathNameToFormatName. if no format name is found, the function checks */
/* whether format name was given. */
/* returns TRUE is succeeded or FALSE if not */
/* ************************************************************************ */
BOOL CMainFrame::TranslatePathNameToFormatName(TCHAR *szPathName, size_t PathNameSize, TCHAR *szFormatName, size_t FormatNameSize)
{
//
//check valid parameters
//
if (szPathName==NULL)
{
return FALSE;
}
DWORD dwFormatNameSize=FormatNameSize;
HRESULT hr;
#ifdef UNICODE
hr = MQPathNameToFormatName(szPathName,szFormatName,&dwFormatNameSize);
#else
WCHAR szwPathName[MAX_Q_FORMATNAME_LEN+1]={0};
WCHAR szwFormatName[MAX_Q_FORMATNAME_LEN+1]={0};
size_t nResultedStringSize=0;
size_t rc = mbstowcs_s(
&nResultedStringSize,
szwPathName,
sizeof(szwPathName)/sizeof(szwPathName[0]),
szPathName,
PathNameSize);
if (rc != (size_t)(0))
{
AfxMessageBox(_T("An unsupported wide character was encountered. Exiting..."));
exit(1);
}
dwFormatNameSize = sizeof(szwFormatName)/sizeof(szwFormatName[0]);
hr = MQPathNameToFormatName(szwPathName,szwFormatName,&dwFormatNameSize);
nResultedStringSize = 0;
rc = wcstombs_s(
&nResultedStringSize,
szFormatName,
FormatNameSize,
szwFormatName,
dwFormatNameSize
);
#endif
if (FAILED(hr))
{
if (IsFormatName(szPathName)==TRUE)
{
_tcsncpy_s(
szFormatName,
FormatNameSize,
szPathName,
PathNameSize);
return TRUE;
}
return FALSE;
}
return TRUE;
}
/* ************************************************************************ */
/* DisplayPathNameArray */
/* ************************************************************************ */
/* This function goes through the path name array and prints it to sreeen. */
/* ************************************************************************ */
void CMainFrame::DisplayPathNameArray()
{
int Index;
int MaxIndex = m_PathNameArray.GetSize();
TCHAR szMsgBuffer[BUFFERSIZE];
_stprintf_s(szMsgBuffer, sizeof(szMsgBuffer)/sizeof(szMsgBuffer[0]), TEXT(" Located Queues :"));
PrintToScreen(szMsgBuffer);
//
// Loop through the path name array.
//
for (Index=0; Index<MaxIndex; Index++)
{
//
// Print the path names or format names.
//
if (m_PathNameArray[Index]->bFormatNameOnly==TRUE)
{
_stprintf_s(szMsgBuffer, sizeof(szMsgBuffer)/sizeof(szMsgBuffer[0]), TEXT("\t%d. %s"),Index+1, m_PathNameArray[Index]->szFormatName);
PrintToScreen(szMsgBuffer);
}
else
{
_stprintf_s(szMsgBuffer, sizeof(szMsgBuffer)/sizeof(szMsgBuffer[0]), TEXT("\t%d. %s"),Index+1, m_PathNameArray[Index]->szPathName);
PrintToScreen(szMsgBuffer);
}
}
}
/* ************************************************************************ */
/* DisplayOpenedQueuePathNameArray */
/* ************************************************************************ */
/* This function goes through the open queue path name array and prints it */
/* to screen. */
/* ************************************************************************ */
void CMainFrame::DisplayOpenedQueuePathNameArray()
{
int Index;
int MaxIndex = m_OpenedQueuePathNameArray.GetSize();
TCHAR szMsgBuffer[BUFFERSIZE];
_stprintf_s(szMsgBuffer, sizeof(szMsgBuffer)/sizeof(szMsgBuffer[0]), TEXT(" Currently Opened Queues :"));
PrintToScreen(szMsgBuffer);
//
// Loop through the open queue path name array.
//
for (Index=0; Index<MaxIndex; Index++)
{
//
// Print the path names or format names.
//
if (m_OpenedQueuePathNameArray[Index]->bFormatNameOnly==TRUE)
{
_stprintf_s(szMsgBuffer, sizeof(szMsgBuffer)/sizeof(szMsgBuffer[0]), TEXT("\t%d. %s"),Index+1, m_OpenedQueuePathNameArray[Index]->szFormatName);
PrintToScreen(szMsgBuffer);
}
else
{
_stprintf_s(szMsgBuffer, sizeof(szMsgBuffer)/sizeof(szMsgBuffer[0]), TEXT("\t%d. %s"),Index+1, m_OpenedQueuePathNameArray[Index]->szPathName);
PrintToScreen(szMsgBuffer);
}
}
}
/* ************************************************************************ */
/* GetMsgClassStatus */
/* ************************************************************************ */
/* This function sets the proper status string based on a given MQMSG class.*/
/* ************************************************************************ */
struct
{
unsigned short mclass;
LPTSTR pszDescription;
} StringClass[] =
{
{ MQMSG_CLASS_NORMAL, TEXT("The Message was received successfully.")},
{ MQMSG_CLASS_ACK_REACH_QUEUE, TEXT("The REACH QUEUE ACK Message was read successfully.")},
{ MQMSG_CLASS_ACK_RECEIVE, TEXT("The RECEIVE ACK Message was read successfully.")},
{ MQMSG_CLASS_NACK_BAD_DST_Q, TEXT("The DESTINATION QUEUE HANDLE INVALID Nack Message was read successfully.")},
{ MQMSG_CLASS_NACK_RECEIVE_TIMEOUT, TEXT("The TIME TO RECEIVE EXPIRED Nack Message was read successfully.")},
{ MQMSG_CLASS_NACK_REACH_QUEUE_TIMEOUT, TEXT("The TIME TO REACH QUEUE EXPIRED Nack Message was read successfully.")},
{ MQMSG_CLASS_NACK_Q_EXCEED_QUOTA, TEXT("The QUEUE IS FULL Nack Message was read successfully.")},
{ MQMSG_CLASS_NACK_ACCESS_DENIED, TEXT("The SENDER HAVE NO SEND ACCESS RIGHTS ON QUEUE Nack Message was read successfully.")},
{ MQMSG_CLASS_NACK_HOP_COUNT_EXCEEDED, TEXT("The HOP COUNT EXCEEDED Nack Message was read successfully.")},
{ MQMSG_CLASS_NACK_BAD_SIGNATURE, TEXT("The MESSAGE RECEIVED WITH BAD SIGNATURE Nack Message was read successfully.")},
{ MQMSG_CLASS_NACK_BAD_ENCRYPTION, TEXT("The MSG COULD NOT DECRYPTED Nack Message was read successfully.")},
{ MQMSG_CLASS_NACK_COULD_NOT_ENCRYPT, TEXT("The SOURCE QM COULD NOT ENCRYPT MSG FOR DEST QM Nack Message was read successfully.")},
{ 0, NULL}
};
void CMainFrame::ClassToString(unsigned short MsgClass,LPTSTR pszStatus, size_t sizeinChars)
{
//
// Loop through the StringClass array to find MsgClass.
//
ASSERT(pszStatus != NULL);
DWORD dwIndex = 0;
while (StringClass[dwIndex].pszDescription != NULL)
{
if (StringClass[dwIndex].mclass == MsgClass)
{
_tcsncpy_s(pszStatus, sizeinChars, StringClass[dwIndex].pszDescription, sizeinChars -1);
return;
}
dwIndex++;
}
//
// MsgClass was not found, so print the default error.
//
_stprintf_s(pszStatus, sizeinChars, TEXT("The NACK (0x%X) message was read successfully."), MsgClass);
}
/* ************************************************************************ */
/* OnApiCreateQueue */
/* ************************************************************************ */
/* This function opens a dialog box and asks the user for the queue's */
/* path name and label. Then it creates the specified queue. */
/* */
/* Uses: MQCreateQueue. */
/* ************************************************************************ */
void CMainFrame::OnApiCreateQueue()
{
// TODO: Add your command handler code here.
TCHAR szMsgBuffer[BUFFERSIZE];
MQQUEUEPROPS QueueProps;
MQPROPVARIANT aVariant[MAXINDEX];
QUEUEPROPID aPropId[MAXINDEX];
DWORD PropIdCount = 0;
HRESULT hr;
PSECURITY_DESCRIPTOR pSecurityDescriptor;
TCHAR szPathNameBuffer[MAX_Q_PATHNAME_LEN+1];
TCHAR szFormatNameBuffer[MAX_Q_FORMATNAME_LEN+1];
TCHAR szLabelBuffer[MAX_Q_PATHNAME_LEN+1];
DWORD dwFormatNameBufferLength = sizeof(szFormatNameBuffer)/sizeof(szFormatNameBuffer[0]);
//
// Display the Create Queue dialog box.
//
CCreateQueueDialog CreateQueueDialog;
if(CreateQueueDialog.DoModal() == IDCANCEL)
{
return;
}
CreateQueueDialog.GetPathName(szPathNameBuffer);
CreateQueueDialog.GetLabel(szLabelBuffer);
//
// Get the input fields from the dialog box
// and prepare the property array PROPVARIANT.
//
//
// Set the PROPID_Q_PATHNAME property.
//
aPropId[PropIdCount] = PROPID_Q_PATHNAME; // PropId
aVariant[PropIdCount].vt = VT_LPWSTR; // Type
aVariant[PropIdCount].pwszVal = new WCHAR[MAX_Q_PATHNAME_LEN+1];
_mqscpy(aVariant[PropIdCount].pwszVal, szPathNameBuffer); // Value
PropIdCount++;
//
// Set the PROPID_Q_LABEL property.
//
aPropId[PropIdCount] = PROPID_Q_LABEL; // PropId
aVariant[PropIdCount].vt = VT_LPWSTR; // Type
aVariant[PropIdCount].pwszVal = new WCHAR[MAX_Q_PATHNAME_LEN+1];
_mqscpy(aVariant[PropIdCount].pwszVal, szLabelBuffer); // Value
PropIdCount++;
//
// Initialize the MQEUEUPROPS structure.
//
QueueProps.cProp = PropIdCount; //Number of properties
QueueProps.aPropID = aPropId; //Identifiers of properties
QueueProps.aPropVar = aVariant; // Value of properties
QueueProps.aStatus = NULL; //No error reports
//
// No security is defined (default).
//
pSecurityDescriptor = NULL;
//
// Create the queue.
//
#ifdef UNICODE
hr = MQCreateQueue(
pSecurityDescriptor, //Security
&QueueProps, //Queue properties
szFormatNameBuffer, //Output: Format name
&dwFormatNameBufferLength //Output: Format name length
);
#else
WCHAR szwFormatNameBuffer[MAX_Q_FORMATNAME_LEN+1];
dwFormatNameBufferLength = sizeof(szwFormatNameBuffer)/sizeof(szwFormatNameBuffer[0]);
hr = MQCreateQueue(
pSecurityDescriptor, //Security
&QueueProps, //Queue properties
szwFormatNameBuffer, //Output: Format name
&dwFormatNameBufferLength //Output: Format name length
);
if (SUCCEEDED(hr))
{
size_t nResultedStringSize=0;
size_t rc =wcstombs_s(
&nResultedStringSize,
szFormatNameBuffer,
sizeof(szFormatNameBuffer)/sizeof(szFormatNameBuffer[0]),
szwFormatNameBuffer,
dwFormatNameBufferLength
);
if (rc != (size_t)(0))
{
AfxMessageBox("An unsupported wide character was encountered. Exiting...");
exit(1);
}
}
#endif
if (FAILED(hr))
{
//
// An error occurred, so display a message.
//
_stprintf_s(szMsgBuffer, sizeof(szMsgBuffer)/sizeof(szMsgBuffer[0]), TEXT("MQCreateQueue failed. Error code: 0x%x."),hr);
MessageBox(szMsgBuffer, TEXT("ERROR"), MB_OK);
}
else
{
//
// Success was achieved, so write to the edit control.
//
_stprintf_s(szMsgBuffer, sizeof(szMsgBuffer)/sizeof(szMsgBuffer[0]), TEXT("The queue %s was created successfully. ( FormatName: %s )"),
szPathNameBuffer, szFormatNameBuffer);
PrintToScreen(szMsgBuffer);
//
// Add the new queue to the path name array.
//
ARRAYQ* pNewQueue = new ARRAYQ;
if (pNewQueue == NULL)
return;
//
// Save the path name and the format name in the ARRAYQ structure.
//
_tcsncpy_s (
pNewQueue->szPathName,
sizeof(pNewQueue->szPathName)/sizeof(pNewQueue->szPathName[0]),
szPathNameBuffer,
sizeof(pNewQueue->szPathName)/sizeof(pNewQueue->szPathName[0])-1
);
_tcsncpy_s (
pNewQueue->szFormatName,
sizeof(pNewQueue->szFormatName)/sizeof(pNewQueue->szFormatName[0]),
szFormatNameBuffer,
sizeof(pNewQueue->szFormatName)/sizeof(pNewQueue->szFormatName[0])-1
);
Add2PathNameArray(pNewQueue);
}
//
// Free the allocated memory.
//
delete aVariant[0].pwszVal;
delete aVariant[1].pwszVal;
}
/* ************************************************************************ */
/* OnApiDeleteQueue */
/* ************************************************************************ */
/* This function opens a dialog box and asks the user for the queue's */
/* path name. Then it deletes the specified queue. */
/* */
/* Uses: MQDeleteQueue. */
/* ************************************************************************ */
void CMainFrame::OnApiDeleteQueue()
{
// TODO: Add your command handler code here.
TCHAR szPathNameBuffer[MAX_Q_PATHNAME_LEN+1];
TCHAR szFormatNameBuffer[MAX_Q_PATHNAME_LEN+1];
TCHAR szMsgBuffer[BUFFERSIZE];
HRESULT hr;
DWORD dwFormatNameBufferLength = sizeof(szFormatNameBuffer)/sizeof(szFormatNameBuffer[0]);
CDeleteQueueDialog DeleteQueueDialog(&m_PathNameArray);
//
// Display the Delete Queue dialog box.
//
if (DeleteQueueDialog.DoModal() == IDCANCEL)
{
return;
}
DeleteQueueDialog.GetPathName(szPathNameBuffer);
//
// Translate the path name to a format name using the ARRAYQ array.
//
if (TranslatePathNameToFormatName(szPathNameBuffer, _tcslen(szPathNameBuffer), szFormatNameBuffer, sizeof(szFormatNameBuffer)/sizeof(szFormatNameBuffer[0]) ) == FALSE)
{
//
// An error occurred, so display a message.
//
_stprintf_s(szMsgBuffer, sizeof(szMsgBuffer)/sizeof(szMsgBuffer[0]), TEXT("The queue was not found."));
MessageBox(szMsgBuffer, TEXT("ERROR"), MB_OK);
return;
}
//
// Delete the queue.
//
#ifdef UNICODE
hr = MQDeleteQueue(szFormatNameBuffer); // Format name of the queue to be deleted
#else
WCHAR szwFormatNameBuffer[MAX_Q_FORMATNAME_LEN+1];
size_t nResultedStringSize=0;
size_t rc = mbstowcs_s(
&nResultedStringSize,
szwFormatNameBuffer,
sizeof(szwFormatNameBuffer)/sizeof(szwFormatNameBuffer[0]),
szFormatNameBuffer,
_tcslen(szFormatNameBuffer));
if (rc != (size_t)(0))
{
AfxMessageBox("An unsupported wide character was encountered. Exiting...");
exit(1);
}
hr = MQDeleteQueue(szwFormatNameBuffer); // Format name of the queue to be deleted
#endif
if (FAILED(hr))
{
//
// An error occurred, so display a message.
//
_stprintf_s(szMsgBuffer, sizeof(szMsgBuffer)/sizeof(szMsgBuffer[0]), TEXT("MQDeleteQueue failed. Error code: 0x%x."),hr);
MessageBox(szMsgBuffer, TEXT("ERROR"), MB_OK);
}
else
{
//
// Success was achieved, so write in the edit control.
//
_stprintf_s(szMsgBuffer, sizeof(szMsgBuffer)/sizeof(szMsgBuffer[0]), TEXT("The queue %s was deleted successfully."), szPathNameBuffer);
PrintToScreen(szMsgBuffer);
//
// Delete the name from the path name array.
//
ARRAYQ* DeletedQueue = RemoveFromPathNameArray(szPathNameBuffer);
if (DeletedQueue != NULL)
{
delete DeletedQueue;
}
}
}
/* ************************************************************************ */
/* OnApiOpenQueue */
/* ************************************************************************ */
/* This function opens a dialog box and asks the user for the queue's */
/* path name. Then it opens the specified queue. */
/* */
/* Uses: MQOpenQueue. */
/* ************************************************************************ */
void CMainFrame::OnApiOpenQueue()
{
// TODO: Add your command handler code here.
TCHAR szPathNameBuffer[MAX_Q_PATHNAME_LEN+1];
TCHAR szFormatNameBuffer[MAX_Q_PATHNAME_LEN+1];
TCHAR szAccessBuffer[ACCESSBUFFERSIZE];
TCHAR szMsgBuffer[BUFFERSIZE];
WCHAR szwFormatNameBuffer[MAX_Q_FORMATNAME_LEN+1]={0};
DWORD dwFormatNameSize=sizeof(szwFormatNameBuffer)/sizeof(szwFormatNameBuffer[0]);
HRESULT hrFormatName;
HRESULT hrPathName;
DWORD dwFormatNameBufferLength = sizeof(szFormatNameBuffer)/sizeof(szFormatNameBuffer[0]);
DWORD dwAccess;
QUEUEHANDLE hQueue;
COpenQueueDialog OpenQueueDialog(&m_PathNameArray);
//
// Display the Open Queue dialog box.
//
if (OpenQueueDialog.DoModal() == IDCANCEL)
{
return;
}
OpenQueueDialog.GetPathName(szPathNameBuffer);
OpenQueueDialog.GetFormatName( szFormatNameBuffer, sizeof(szFormatNameBuffer)/sizeof(szFormatNameBuffer[0]) );
dwAccess = OpenQueueDialog.GetAccess();
//
// Set the access buffer string.
//
switch (dwAccess)
{
case (MQ_RECEIVE_ACCESS | MQ_SEND_ACCESS):
_tcsncpy_s(szAccessBuffer, sizeof(szAccessBuffer)/sizeof(szAccessBuffer[0]), TEXT("MQ_RECEIVE_ACCESS, MQ_SEND_ACCESS."), 34);
break;
case MQ_RECEIVE_ACCESS:
_tcsncpy_s(szAccessBuffer, sizeof(szAccessBuffer)/sizeof(szAccessBuffer[0]), TEXT("MQ_RECEIVE_ACCESS."), 18);
break;
case MQ_SEND_ACCESS:
_tcsncpy_s(szAccessBuffer, sizeof(szAccessBuffer)/sizeof(szAccessBuffer[0]), TEXT("MQ_SEND_ACCESS."), 15);
break;
default:
_tcsncpy_s(szAccessBuffer, sizeof(szAccessBuffer)/sizeof(szAccessBuffer[0]), TEXT("NONE."), 5);
break;
}
//Try Open The Q. using format name given.
#ifdef UNICODE
hrFormatName = MQOpenQueue(szFormatNameBuffer,dwAccess,0,&hQueue);
#else
size_t nResultedStringSize=0;
size_t rc = mbstowcs_s(
&nResultedStringSize,
szwFormatNameBuffer,
sizeof(szwFormatNameBuffer)/sizeof(szwFormatNameBuffer[0]),
szFormatNameBuffer,
_tcslen(szFormatNameBuffer));
if (rc != (size_t)(0))
{
AfxMessageBox("An unsupported wide character was encountered. Exiting...");
exit(1);
}
hrFormatName = MQOpenQueue(
szwFormatNameBuffer, // Format name of the queue to be opened.
dwAccess, // Access rights to the queue.
0, // No exclusive receive.
&hQueue // OUT: handle to the opened queue.
);
#endif
//
//If failed to open Q. using format name,open The Q. using path name given.
//
if (FAILED(hrFormatName))
{
#ifdef UNICODE
//Traslate PathName to FormatName
dwFormatNameSize = sizeof(szwFormatNameBuffer)/sizeof(szwFormatNameBuffer[0]);
MQPathNameToFormatName(szPathNameBuffer,szwFormatNameBuffer,&dwFormatNameSize);
//Open The Q.
hrPathName = MQOpenQueue(szwFormatNameBuffer,dwAccess,0,&hQueue);
#else
WCHAR szwPathNameBuffer[MAX_Q_FORMATNAME_LEN+1]={0};
size_t nResultedStringSize=0;
size_t rc = mbstowcs_s(
&nResultedStringSize,
szwPathNameBuffer,
sizeof(szwPathNameBuffer)/sizeof(szwPathNameBuffer[0]),
szPathNameBuffer,
_tcslen(szPathNameBuffer));
if (rc != (size_t)(0))
{
AfxMessageBox("An unsupported wide character was encountered. Exiting...");
exit(1);
}
dwFormatNameSize = sizeof(szwFormatNameBuffer)/sizeof(szwFormatNameBuffer[0]);
MQPathNameToFormatName(szwPathNameBuffer,szwFormatNameBuffer,&dwFormatNameSize);
hrPathName = MQOpenQueue(
szwFormatNameBuffer, // Format name of the queue to be opened.
dwAccess, // Access rights to the queue.
0, // No exclusive receive.
&hQueue // OUT: handle to the opened queue.
);
#endif
}
//Results
if (FAILED(hrPathName)&&FAILED(hrFormatName))
{
//
// An error occurred, so display a message.
//
if (szFormatNameBuffer[0]!=0)
{
_stprintf_s(szMsgBuffer, sizeof(szMsgBuffer)/sizeof(szMsgBuffer[0]), TEXT("MQOpenQueue failed. Error code: 0x%x."),hrFormatName);
}
else
{
_stprintf_s(szMsgBuffer, sizeof(szMsgBuffer)/sizeof(szMsgBuffer[0]), TEXT("MQOpenQueue failed. Error code: 0x%x."),hrPathName);
}
MessageBox(szMsgBuffer, TEXT("ERROR"), MB_OK);
}
else
{
//
// Success was achieved, so write in the edit control.
//
_stprintf_s(szMsgBuffer,
sizeof(szMsgBuffer)/sizeof(szMsgBuffer[0]),
TEXT("The queue %s was opened successfully.\r\n\tQueueHandle: 0x%xI\r\n\tQueue Access : %s"),
szPathNameBuffer,
(ptrdiff_t)hQueue,
szAccessBuffer);
PrintToScreen(szMsgBuffer);
//
// Move the queue to the array of opened queue path names.
//
MoveToOpenedQueuePathNameArray(szPathNameBuffer,szFormatNameBuffer,hQueue, dwAccess);
}
}
/* ************************************************************************ */
/* OnApiCloseQueue */
/* ************************************************************************ */
/* This function opens a dialog box and asks the user for the queue's */
/* path name. Then it closes the specified queue. */
/* */
/* Uses: MQCloseQueue. */
/* ************************************************************************ */
void CMainFrame::OnApiCloseQueue()
{
TCHAR szPathNameBuffer[MAX_Q_PATHNAME_LEN+1];
TCHAR szMsgBuffer[BUFFERSIZE];
HRESULT hr;
DWORD dwFormatNameBufferLength = sizeof(szPathNameBuffer)/sizeof(szPathNameBuffer[0]);
QUEUEHANDLE hClosedQueueHandle;
//
// Display the Close Queue dialog box.
//
CCloseQueueDialog CloseQueueDialog(&m_OpenedQueuePathNameArray);
if (CloseQueueDialog.DoModal() == IDCANCEL)
{
return;
}
CloseQueueDialog.GetPathName(szPathNameBuffer);
//
// Get the handle of the queue to be closed.
//
if (GetQueueHandle(szPathNameBuffer, &hClosedQueueHandle) == FALSE)
{
//
// An error occurred, so display a message.
//
_stprintf_s(szMsgBuffer, sizeof(szMsgBuffer)/sizeof(szMsgBuffer[0]), TEXT("The queue could not be closed because it was not opened before."));
MessageBox(szMsgBuffer, TEXT("ERROR"), MB_OK);
return;
}
//
// Close the queue.
//
hr = MQCloseQueue(hClosedQueueHandle); // The handle of the queue to be closed is passed.
if (FAILED(hr))
{
//
// An error occurred, so display a message.
//
_stprintf_s(szMsgBuffer, sizeof(szMsgBuffer)/sizeof(szMsgBuffer[0]), TEXT("MQCloseQueue failed. Error code: 0x%x."),hr);
MessageBox(szMsgBuffer, TEXT("ERROR"), MB_OK);
}
else
{
//
// Success was achieved, so write in the edit control.
//
_stprintf_s(szMsgBuffer, sizeof(szMsgBuffer)/sizeof(szMsgBuffer[0]), TEXT("The queue %s was closed successfully."), szPathNameBuffer);
PrintToScreen(szMsgBuffer);
//
// Move the queue from the open queue path name array to the path name array.
//
MoveToPathNameArray(szPathNameBuffer);
}
}
/* ************************************************************************ */
/* OnApiSendMessage */
/* ************************************************************************ */
/* This function opens a dialog box and asks the user for the queue's path */
/* name and some message properties. Then it sends the message to the */
/* specified queue. */
/* */
/* Uses: MQSendMessage. */
/* ************************************************************************ */
//
// Declare two static buffers to hold the last message body and label for the next time.
//
TCHAR szLastMessageBody[BUFFERSIZE];
TCHAR szLastMessageLabel[BUFFERSIZE];
void CMainFrame::OnApiSendMessage()
{
// TODO: Add your command handler code here.
TCHAR szPathNameBuffer[MAX_Q_PATHNAME_LEN+1]={0};
TCHAR szAdminPathNameBuffer[MAX_Q_PATHNAME_LEN+1]={0};
TCHAR szAdminFormatNameBuffer[MAX_Q_FORMATNAME_LEN+1]={0};
TCHAR szMsgBuffer[BUFFERSIZE]={0};
MQMSGPROPS MsgProps;
MQPROPVARIANT aVariant[MAXINDEX];
MSGPROPID aPropId[MAXINDEX];
DWORD PropIdCount = 0;
HRESULT hr;
unsigned char bPriority;
unsigned char bDelivery;
unsigned char bJournal;
unsigned char bDeadLetter;
unsigned char bAuthenticated;
unsigned char bEncrypted;
unsigned char bAcknowledge;
WCHAR szMessageBodyBuffer [BUFFERSIZE];
WCHAR szMessageLabelBuffer[BUFFERSIZE];
DWORD dwTimeToReachQueue;
DWORD dwTimeToBeReceived;
QUEUEHANDLE hQueue;
CSendMessageDialog SendMessageDialog(&m_OpenedQueuePathNameArray);
//
// Display the Send Message dialog box.
//
if (SendMessageDialog.DoModal() == IDCANCEL)
{
return;
}
//
// Retrieve the properties from the dialog box.
//
SendMessageDialog.GetPathName(szPathNameBuffer);
SendMessageDialog.GetAdminPathName(szAdminPathNameBuffer);
bPriority = SendMessageDialog.GetPriority();
bDelivery = SendMessageDialog.GetDelivery();
bJournal = SendMessageDialog.GetJournal();
bDeadLetter = SendMessageDialog.GetDeadLetter();
bAuthenticated = SendMessageDialog.GetAuthenticated();
bEncrypted = SendMessageDialog.GetEncrypted();
bAcknowledge = SendMessageDialog.GetAcknowledge();
SendMessageDialog.GetMessageBody(szLastMessageBody);
SendMessageDialog.GetMessageLabel(szLastMessageLabel);
dwTimeToReachQueue = SendMessageDialog.GetTimeToReachQueue();
dwTimeToBeReceived = SendMessageDialog.GetTimeToBeReceived();
//
// Update the properties of the last message.
//
_mqscpy(szMessageBodyBuffer, szLastMessageBody);
_mqscpy(szMessageLabelBuffer, szLastMessageLabel);
//
// Get the target queue handle.
//
if (GetQueueHandle(szPathNameBuffer, &hQueue) == FALSE)
{
//
// An error occurred, so display a message.
//
_stprintf_s(szMsgBuffer, sizeof(szMsgBuffer)/sizeof(szMsgBuffer[0]), TEXT("GetQueueHandle failed. Queue not opened yet."));
MessageBox(szMsgBuffer, TEXT("ERROR"), MB_OK);
return;
}
//
// Get the administration queue format name.
//
if (szAdminPathNameBuffer[0] != 0)
{
if (TranslatePathNameToFormatName(szAdminPathNameBuffer, _tcslen(szAdminPathNameBuffer), szAdminFormatNameBuffer, sizeof(szAdminFormatNameBuffer)/sizeof(szAdminFormatNameBuffer[0])) == FALSE)
{
//
// An error occurred, so display a message.
//
_stprintf_s(szMsgBuffer, sizeof(szMsgBuffer)/sizeof(szMsgBuffer[0]), TEXT("TranslatePathNameToFormatName failed, Queue has not been opened yet."));
MessageBox(szMsgBuffer, TEXT("ERROR"), MB_OK);
return;
}
}
//
// Prepare the property array PROPVARIANT.
//
//
// Set the PROPID_M_PRIORITY property.
//
aPropId[PropIdCount] = PROPID_M_PRIORITY; // PropId
aVariant[PropIdCount].vt = VT_UI1; // Type
aVariant[PropIdCount].bVal = bPriority; // Value
PropIdCount++;
//
// Set the PROPID_M_DELIVERY property.
//
aPropId[PropIdCount] = PROPID_M_DELIVERY; // PropId
aVariant[PropIdCount].vt = VT_UI1; // Type
aVariant[PropIdCount].bVal = bDelivery; // Value
PropIdCount++;
//
// Set the PROPID_M_ACKNOWLEDGE property.
//
aPropId[PropIdCount] = PROPID_M_ACKNOWLEDGE; // PropId
aVariant[PropIdCount].vt = VT_UI1; // Type
aVariant[PropIdCount].bVal = bAcknowledge; // Value
PropIdCount++;
//
// Set the PROPID_M_BODY property.
//
aPropId[PropIdCount] = PROPID_M_BODY; // PropId
aVariant[PropIdCount].vt = VT_VECTOR|VT_UI1; // Type
aVariant[PropIdCount].caub.cElems =
(wcslen(szMessageBodyBuffer) + 1) * sizeof(WCHAR); // Value
aVariant[PropIdCount].caub.pElems = (unsigned char *)szMessageBodyBuffer;
PropIdCount++;
//
// Set the PROPID_M_LABEL property.
//
aPropId[PropIdCount] = PROPID_M_LABEL; // PropId
aVariant[PropIdCount].vt = VT_LPWSTR; // Type
aVariant[PropIdCount].pwszVal = szMessageLabelBuffer; // Value
PropIdCount++;
//
// Set the PROPID_M_TIME_TO_REACH_QUEUE property.
//
aPropId[PropIdCount] = PROPID_M_TIME_TO_REACH_QUEUE; // PropId
aVariant[PropIdCount].vt = VT_UI4; // Type
aVariant[PropIdCount].ulVal = dwTimeToReachQueue; // Value
PropIdCount++;
//
// Set the PROPID_M_TIME_TO_BE_RECEIVED property.
//
aPropId[PropIdCount] = PROPID_M_TIME_TO_BE_RECEIVED; // PropId
aVariant[PropIdCount].vt = VT_UI4; // Type
aVariant[PropIdCount].ulVal = dwTimeToBeReceived; // Value
PropIdCount++;
if (bJournal || bDeadLetter)
{
//
// Set the PROPID_M_JOURNAL property.
//
aPropId[PropIdCount] = PROPID_M_JOURNAL; // PropId
aVariant[PropIdCount].vt = VT_UI1; // Type
if (bJournal)
aVariant[PropIdCount].bVal = MQMSG_JOURNAL;
else
aVariant[PropIdCount].bVal = 0;
if (bDeadLetter)
aVariant[PropIdCount].bVal |= MQMSG_DEADLETTER;
PropIdCount++;
}
if (bAuthenticated)
{
//
// Set the PROPID_M_AUTH_LEVEL property.
//
aPropId[PropIdCount] = PROPID_M_AUTH_LEVEL; // PropId
aVariant[PropIdCount].vt = VT_UI4; // Type
aVariant[PropIdCount].ulVal = MQMSG_AUTH_LEVEL_ALWAYS; // Value
PropIdCount++;
}
if (bEncrypted)
{
//
// Set the PROPID_M_ENCRYPTION_ALG property.
//
aPropId[PropIdCount] = PROPID_M_PRIV_LEVEL; // PropId
aVariant[PropIdCount].vt = VT_UI4; // Type
aVariant[PropIdCount].ulVal = MQMSG_PRIV_LEVEL_BODY_BASE; // Value
PropIdCount++;
}
//
// Set the PROPID_M_ADMIN_QUEUE property.
//
if (szAdminFormatNameBuffer[0] != 0)
{
aPropId[PropIdCount] = PROPID_M_ADMIN_QUEUE; // PropId
aVariant[PropIdCount].vt = VT_LPWSTR; // Type
#ifdef UNICODE
aVariant[PropIdCount].pwszVal = szAdminFormatNameBuffer; // Value
#else
WCHAR szwAdminFormatNameBuffer[MAX_Q_FORMATNAME_LEN+1];
size_t nResultedStringSize=0;
size_t rc = mbstowcs_s(
&nResultedStringSize,
szwAdminFormatNameBuffer,
sizeof(szwAdminFormatNameBuffer)/sizeof(szwAdminFormatNameBuffer[0]),
szAdminFormatNameBuffer,
_tcslen(szAdminFormatNameBuffer));
if (rc != (size_t)(0))
{
AfxMessageBox("An unsupported wide character was encountered. Exiting...");
exit(1);
}
aVariant[PropIdCount].pwszVal = szwAdminFormatNameBuffer; // Value
#endif
PropIdCount++;
}
//
// Initialize the MQMSGPROPS structure.
//
MsgProps.cProp = PropIdCount; // Number of properties
MsgProps.aPropID = aPropId; // Identifiers of properties
MsgProps.aPropVar = aVariant; // Value of properties
MsgProps.aStatus = NULL; // No error report
//
// Send the message.
//
hr = MQSendMessage(
hQueue, // Handle to the queue.
&MsgProps, // Message properties to be sent
NULL // No transaction
);
if (FAILED(hr))
{
//
// An error occurred, so display a message.
//
_stprintf_s(szMsgBuffer, sizeof(szMsgBuffer)/sizeof(szMsgBuffer[0]), TEXT("MQSendMessage failed. Error code: 0x%x."),hr);
MessageBox(szMsgBuffer, TEXT("ERROR"), MB_OK);
}
else
{
//
// Success was achieved, so write in the edit control.
//
_stprintf_s(szMsgBuffer, sizeof(szMsgBuffer)/sizeof(szMsgBuffer[0]), TEXT("The Message \"%s\" was sent successfully."), szLastMessageLabel);
PrintToScreen(szMsgBuffer);
}
}
/* ************************************************************************ */
/* OnApiReceiveMessage */
/* ************************************************************************ */
/* This function opens a dialog box and asks the user for the queue's */
/* path name and the time to wait for the message. Then it tries to get a */
/* message from the specified queue within the given time. */
/* */
/* Uses: MQReceiveMessage, MQFreeMemory. */
/* ************************************************************************ */
void CMainFrame::OnApiReceiveMessage()
{
TCHAR szPathNameBuffer[MAX_Q_PATHNAME_LEN+1];
TCHAR szMsgBuffer[2*BUFFERSIZE];
TCHAR szDomainName[BUFFERSIZE];
TCHAR szAccountName[BUFFERSIZE];
DWORD dwActNameSize = sizeof(szAccountName);
DWORD dwDomNameSize = sizeof(szDomainName);
TCHAR szTextSid[BUFFERSIZE];
DWORD dwTextSidSize = sizeof(szTextSid);
BYTE blobBuffer[BUFFERSIZE];
MQMSGPROPS MsgProps;
MQPROPVARIANT aVariant[MAXINDEX];
MSGPROPID aPropId[MAXINDEX];
DWORD PropIdCount = 0;
HRESULT hr;
WCHAR szMessageLabelBuffer[BUFFERSIZE];
DWORD dwTimeout;
QUEUEHANDLE hQueue;
CReceiveWaitDialog WaitDialog;
CReceiveMessageDialog ReceiveMessageDialog(&m_OpenedQueuePathNameArray);
//
// Display the Receive Message dialog box.
//
if (ReceiveMessageDialog.DoModal() == IDCANCEL)
{
return;
}
ReceiveMessageDialog.DestroyWindow();
ReceiveMessageDialog.GetPathName(szPathNameBuffer);
//
// Get the queue handle.
//
if (GetQueueHandle(szPathNameBuffer, &hQueue) == FALSE)
{
//
// An error occurred, so display a message.
//
_stprintf_s(szMsgBuffer, sizeof(szMsgBuffer)/sizeof(szMsgBuffer[0]), TEXT("GetQueueHandle failed. The queue was not found in array of opened queues."));
MessageBox(szMsgBuffer, TEXT("ERROR"), MB_OK);
return;
}
//
// Retrieve the properties form the dialog box.
//
dwTimeout = ReceiveMessageDialog.GetTimeout();
//
// Prepare the property array PROPVARIANT of
// message properties that we want to receive.
//
//
// Set the PROPID_M_BODY property.
//
aPropId[PropIdCount] = PROPID_M_BODY; // PropId
aVariant[PropIdCount].vt = VT_VECTOR|VT_UI1; // Type
aVariant[PropIdCount].caub.cElems = ReceiveMessageDialog.GetBodySize();
aVariant[PropIdCount].caub.pElems = (unsigned char *) new
char [ aVariant[PropIdCount].caub.cElems ];
int iBodyIndex = PropIdCount;
PropIdCount++;
//
// Set the PROPID_M_LABEL property.
//
aPropId[PropIdCount] = PROPID_M_LABEL; // PropId
aVariant[PropIdCount].vt = VT_LPWSTR; // Type
aVariant[PropIdCount].pwszVal = szMessageLabelBuffer;
PropIdCount++;
//
// Set the PROPID_M_PRIORITY property.
//
aPropId[PropIdCount] = PROPID_M_PRIORITY; // PropId
aVariant[PropIdCount].vt = VT_UI1; // Type
PropIdCount++;
//
// Set the PROPID_M_CLASS property.
//
aPropId[PropIdCount] = PROPID_M_CLASS; // PropId
aVariant[PropIdCount].vt = VT_UI2; // Type
PropIdCount++;
//
// Set the PROPID_M_AUTHENTICATED property.
//
aPropId[PropIdCount] = PROPID_M_AUTHENTICATED; // PropId
aVariant[PropIdCount].vt = VT_UI1; // Type
PropIdCount++;
//
// Set the PROPID_M_SENDERID property.
//
aPropId[PropIdCount] = PROPID_M_SENDERID; // PropId
aVariant[PropIdCount].vt = VT_UI1|VT_VECTOR; // Type
aVariant[PropIdCount].blob.pBlobData = blobBuffer;
aVariant[PropIdCount].blob.cbSize = sizeof(blobBuffer);
PropIdCount++;
//
// Set the PROPID_M_PRIV_LEVEL property.
//
aPropId[PropIdCount] = PROPID_M_PRIV_LEVEL; // PropId
aVariant[PropIdCount].vt = VT_UI4; // Type
PropIdCount++;
//
// Set the PROPID_M_LABEL_LEN property.
//
aPropId[PropIdCount] = PROPID_M_LABEL_LEN; // PropId
aVariant[PropIdCount].vt = VT_UI4; // Type
aVariant[PropIdCount].ulVal = BUFFERSIZE; // Value
PropIdCount++;
//
// Initialize the MQMSGPROPS structure.
//
MsgProps.cProp = PropIdCount; // Number of properties
MsgProps.aPropID = aPropId; // Identifiers of properties
MsgProps.aPropVar = aVariant; // Value of properties
MsgProps.aStatus = NULL; // No error report
//
// Display a message window until the message is received from the queue.
//
WaitDialog.Create(IDD_WAIT_DIALOG,pMainView);
WaitDialog.ShowWindow(SW_SHOWNORMAL);
WaitDialog.UpdateWindow();
WaitDialog.CenterWindow();
pMainView->RedrawWindow();
//
// Receive the message.
//
hr = MQReceiveMessage(
hQueue, // Handle to the queue
dwTimeout, // Max time (msec) to wait for the message
MQ_ACTION_RECEIVE, // Action
&MsgProps, // Properties to retrieve
NULL, // No OVERLAPPED structure
NULL, // No callback function
NULL, // No cursor
NULL // No transaction
);
WaitDialog.ShowWindow(SW_HIDE);
if(hr == MQ_ERROR_IO_TIMEOUT)
{
_stprintf_s(szMsgBuffer, sizeof(szMsgBuffer)/sizeof(szMsgBuffer[0]), TEXT("MQReceiveMessage failed, The time-out period expired."));
MessageBox(szMsgBuffer, TEXT("ERROR"), MB_OK);
}
else if(hr != MQ_OK)
{
//
// An error occurred, so display a message.
//
_stprintf_s(szMsgBuffer, sizeof(szMsgBuffer)/sizeof(szMsgBuffer[0]), TEXT("MQReceiveMessage failed. Error code: 0x%x."),hr);
MessageBox(szMsgBuffer, TEXT("ERROR"), MB_OK);
}
else
{
//
// Success was achieved, so write in the edit control.
//
ClassToString(aVariant[3].uiVal, szMsgBuffer, sizeof(szMsgBuffer)/sizeof(szMsgBuffer[0]));
PrintToScreen(szMsgBuffer);
//
// Print some of the message properties.
//
#ifdef UNICODE
_stprintf_s(szMsgBuffer, sizeof(szMsgBuffer)/sizeof(szMsgBuffer[0]), TEXT("\tLabel: %s"), (WCHAR *)(aVariant[1].pwszVal));
#else
{
PCHAR lpLable = UnicodeStringToAnsiString((WCHAR *)(aVariant[1].pwszVal));
_stprintf_s(szMsgBuffer, sizeof(szMsgBuffer)/sizeof(szMsgBuffer[0]), TEXT("\tLabel: %s"), lpLable);
delete [] lpLable;
}
#endif
PrintToScreen(szMsgBuffer);
//
// Print the body only if the message is not an acknowledgment or report message.
// (This is done because there is no message body in acknowledgment messages.)
//
if (aVariant[3].bVal == MQMSG_CLASS_NORMAL)
{
#ifdef UNICODE
_stprintf_s(szMsgBuffer, sizeof(szMsgBuffer)/sizeof(szMsgBuffer[0]), TEXT("\tBody : %s"), (WCHAR *)(aVariant[0].caub.pElems));
#else
{
PCHAR pBody = UnicodeStringToAnsiString((WCHAR *)(aVariant[0].caub.pElems));
_stprintf_s(szMsgBuffer, sizeof(szMsgBuffer)/sizeof(szMsgBuffer[0]), TEXT("\tBody : %s"), pBody);
delete [] pBody;
}
#endif
PrintToScreen(szMsgBuffer);
}
_stprintf_s(szMsgBuffer, sizeof(szMsgBuffer)/sizeof(szMsgBuffer[0]), TEXT("\tPriority : %d"), aVariant[2].bVal);
PrintToScreen(szMsgBuffer);
//
// Print Sender ID
//
//
// See if we're running on NT or Win95.
//
OSVERSIONINFO OsVerInfo;
OsVerInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
GetVersionEx(&OsVerInfo);
if (OsVerInfo.dwPlatformId == VER_PLATFORM_WIN32_NT)
{
//
// On NT
//
SID_NAME_USE peUse;
if (LookupAccountSid(NULL,
blobBuffer,
szAccountName,
&dwActNameSize,
szDomainName,
&dwDomNameSize,
&peUse) )
{
_stprintf_s(szMsgBuffer, sizeof(szMsgBuffer)/sizeof(szMsgBuffer[0]), TEXT("\tUser: %s\\%s"), szDomainName, szAccountName);
PrintToScreen(szMsgBuffer);
}
}
else
{
//
// LookupAccountSid is not implemented on Win95,
// Instead print the textual SID.
//
if ( GetTextualSid((PSID)blobBuffer, szTextSid, &dwTextSidSize))
{
_stprintf_s(szMsgBuffer, sizeof(szMsgBuffer)/sizeof(szMsgBuffer[0]), TEXT("\tUser SID : %s"), szTextSid);
PrintToScreen(szMsgBuffer);
}
}
//
// Print "authenticated" or "not authenticated."
//
if (aVariant[4].bVal)
PrintToScreen(TEXT("\tMessage is authenticated."));
else
PrintToScreen(TEXT("\tMessage is not authenticated."));
//
// Print "encrypted" or "not encrypted."
//
if (aVariant[6].ulVal)
PrintToScreen(TEXT("\tMessage is encrypted."));
else
PrintToScreen(TEXT("\tMessage is not Encrypted."));
}
delete aVariant[ iBodyIndex ].caub.pElems;
}
/* ************************************************************************ */
/* OnApiLocate */
/* ************************************************************************ */
/* This function opens a dialog box and asks the user to give a label. Then */
/* it locates all the queues in the DS with a matching label. */
/* The function updates the path name array with those queues. */
/* */
/* Uses: MQLocateBegin, MQLocateNext, MQLocateEnd, */
/* MQInstanceToFormatName, MQFreeMemory. */
/* ************************************************************************ */
void CMainFrame::OnApiLocate()
{
// TODO: Add your command handler code here.
TCHAR szMsgBuffer[BUFFERSIZE];
TCHAR szLabelBuffer[BUFFERSIZE];
HRESULT hr;
MQPROPERTYRESTRICTION PropertyRestriction;
MQRESTRICTION Restriction;
MQCOLUMNSET Column;
QUEUEPROPID aPropId[2]; // only two properties to retrieve
HANDLE hEnum;
DWORD cQueue;
MQPROPVARIANT aPropVar[MAX_VAR] = {0};
ARRAYQ* pArrayQ;
DWORD i;
DWORD dwColumnCount = 0;
DWORD dwFormatNameLength = MAX_Q_FORMATNAME_LEN;
CLocateDialog LocateDialog;
//
// Display the Receive Message dialog box.
//
if (LocateDialog.DoModal() == IDCANCEL)
{
return;
}
//
// Retrieve the label from the dialog box.
//
LocateDialog.GetLabel(szLabelBuffer);
//
// Clean the path name array before locating queues.
//
CleanPathNameArray();
//
// Prepare parameters for locating queues.
//
//
// Prepare a property restriction.
// Restriction: All queues with PROPID_Q_LABEL equal to "MQ API test."
//
PropertyRestriction.rel = PREQ;
PropertyRestriction.prop = PROPID_Q_LABEL;
PropertyRestriction.prval.vt = VT_LPWSTR;
#ifdef UNICODE
PropertyRestriction.prval.pwszVal = szLabelBuffer;
#else
DWORD size = _tcslen(szLabelBuffer) +1;
PropertyRestriction.prval.pwszVal = new WCHAR[size];
AnsiStringToUnicode(PropertyRestriction.prval.pwszVal, szLabelBuffer,size);
#endif
//
// Prepare a restriction with one property restriction.
//
Restriction.cRes = 1;
Restriction.paPropRes = &PropertyRestriction;
//
// Specify the properties that should be returned by the query.
// Only the path name is important.
//
aPropId[dwColumnCount] = PROPID_Q_PATHNAME;
dwColumnCount++;
aPropId[dwColumnCount] = PROPID_Q_INSTANCE;
dwColumnCount++;
Column.cCol = dwColumnCount;
Column.aCol = aPropId;
//
// Run the query to locate the queues.
//
hr = MQLocateBegin(
NULL, // Start search at the top.
&Restriction, // Restriction
&Column, // Properties to be retrieved
NULL, // No sort order
&hEnum // Enumeration handle
);
if(FAILED(hr))
{
//
// An error occurred, so display a message.
//
_stprintf_s(szMsgBuffer, sizeof(szMsgBuffer)/sizeof(szMsgBuffer[0]),
TEXT("MQLocateBegin failed. Error code: 0x%x."),hr);
MessageBox(szMsgBuffer, TEXT("ERROR"), MB_OK);
return;
}
//
// Get the results.
//
cQueue = MAX_VAR;
//
// If cQueue == 0, no Variants were retrieved in the last call to MQLocateNext.
//
while (cQueue != 0)
{
hr = MQLocateNext(
hEnum, // Handle returned by MQLocateBegin
&cQueue, // Size of aPropVar
aPropVar // OUT: an array of MQPROPVARIANT for receiving the results
);
if(FAILED(hr))
{
//
// An error occurred, so display a message.
//
_stprintf_s(szMsgBuffer, sizeof(szMsgBuffer)/sizeof(szMsgBuffer[0]),
TEXT("MQLocateNext failed. Error code: 0x%x."),hr);
MessageBox(szMsgBuffer, TEXT("ERROR"), MB_OK);
return;
}
for (i=0; i<cQueue; i++)
{
//
// Add the new path names to the path name array.
//
pArrayQ = new ARRAYQ;
if (!pArrayQ)
return;
#ifdef UNICODE
wcsncpy_s (
pArrayQ->szPathName,
sizeof(pArrayQ->szPathName)/sizeof(pArrayQ->szPathName[0]),
aPropVar[i].pwszVal,
sizeof(pArrayQ->szPathName)/sizeof(pArrayQ->szPathName[0])-1
);
#else
size_t nResultedStringSize=0;
size_t rc = wcstombs_s(
&nResultedStringSize,
pArrayQ->szPathName,
sizeof(pArrayQ->szPathName)/sizeof(pArrayQ->szPathName[0]),
aPropVar[i].pwszVal,
sizeof(pArrayQ->szPathName)/sizeof(pArrayQ->szPathName[0])-1
);
if (rc != (size_t)(0))
{
AfxMessageBox("An unsupported wide character was encountered. Ignoring queue.");
MQFreeMemory(aPropVar[i].pwszVal);
i = i + 1;
delete pArrayQ;
continue;
}
#endif
//
// Free the memory allocated by MSMQ.
//
MQFreeMemory(aPropVar[i].pwszVal);
//
// Move to the next property.
//
i = i + 1;
//
// Get the format name of the queue and add the queue to the path name array.
//
#ifdef UNICODE
dwFormatNameLength = sizeof(pArrayQ->szFormatName)/sizeof(pArrayQ->szFormatName[0]);
hr = MQInstanceToFormatName(aPropVar[i].puuid, pArrayQ->szFormatName, &dwFormatNameLength);
#else
WCHAR szwFormatNameBuffer[MAX_Q_FORMATNAME_LEN+1];
dwFormatNameLength = sizeof(szwFormatNameBuffer)/sizeof(szwFormatNameBuffer[0]);
hr = MQInstanceToFormatName(aPropVar[i].puuid, szwFormatNameBuffer, &dwFormatNameLength);
if (SUCCEEDED(hr))
{
size_t rwc = wcstombs_s(
&nResultedStringSize,
pArrayQ->szFormatName,
sizeof(pArrayQ->szFormatName)/sizeof(pArrayQ->szFormatName[0]),
szwFormatNameBuffer,
dwFormatNameLength
);
if (rwc != (size_t)(0))
{
AfxMessageBox("An unsupported wide character was encountered. Exiting...");
exit(1);
}
}
#endif
if(FAILED(hr))
{
//
// An error occurred, so display a message.
//
_stprintf_s (szMsgBuffer, sizeof(szMsgBuffer)/sizeof(szMsgBuffer[0]),
TEXT("MQInstanceToFormatName failed. Error code: 0x%x."),hr);
MessageBox(szMsgBuffer, TEXT("ERROR"), MB_OK);
}
//
// Add the new queue to the path name array.
//
Add2PathNameArray(pArrayQ);
}
}
//
// End the locate operation.
//
hr = MQLocateEnd(hEnum); // handle returned by MQLocateBegin
if(FAILED(hr))
{
//
// An error occurred, so display a message.
//
_stprintf_s (szMsgBuffer, sizeof(szMsgBuffer)/sizeof(szMsgBuffer[0]),
TEXT("MQLocateEnd failed. Error code: 0x%x."),hr);
MessageBox(szMsgBuffer, TEXT("ERROR"), MB_OK);
return;
}
//
// Display the queues found during the query.
//
_stprintf_s (szMsgBuffer, sizeof(szMsgBuffer)/sizeof(szMsgBuffer[0]), TEXT("Locate Operation completed successfully"));
PrintToScreen(szMsgBuffer);
UpdatePathNameArrays();
DisplayPathNameArray();
DisplayOpenedQueuePathNameArray();
}
/* ************************************************************************ */
/* OnUpdateFrameTitle */
/* ************************************************************************ */
void CMainFrame::OnUpdateFrameTitle(BOOL bAddToTitle)
{
SetWindowText (TEXT("MQ API test"));
}
BOOL CMainFrame::IsFormatName(TCHAR *pszName)
{
int Index;
int MaxIndex = m_OpenedQueuePathNameArray.GetSize();
for (Index=0; Index<MaxIndex; Index++)
{
if (_tcscmp(pszName, m_OpenedQueuePathNameArray[Index]->szFormatName) == 0)
{
return TRUE;
}
}
MaxIndex=m_PathNameArray.GetSize();
for (Index=0; Index<MaxIndex; Index++)
{
if (_tcscmp(pszName, m_PathNameArray[Index]->szFormatName) == 0)
{
return TRUE;
}
}
return FALSE;
}