MAINFRM.CPP
/* ************************************************************************ */ 
/*                                                                          */ 
/* 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) 
    { 
        DWORD dwSize = wcstombs(NULL, lpcsUnicode, 0); 
        lpAnsiString = new char[dwSize+1]; 
        size_t rc = wcstombs(lpAnsiString, lpcsUnicode, dwSize); 
        ASSERT(rc != (size_t)(-1)); 
        lpAnsiString[dwSize] = '\0'; 
    } 
 
    return lpAnsiString; 
} 
 
void AnsiStringToUnicode(LPWSTR lpsUnicode, LPSTR  lpsAnsi, DWORD  nSize) 
{ 
    if (lpsUnicode == NULL) 
    { 
        return; 
    } 
 
    ASSERT(lpsAnsi != NULL); 
 
    size_t rc = mbstowcs(lpsUnicode, lpsAnsi, nSize); 
    ASSERT(rc != (size_t)(-1)); 
    if (lpsUnicode[nSize-1] != L'\0') 
        lpsUnicode[nSize] = L'\0'; 
} 
 
#ifdef UNICODE 
#define _mqscpy(dest, src)  wcscpy(dest, src) 
#else 
#define _mqscpy(dest, src)  AnsiStringToUnicode(dest, src, _tcslen(src)+1) 
#endif 
 
BOOL GetTextualSid( 
    PSID pSid,          // binary SID 
    LPTSTR TextualSID,   // buffer for textual representation of SID 
    LPDWORD dwBufferLen // required/provided TextualSid buffersize 
    ) 
{ 
    PSID_IDENTIFIER_AUTHORITY psia; 
    DWORD dwSubAuthorities; 
    DWORD dwSidRev=SID_REVISION; 
    DWORD dwCounter; 
    DWORD dwSidSize; 
 
    // obtain SidIdentifierAuthority 
    psia=&((SID *)pSid)->IdentifierAuthority; 
 
    // obtain sidsubauthority count 
    dwSubAuthorities=(DWORD)((SID *)pSid)->SubAuthorityCount; 
 
    // 
    // compute buffer length 
    // S-SID_REVISION- + identifierauthority- + subauthorities- + NULL 
    // 
    dwSidSize = (15 + 12 + (12 * dwSubAuthorities) + 1) * sizeof(TCHAR); 
 
    // 
    // check provided buffer length. 
    // If not large enough, indicate proper size and setlasterror 
    // 
    if (*dwBufferLen < dwSidSize) 
    { 
        *dwBufferLen = dwSidSize; 
        SetLastError(ERROR_INSUFFICIENT_BUFFER); 
        return FALSE; 
    } 
 
    // 
    // prepare S-SID_REVISION- 
    // 
    TextualSID += _stprintf(TextualSID, TEXT("S-%lu-"), dwSidRev ); 
 
    // 
    // prepare SidIdentifierAuthority 
    // 
    if ( (psia->Value[0] != 0) || (psia->Value[1] != 0) ) 
    { 
        TextualSID += _stprintf(TextualSID, 
                    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(TextualSID, TEXT("%lu"), 
                    (ULONG)(psia->Value[5]      )   + 
                    (ULONG)(psia->Value[4] <<  8)   + 
                    (ULONG)(psia->Value[3] << 16)   + 
                    (ULONG)(psia->Value[2] << 24)   ); 
    } 
 
    // 
    // loop through SidSubAuthorities 
    // 
    for (dwCounter=0 ; dwCounter < dwSubAuthorities ; dwCounter++) 
    { 
        TextualSID += _stprintf(TextualSID, 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("Failed to create toolbar\n"); 
        return -1;      // fail to create 
    } 
 
    if (!m_wndStatusBar.Create(this) || 
        !m_wndStatusBar.SetIndicators(indicators, 
        sizeof(indicators)/sizeof(UINT))) 
    { 
        TRACE0("Failed to create status bar\n"); 
        return -1;      // fail to create 
    } 
 
    // 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 PathName Array and compares the given     */ 
/* PathName to the PathName's 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 szPathName[MAX_Q_PATHNAME_LEN]) 
{ 
    int Index; 
    int MaxIndex = m_PathNameArray.GetSize(); 
    ARRAYQ* pQueue; 
 
    // 
    // Loop through the PathName array. 
    // 
    for (Index=0; Index<MaxIndex; Index++) 
    { 
        if (_tcscmp(szPathName, m_PathNameArray[Index]->szPathName) == 0) 
        { 
            // 
            // Found a match. 
            // 
            pQueue = m_PathNameArray[Index]; 
            m_PathNameArray.RemoveAt(Index); 
            return pQueue; 
        } 
    } 
    return NULL; // ERROR - no match was found. 
} 
 
/* ************************************************************************ */ 
/*                             CleanPathNameArray                           */ 
/* ************************************************************************ */ 
/* This function goes through the PathName 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 OpenedPathName Array and compares the     */ 
/* given PathName to the PathName's 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 szPathName[MAX_Q_PATHNAME_LEN]) 
{ 
    int Index; 
    int MaxIndex = m_OpenedQueuePathNameArray.GetSize(); 
    ARRAYQ* pQueue; 
 
    // 
    // Loop through the OpenedPathName array. 
    // 
    for (Index=0; Index<MaxIndex; Index++) 
    { 
        if (_tcscmp(szPathName, m_OpenedQueuePathNameArray[Index]->szPathName) == 0) 
        { 
            // 
            // Found a match. 
            // 
            pQueue = m_OpenedQueuePathNameArray[Index]; 
            m_OpenedQueuePathNameArray.RemoveAt(Index); 
            return pQueue; 
        } 
    } 
    return NULL; // ERROR - no match was found. 
} 
 
/* ************************************************************************ */ 
/*                           IsOpenedQueueArrayEmpty                        */ 
/* ************************************************************************ */ 
/* This function checks if the size of the OpenedPathName array is zero or  */ 
/* less 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 PathName array to the               */ 
/* OpenedPathName array. also it updates the hadle and the access rights    */ 
/* to the moved queue.                                                      */ 
/* ************************************************************************ */ 
void CMainFrame::MoveToOpenedQueuePathNameArray(TCHAR szPathName[MAX_Q_PATHNAME_LEN], 
                                                QUEUEHANDLE hQueue, DWORD dwAccess) 
{ 
    ARRAYQ* pQueue; 
 
    pQueue = RemoveFromPathNameArray(szPathName); 
    pQueue->hHandle = hQueue;                     // add Queue Handle. 
    pQueue->dwAccess = dwAccess;                  // add Queue Access rights. 
    Add2OpenedQueuePathNameArray(pQueue); 
} 
 
/* ************************************************************************ */ 
/*                              MoveToPathNameArray                         */ 
/* ************************************************************************ */ 
/* This function moves an item from the OpenedPathName array to the         */ 
/* PathName array.                                                          */ 
/* ************************************************************************ */ 
void CMainFrame::MoveToPathNameArray(TCHAR szPathName[MAX_Q_PATHNAME_LEN]) 
{ 
    ARRAYQ* pQueue; 
 
    pQueue = RemoveFromOpenedQueuePathNameArray(szPathName); 
    Add2PathNameArray(pQueue); 
} 
 
/* ************************************************************************ */ 
/*                             UpdatePathNameArrays                         */ 
/* ************************************************************************ */ 
/* This function goes through the Opened Queue PathName array and for every */ 
/* item in it, it checkes if the item is found in the PathName array as     */ 
/* well, if so the function removes the item from the PathName array.       */ 
/* ************************************************************************ */ 
void CMainFrame::UpdatePathNameArrays() 
{ 
    int PathNameIndex; 
    int OpenedPathNameIndex; 
    int MaxPathNameIndex = m_PathNameArray.GetSize(); 
    int MaxOpenedPathNameIndex = m_OpenedQueuePathNameArray.GetSize(); 
    ARRAYQ* pQueue; 
 
    // 
    // Loop through the OpenedPathName array. 
    // 
    for (OpenedPathNameIndex=0; OpenedPathNameIndex<MaxOpenedPathNameIndex; OpenedPathNameIndex++) 
    { 
        for (PathNameIndex=0; PathNameIndex<MaxPathNameIndex; PathNameIndex++) 
        { 
            if (_tcscmp(m_OpenedQueuePathNameArray[OpenedPathNameIndex]->szPathName, 
                m_PathNameArray[PathNameIndex]->szPathName) == 0) 
            { 
                // 
                // Found a match, remove it from PathName Array. 
                // 
                pQueue = m_PathNameArray[PathNameIndex]; 
                m_PathNameArray.RemoveAt(PathNameIndex); 
                delete pQueue; 
                // 
                // get out of inner for loop. 
                // 
                break; 
            } 
        } 
    } 
} 
 
 
/* ************************************************************************ */ 
/*                              GetQueueHandle                              */ 
/* ************************************************************************ */ 
/* This function goes through the OpenedPathName array and retrieve the     */ 
/* Handle to the queue which matches the given PathName. If no match was    */ 
/* found the function returns FALSE.                                        */ 
/* ************************************************************************ */ 
BOOL CMainFrame::GetQueueHandle(TCHAR szPathName[MAX_Q_PATHNAME_LEN], 
                                QUEUEHANDLE* phClosedQueueHandle) 
{ 
    int Index; 
    int MaxIndex = m_OpenedQueuePathNameArray.GetSize(); 
    ARRAYQ* pQueue; 
 
    // 
    // Loop through the OpenedPathName array. 
    // 
    for (Index=0; Index<MaxIndex; Index++) 
    { 
        if (_tcscmp(szPathName, m_OpenedQueuePathNameArray[Index]->szPathName) == 0) 
        { 
            // 
            // Found a match. 
            // 
            pQueue = m_OpenedQueuePathNameArray[Index]; 
            *phClosedQueueHandle = pQueue->hHandle; 
            return TRUE; 
        } 
    } 
    return FALSE; // ERROR - no match was found. 
} 
 
/* ************************************************************************ */ 
/*                       TranslatePathNameToFormatName                      */ 
/* ************************************************************************ */ 
/* This function goes through the PathName array and retrieve the           */ 
/* FormatName to the queue which matches the given PathName. If no match    */ 
/* was found the function returns FALSE.                                    */ 
/* ************************************************************************ */ 
BOOL CMainFrame::TranslatePathNameToFormatName(TCHAR szPathName[MAX_Q_PATHNAME_LEN], 
                                               TCHAR szFormatName[MAX_Q_FORMATNAME_LEN]) 
{ 
    int Index; 
    int MaxIndex = m_PathNameArray.GetSize(); 
    ARRAYQ* pQueue; 
 
    // 
    // Loop through the PathName array. 
    // 
    for (Index=0; Index<MaxIndex; Index++) 
    { 
        if (_tcscmp(szPathName, m_PathNameArray[Index]->szPathName) == 0) 
        { 
            // 
            // Found a match. 
            // 
            pQueue = m_PathNameArray[Index]; 
            _tcsncpy (szFormatName, pQueue->szFormatName, MAX_Q_FORMATNAME_LEN); 
            return TRUE; 
        } 
    } 
    return FALSE; // ERROR - no match was found. 
} 
 
/* ************************************************************************ */ 
/*                  TranslateOpenedQueuePathNameToFormatName                */ 
/* ************************************************************************ */ 
/* This function goes through the OpenedPathName array and retrieve the     */ 
/* FormatName to the queue which matches the given PathName. If no match    */ 
/* was found the function returns FALSE.                                    */ 
/* ************************************************************************ */ 
BOOL CMainFrame::TranslateOpenedQueuePathNameToFormatName( 
    TCHAR szPathName[MAX_Q_PATHNAME_LEN], 
    TCHAR szFormatName[MAX_Q_FORMATNAME_LEN] 
    ) 
{ 
    int Index; 
    int MaxIndex = m_OpenedQueuePathNameArray.GetSize(); 
    ARRAYQ* pQueue; 
 
    // 
    // Loop through the OpenedPathName array. 
    // 
    for (Index=0; Index<MaxIndex; Index++) 
    { 
        if (_tcscmp(szPathName, m_OpenedQueuePathNameArray[Index]->szPathName) == 0) 
        { 
            // 
            // Found a match. 
            // 
            pQueue = m_OpenedQueuePathNameArray[Index]; 
            _tcsncpy (szFormatName, pQueue->szFormatName, MAX_Q_FORMATNAME_LEN); 
            return TRUE; 
        } 
    } 
    return FALSE; // ERROR - no match was found. 
} 
 
 
/* ************************************************************************ */ 
/*                         DisplayPathNameArray                             */ 
/* ************************************************************************ */ 
/* This function goes through the PathName Array and prints it to screen.   */ 
/* ************************************************************************ */ 
void CMainFrame::DisplayPathNameArray() 
{ 
    int Index; 
    int MaxIndex = m_PathNameArray.GetSize(); 
    TCHAR szMsgBuffer[BUFFERSIZE]; 
 
    _stprintf(szMsgBuffer, TEXT("   Located Queues Path Name :")); 
    PrintToScreen(szMsgBuffer); 
    // 
    // Loop through the PathName array. 
    // 
    for (Index=0; Index<MaxIndex; Index++) 
    { 
        // 
        // Print the PathNames. 
        // 
        _stprintf(szMsgBuffer, TEXT("\t%d. %s"),Index+1, m_PathNameArray[Index]->szPathName); 
        PrintToScreen(szMsgBuffer); 
    } 
} 
 
/* ************************************************************************ */ 
/*                    DisplayOpenedQueuePathNameArray                       */ 
/* ************************************************************************ */ 
/* This function goes through the Opened Queues PathName Array and          */ 
/* prints it to screen.                                                     */ 
/* ************************************************************************ */ 
void CMainFrame::DisplayOpenedQueuePathNameArray() 
{ 
    int Index; 
    int MaxIndex = m_OpenedQueuePathNameArray.GetSize(); 
    TCHAR szMsgBuffer[BUFFERSIZE]; 
 
    _stprintf(szMsgBuffer, TEXT("   Currently Opened Queues Path Names:")); 
    PrintToScreen(szMsgBuffer); 
    // 
    // Loop through the OpenedQueuePathName array. 
    // 
    for (Index=0; Index<MaxIndex; Index++) 
    { 
        // 
        // Print the PathNames. 
        // 
        _stprintf(szMsgBuffer, TEXT("\t%d. %s"),Index+1, m_OpenedQueuePathNameArray[Index]->szPathName); 
        PrintToScreen(szMsgBuffer); 
    } 
} 
 
/* ************************************************************************ */ 
/*                          GetMsgClassStatus                               */ 
/* ************************************************************************ */ 
/* This function sets proper status string based on a given MQMSG class.    */ 
/* ************************************************************************ */ 
 
struct 
{ 
unsigned shortmclass; 
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) 
{ 
// 
// loop the StringClass array to find MsgClass 
// 
DWORD dwIndex = 0; 
while (StringClass[dwIndex].pszDescription != NULL) 
{ 
if (StringClass[dwIndex].mclass == MsgClass) 
{ 
_stprintf(pszStatus,StringClass[dwIndex].pszDescription); 
return; 
} 
dwIndex++; 
} 
 
// 
// MsgClass not found - print default error 
// 
_stprintf(pszStatus,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       */ 
/* PathName 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]; 
    TCHAR szFormatNameBuffer[MAX_Q_FORMATNAME_LEN]; 
    TCHAR szLabelBuffer[MAX_Q_PATHNAME_LEN]; 
    DWORD dwFormatNameBufferLength = MAX_Q_FORMATNAME_LEN; 
 
 
    // 
    // Display CreateQueue Dialog. 
    // 
    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]; 
    _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]; 
    _mqscpy(aVariant[PropIdCount].pwszVal, szLabelBuffer); //Value 
 
    PropIdCount++; 
 
 
    // 
    // Set the MQEUEUPROPS structure 
    // 
    QueueProps.cProp = PropIdCount;           //No of properties 
    QueueProps.aPropID = aPropId;             //Id of properties 
    QueueProps.aPropVar = aVariant;           //Value of properties 
    QueueProps.aStatus = NULL;                //No error reports 
 
    // 
    // No security (default) 
    // 
    pSecurityDescriptor = NULL; 
 
    // 
    // Create the queue 
    // 
#ifdef UNICODE 
    hr = MQCreateQueue( 
            pSecurityDescriptor,            //Security 
            &QueueProps,                    //Queue properties 
            szFormatNameBuffer,             //Output: Format Name 
            &dwFormatNameBufferLength       //Output: Format Name len 
            ); 
#else 
    WCHAR szwFormatNameBuffer[MAX_Q_FORMATNAME_LEN]; 
    hr = MQCreateQueue( 
            pSecurityDescriptor,            //Security 
            &QueueProps,                    //Queue properties 
            szwFormatNameBuffer,            //Output: Format Name 
            &dwFormatNameBufferLength       //Output: Format Name len 
            ); 
 
    if (SUCCEEDED(hr)) 
    { 
        size_t rc =wcstombs(szFormatNameBuffer, szwFormatNameBuffer, dwFormatNameBufferLength); 
        ASSERT(rc != (size_t)(-1)); 
    } 
#endif 
 
    if (FAILED(hr)) 
    { 
        // 
        // Error - display message 
        // 
        _stprintf(szMsgBuffer, TEXT("MQCreateQueue failed, Error code = 0x%x."),hr); 
        MessageBox(szMsgBuffer, TEXT("ERROR"), MB_OK); 
    } 
    else 
    { 
        // 
        // Success - write in edit control. 
        // 
        _stprintf(szMsgBuffer, TEXT("The queue %s was created successfully. ( FormatName: %s )"), 
            szPathNameBuffer, szFormatNameBuffer); 
        PrintToScreen(szMsgBuffer); 
 
        // 
        // Add the new queue to the PathName Array. 
        // 
        ARRAYQ* pNewQueue = new ARRAYQ; 
        // 
        // Save PathName and FormatName in the ARRAYQ structure. 
        // 
        _tcsncpy (pNewQueue->szPathName, szPathNameBuffer, MAX_Q_PATHNAME_LEN); 
        _tcsncpy (pNewQueue->szFormatName, szFormatNameBuffer, MAX_Q_FORMATNAME_LEN); 
        Add2PathNameArray(pNewQueue); 
    } 
 
    // 
    // Free 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       */ 
/* PathName. then it deletes the specified queue.                           */ 
/*                                                                          */ 
/* Uses: MQDeleteQueue.                                                     */ 
/* ************************************************************************ */ 
void CMainFrame::OnApiDeleteQueue() 
{ 
    // TODO: Add your command handler code here 
    TCHAR szPathNameBuffer[MAX_Q_PATHNAME_LEN]; 
    TCHAR szFormatNameBuffer[MAX_Q_PATHNAME_LEN]; 
    TCHAR szMsgBuffer[BUFFERSIZE]; 
 
    HRESULT hr; 
 
    DWORD dwFormatNameBufferLength = MAX_Q_PATHNAME_LEN; 
 
    CDeleteQueueDialog DeleteQueueDialog(&m_PathNameArray); 
 
    // 
    // Display DeleteQueue Dialog. 
    // 
    if (DeleteQueueDialog.DoModal() == IDCANCEL) 
    { 
        return; 
    } 
 
    DeleteQueueDialog.GetPathName(szPathNameBuffer); 
 
    // 
    // Translate the path name to format name using the ARRAYQ arrays. 
    // 
    if (TranslatePathNameToFormatName(szPathNameBuffer, szFormatNameBuffer) == FALSE) 
    { 
        // 
        // Error - display message 
        // 
        _stprintf(szMsgBuffer, TEXT("Queue wasn't found")); 
        MessageBox(szMsgBuffer, TEXT("ERROR"), MB_OK); 
        return; 
    } 
 
    // 
    // Delete the queue. 
    // 
#ifdef UNICODE 
    hr = MQDeleteQueue(szFormatNameBuffer);  // FormatName of the Queue to be deleted. 
#else 
    WCHAR szwFormatNameBuffer[MAX_Q_FORMATNAME_LEN]; 
    size_t rc = mbstowcs(szwFormatNameBuffer, szFormatNameBuffer, _tcslen(szFormatNameBuffer)+1); 
    ASSERT(rc != (size_t)(-1)); 
    hr = MQDeleteQueue(szwFormatNameBuffer);  // FormatName of the Queue to be deleted. 
#endif 
 
    if (FAILED(hr)) 
    { 
        // 
        // Error - display message 
        // 
        _stprintf(szMsgBuffer, TEXT("MQDeleteQueue failed, Error code = 0x%x."),hr); 
        MessageBox(szMsgBuffer, TEXT("ERROR"), MB_OK); 
    } 
    else 
    { 
        // 
        // Success - write in edit control 
        // 
        _stprintf(szMsgBuffer, TEXT("The queue %s was deleted successfully."), szPathNameBuffer); 
        PrintToScreen(szMsgBuffer); 
// 
        // Delete the name from the Path Names 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       */ 
/* PathName. then it opens the specified queue.                             */ 
/*                                                                          */ 
/* Uses: MQOpenQueue.                                                       */ 
/* ************************************************************************ */ 
void CMainFrame::OnApiOpenQueue() 
{ 
    // TODO: Add your command handler code here 
    TCHAR szPathNameBuffer[MAX_Q_PATHNAME_LEN]; 
    TCHAR szFormatNameBuffer[MAX_Q_PATHNAME_LEN]; 
    TCHAR szAccessBuffer[50]; // BUGBUG - maybe set with a define 
    TCHAR szMsgBuffer[BUFFERSIZE]; 
 
    HRESULT hr; 
 
    DWORD dwFormatNameBufferLength = MAX_Q_PATHNAME_LEN; 
    DWORD dwAccess; 
 
    QUEUEHANDLE hQueue; 
 
    COpenQueueDialog OpenQueueDialog(&m_PathNameArray); 
 
    // 
    // Display the OpenQueue dialog. 
    // 
    if (OpenQueueDialog.DoModal() == IDCANCEL) 
    { 
        return; 
    } 
 
    OpenQueueDialog.GetPathName(szPathNameBuffer); 
    dwAccess = OpenQueueDialog.GetAccess(); 
    // 
    // Set the access buffer string. 
    // 
    switch (dwAccess) 
    { 
    case (MQ_RECEIVE_ACCESS | MQ_SEND_ACCESS): 
 
        _tcscpy(szAccessBuffer, TEXT("MQ_RECEIVE_ACCESS, MQ_SEND_ACCESS.")); 
        break; 
 
    case MQ_RECEIVE_ACCESS: 
 
        _tcscpy(szAccessBuffer, TEXT("MQ_RECEIVE_ACCESS.")); 
        break; 
 
    case MQ_SEND_ACCESS: 
 
        _tcscpy(szAccessBuffer, TEXT("MQ_SEND_ACCESS.")); 
        break; 
 
    default: 
 
        _tcscpy(szAccessBuffer, TEXT("NONE.")); 
        break; 
    } 
 
    // 
    // Translate the path name to format name using the ARRAYQ arrays. 
    // 
    if (TranslatePathNameToFormatName(szPathNameBuffer, szFormatNameBuffer) == FALSE) 
    { 
        // 
        // Error - display message 
        // 
        _stprintf(szMsgBuffer, TEXT("Queue wasn't found")); 
        MessageBox(szMsgBuffer, TEXT("ERROR"), MB_OK); 
        return; 
    } 
 
    // 
    // Open the queue. (no sharing) 
    // 
#ifdef UNICODE 
    hr = MQOpenQueue( 
            szFormatNameBuffer,     // Format Name of the queue to be opened. 
            dwAccess,               // Access rights to the Queue. 
            0,                      // No receive Exclusive. 
            &hQueue                 // OUT: handle to the opened Queue. 
            ); 
#else 
    WCHAR szwFormatNameBuffer[MAX_Q_FORMATNAME_LEN]; 
    size_t rc = mbstowcs(szwFormatNameBuffer, szFormatNameBuffer, _tcslen(szFormatNameBuffer)+1); 
    ASSERT(rc != (size_t)(-1)); 
 
    hr = MQOpenQueue( 
            szwFormatNameBuffer,    // Format Name of the queue to be opened. 
            dwAccess,               // Access rights to the Queue. 
            0,                      // No receive Exclusive. 
            &hQueue                 // OUT: handle to the opened Queue. 
            ); 
#endif 
 
    if (FAILED(hr)) 
    { 
        // 
        // Error - display message 
        // 
        _stprintf(szMsgBuffer, TEXT("MQOpenQueue failed, Error code = 0x%x."),hr); 
        MessageBox(szMsgBuffer, TEXT("ERROR"), MB_OK); 
    } 
    else 
    { 
        // 
        // Success - write in edit control 
        // 
        _stprintf(szMsgBuffer, 
            TEXT("The queue %s was opened successfully.\r\n\tQueueHandle: 0x%x\r\n\tQueue Access : %s"), 
            szPathNameBuffer, 
            hQueue, 
            szAccessBuffer); 
        PrintToScreen(szMsgBuffer); 
 
        // 
        // move the queue to the opened queues array. 
        // 
        MoveToOpenedQueuePathNameArray(szPathNameBuffer, hQueue, dwAccess); 
    } 
} 
 
/* ************************************************************************ */ 
/*                            OnApiCloseQueue                               */ 
/* ************************************************************************ */ 
/* This function opens a dialog box and asks the user for the queue's       */ 
/* PathName. then it closes the specified queue.                            */ 
/*                                                                          */ 
/* Uses: MQCloseQueue.                                                      */ 
/* ************************************************************************ */ 
void CMainFrame::OnApiCloseQueue() 
{ 
    // TODO: Add your command handler code here 
 
    TCHAR szPathNameBuffer[MAX_Q_PATHNAME_LEN]; 
    TCHAR szMsgBuffer[BUFFERSIZE]; 
 
    HRESULT hr; 
 
    DWORD dwFormatNameBufferLength = MAX_Q_PATHNAME_LEN; 
 
    QUEUEHANDLE hClosedQueueHandle; 
 
    // 
    // Display CloseQueue Dialog. 
    // 
    CCloseQueueDialog CloseQueueDialog(&m_OpenedQueuePathNameArray); 
 
    if (CloseQueueDialog.DoModal() == IDCANCEL) 
    { 
        return; 
    } 
 
    CloseQueueDialog.GetPathName(szPathNameBuffer); 
 
    // 
    // Get the closed queue handle. 
    // 
    if (GetQueueHandle(szPathNameBuffer, &hClosedQueueHandle) == FALSE) 
    { 
        // 
        // Error - display message 
        // 
        _stprintf(szMsgBuffer, TEXT("The Queue couldn't be closed since 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. 
    if (FAILED(hr)) 
    { 
        // 
        // Error - display message 
        // 
        _stprintf(szMsgBuffer, TEXT("MQCloseQueue failed, Error code = 0x%x."),hr); 
        MessageBox(szMsgBuffer, TEXT("ERROR"), MB_OK); 
    } 
    else 
    { 
        // 
        // Success - write in edit control 
        // 
        _stprintf(szMsgBuffer, TEXT("The queue %s was closed successfully."), szPathNameBuffer); 
        PrintToScreen(szMsgBuffer); 
        // 
        // Move the queue form the opened queues array to the path name array. 
        // 
        MoveToPathNameArray(szPathNameBuffer); 
    } 
} 
 
/* ************************************************************************ */ 
/*                            OnApiSendMessage                              */ 
/* ************************************************************************ */ 
/* This function opens a dialog box and asks the user for the queue's       */ 
/* PathName and some message properties. Then it sends the message to the   */ 
/* specified queue.                                                         */ 
/*                                                                          */ 
/* Uses: MQSendMessage.                                                     */ 
/* ************************************************************************ */ 
 
// 
// 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]; 
    TCHAR szAdminPathNameBuffer[MAX_Q_PATHNAME_LEN]; 
    TCHAR szAdminFormatNameBuffer[MAX_Q_FORMATNAME_LEN]; 
    TCHAR szMsgBuffer[BUFFERSIZE]; 
 
    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 SendMessage dialog. 
    // 
    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 Last message properties. 
    // 
    _mqscpy(szMessageBodyBuffer, szLastMessageBody); 
    _mqscpy(szMessageLabelBuffer, szLastMessageLabel); 
 
    // 
    // Get the target queue handle. 
    // 
    if (GetQueueHandle(szPathNameBuffer, &hQueue) == FALSE) 
    { 
        // 
        // Error - display message 
        // 
        _stprintf(szMsgBuffer, TEXT("GetQueueHandle failed. Queue not opened yet.")); 
        MessageBox(szMsgBuffer, TEXT("ERROR"), MB_OK); 
        return; 
    } 
 
    // 
    // Get the admin queue FormatName. 
    // 
    if (TranslateOpenedQueuePathNameToFormatName(szAdminPathNameBuffer, szAdminFormatNameBuffer) == FALSE) 
    { 
        // 
        // Error - display message 
        // 
        _stprintf(szMsgBuffer, 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;   //Value 
 
PropIdCount++; 
} 
 
 
    // 
    // Set the PROPID_M_ADMIN_QUEUE property. 
    // 
    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]; 
    size_t rc = mbstowcs(szwAdminFormatNameBuffer, 
                    szAdminFormatNameBuffer, 
                    _tcslen(szAdminFormatNameBuffer)+1); 
    ASSERT(rc != (size_t)(-1)); 
    aVariant[PropIdCount].pwszVal = szwAdminFormatNameBuffer;  //Value 
#endif 
 
    PropIdCount++; 
 
    // 
    // Set the MQMSGPROPS structure 
    // 
    MsgProps.cProp = PropIdCount;       //Number of properties. 
    MsgProps.aPropID = aPropId;         //Id 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)) 
    { 
        // 
        // Error - display message 
        // 
        _stprintf(szMsgBuffer, TEXT("MQSendMessage failed, Error code = 0x%x."),hr); 
        MessageBox(szMsgBuffer, TEXT("ERROR"), MB_OK); 
    } 
    else 
    { 
        // 
        // Success - write in edit control 
        // 
        _stprintf(szMsgBuffer, 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       */ 
/* PathName and the Time to wait for the message. Then it tries to get a    */ 
/* message from the specified queue at the given time.                      */ 
/*                                                                          */ 
/* Uses: MQReceiveMessage, MQFreeMemory.                                    */ 
/* ************************************************************************ */ 
void CMainFrame::OnApiReceiveMessage() 
{ 
    TCHAR szPathNameBuffer[MAX_Q_PATHNAME_LEN]; 
    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 ReceiveMessage dialog. 
    // 
    if (ReceiveMessageDialog.DoModal() == IDCANCEL) 
    { 
        return; 
    } 
 
    ReceiveMessageDialog.DestroyWindow(); 
    ReceiveMessageDialog.GetPathName(szPathNameBuffer); 
 
    // 
    // Get the queue handle. 
    // 
    if (GetQueueHandle(szPathNameBuffer, &hQueue) == FALSE) 
    { 
        // 
        // Error - display message 
        // 
        _stprintf(szMsgBuffer, TEXT("GetQueueHandle failed. Queue was not found in Opened Queue Array")); 
        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++; 
 
 
    // 
    // Set the MQMSGPROPS structure 
    // 
    MsgProps.cProp = PropIdCount;       //Number of properties. 
    MsgProps.aPropID = aPropId;         //Id of properties. 
    MsgProps.aPropVar = aVariant;       //Value of properties. 
    MsgProps.aStatus  = NULL;           //No Error report. 
 
    // 
    // Display a message window until the message from the queue will be received. 
    // 
    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 overlaped structure. 
               NULL,                 // No callback function. 
               NULL,                 // No Cursor. 
               NULL                  // No transaction 
               ); 
 
    WaitDialog.ShowWindow(SW_HIDE); 
 
 
if(hr == MQ_ERROR_IO_TIMEOUT) 
{ 
        _stprintf(szMsgBuffer, TEXT("MQReceiveMessage failed, Timeout expired."),hr); 
        MessageBox(szMsgBuffer, TEXT("ERROR"), MB_OK); 
} 
else if(hr != MQ_OK) 
{ 
        // 
        // Error - display message 
        // 
        _stprintf(szMsgBuffer, TEXT("MQReceiveMessage failed, Error code = 0x%x."),hr); 
        MessageBox(szMsgBuffer, TEXT("ERROR"), MB_OK); 
} 
else 
{ 
        // 
        // Success - write in edit control 
        // 
ClassToString(aVariant[3].uiVal,szMsgBuffer); 
        PrintToScreen(szMsgBuffer); 
 
        // 
        // Print some of the Message properties. 
        // 
#ifdef UNICODE 
        _stprintf(szMsgBuffer, TEXT("\tLabel: %s"), (WCHAR *)(aVariant[1].pwszVal)); 
#else 
        { 
            PCHAR lpLable = UnicodeStringToAnsiString((WCHAR *)(aVariant[1].pwszVal)); 
            _stprintf(szMsgBuffer, TEXT("\tLabel: %s"), lpLable); 
            delete [] lpLable; 
        } 
#endif 
        PrintToScreen(szMsgBuffer); 
 
        // 
        // Only if the message is not a falcon message print the body. 
        // (this is done since in ACK messages there is no message body). 
        // 
        if (aVariant[3].bVal == MQMSG_CLASS_NORMAL) 
        { 
#ifdef UNICODE 
            _stprintf(szMsgBuffer, TEXT("\tBody : %s"), (WCHAR *)(aVariant[0].caub.pElems)); 
#else 
            { 
                PCHAR pBody = UnicodeStringToAnsiString((WCHAR *)(aVariant[0].caub.pElems)); 
                _stprintf(szMsgBuffer, TEXT("\tBody : %s"), pBody); 
                delete [] pBody; 
            } 
#endif 
            PrintToScreen(szMsgBuffer); 
        } 
 
        _stprintf(szMsgBuffer, 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(szMsgBuffer, TEXT("\tUser: %s\\%s"), 
        (WCHAR *)(szDomainName),(WCHAR *)(szAccountName)); 
        PrintToScreen(szMsgBuffer); 
            } 
        } 
        else 
        { 
            // 
            // LookupAccountSid is not implemented on Win95, 
            // instead print textual sid 
            // 
            if ( GetTextualSid((PSID)blobBuffer, szTextSid, &dwTextSidSize)) 
            { 
                _stprintf(szMsgBuffer, TEXT("\tUser SID : %s"), szTextSid); 
        PrintToScreen(szMsgBuffer); 
            } 
        } 
// 
// Print "Authenticated" or "Non Authenticated" 
// 
if (aVariant[4].bVal) 
PrintToScreen(TEXT("\tMessage is Authenticated.")); 
else 
PrintToScreen(TEXT("\tMessage is Not Authenticated.")); 
 
 
// 
// Print "Encrypted" or "Non 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 ask the user to give a Label. Then  */ 
/* it locates all the Queues in the DS with a matching label.               */ 
/* The function updates the PathName 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 ReceiveMessage dialog. 
    // 
    if (LocateDialog.DoModal() == IDCANCEL) 
    { 
        return; 
    } 
 
    // 
    // Retrieve the label from the dialog box. 
    // 
    LocateDialog.GetLabel(szLabelBuffer); 
 
    // 
    // Clean the PathNameArray before locate. 
    // 
    CleanPathNameArray(); 
 
    // 
    // Prepare Parameters to locate a queue. 
    // 
 
    // 
    // Prepare property restriction. 
    // Restriction = All queue 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; 
 
    // 
    // Columset (In other words what property I want to retrieve). 
    // Only the PathName is important. 
    // 
    aPropId[dwColumnCount] = PROPID_Q_PATHNAME; 
    dwColumnCount++; 
 
    aPropId[dwColumnCount] = PROPID_Q_INSTANCE; 
    dwColumnCount++; 
 
    Column.cCol = dwColumnCount; 
    Column.aCol = aPropId; 
 
    // 
    // Locate the queues. Issue the query 
    // 
    hr = MQLocateBegin( 
            NULL,           //start search at the top. 
            &Restriction,   //Restriction 
            &Column,        //ColumnSet 
            NULL,           //No sort order 
            &hEnum          //Enumeration Handle 
            ); 
 
    if(FAILED(hr)) 
    { 
        // 
        // Error - display message 
        // 
        _stprintf(szMsgBuffer, 
            TEXT("MQLocateBegin failed, Error code = 0x%x."),hr); 
        MessageBox(szMsgBuffer, TEXT("ERROR"), MB_OK); 
        return; 
    } 
 
    // 
    // Get the results. 
    // 
    cQueue = MAX_VAR; 
 
    // 
    // If cQueue == 0 it means that no Variants were retrieved in the last MQLocateNext. 
    // 
    while (cQueue != 0) 
    { 
        hr = MQLocateNext( 
                hEnum,      // handle returned by MQLocateBegin. 
                &cQueue,    // size of aPropVar array. 
                aPropVar    // OUT: an array of MQPROPVARIANT to get the results in. 
                ); 
 
        if(FAILED(hr)) 
        { 
            // 
            // Error - display message 
            // 
            _stprintf(szMsgBuffer, 
                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; 
#ifdef UNICODE 
            wcsncpy (pArrayQ->szPathName, aPropVar[i].pwszVal, MAX_Q_PATHNAME_LEN); 
#else 
            size_t rc = wcstombs(pArrayQ->szPathName, aPropVar[i].pwszVal, MAX_Q_PATHNAME_LEN); 
            ASSERT(rc != (size_t)(-1)); 
#endif 
            // 
            // move to the next property. 
            // 
            i = i + 1; 
 
            // 
            // Get the FormatName of the queue and set it in the PathName array. 
            // 
#ifdef UNICODE 
            hr = MQInstanceToFormatName(aPropVar[i].puuid, pArrayQ->szFormatName, &dwFormatNameLength); 
#else 
            WCHAR szwFormatNameBuffer[MAX_Q_FORMATNAME_LEN]; 
            hr = MQInstanceToFormatName(aPropVar[i].puuid, szwFormatNameBuffer, &dwFormatNameLength); 
            if (SUCCEEDED(hr)) 
            { 
                size_t rwc =wcstombs(pArrayQ->szFormatName, szwFormatNameBuffer, dwFormatNameLength); 
                ASSERT(rwc != (size_t)(-1)); 
            } 
#endif 
 
            if(FAILED(hr)) 
            { 
                // 
                // Error - display message 
                // 
                _stprintf (szMsgBuffer, 
                    TEXT("MQGUIDToFormatName failed, Error code = 0x%x."),hr); 
                MessageBox(szMsgBuffer, TEXT("ERROR"), MB_OK); 
            } 
 
            // 
            // Free the memory allocated by MSMQ 
            // 
            MQFreeMemory(aPropVar[i].pwszVal); 
 
            // 
            // Add the new Queue to the PathNameArray. 
            // 
            Add2PathNameArray(pArrayQ); 
        } 
    } 
 
    // 
    // End the locate operation. 
    // 
    hr = MQLocateEnd(hEnum);   // handle returned by MQLocateBegin. 
    if(FAILED(hr)) 
    { 
        // 
        // Error - display message 
        // 
        _stprintf (szMsgBuffer, 
            TEXT("MQLocateEnd failed, Error code = 0x%x."),hr); 
        MessageBox(szMsgBuffer, TEXT("ERROR"), MB_OK); 
        return; 
    } 
 
    // 
    // Display the Queues found on the locate. 
    // 
    _stprintf (szMsgBuffer, TEXT("Locate Operation completed successfully")); 
    PrintToScreen(szMsgBuffer); 
    UpdatePathNameArrays(); 
    DisplayPathNameArray(); 
    DisplayOpenedQueuePathNameArray(); 
} 
 
/* ************************************************************************ */ 
/*                           OnUpdateFrameTitle                             */ 
/* ************************************************************************ */ 
void CMainFrame::OnUpdateFrameTitle(BOOL bAddToTitle) 
{ 
    SetWindowText (TEXT("MQ API test")); 
}