Friday, April 27, 2012

Send Message to MSMQ in C++

Send Message to MSMQ in C++ :


The MQSendMessage function sends a message to the corresponding queue.


HRESULT APIENTRY MQSendMessage(
  QUEUEHANDLE hDestinationQueue, 
  MQMSGPROPS * pMessageProps,     
  ITransaction * pTransaction     
);

Parameters:

hDestinationQueue

[in] Handle to the queue where you want to send the message.

pMessageProps

[in] Pointer to an MQMSGPROPS structure describing the message to send.

pTransaction

[in] Must be a pointer to an ITransaction interface, a constant, or NULL.


Constants include:

MQ_NO_TRANSACTION

Specifies that the call is not part of a transaction. This constant cannot be used to send a message to a transactional queue.

MQ_MTS_TRANSACTION

Instructs Message Queuing to verify that a COM+ object is running and that the current COM+ object is participating in a transaction. If Message Queuing finds that the application is running in the context of a COM+ (Component Services) transaction, the message is sent within the current COM+ transaction. Otherwise, the message is sent outside of a transaction. For more information, see COM+ Transactions.

MQ_SINGLE_MESSAGE

Specifies that the message is sent in a single-message transaction. Messages sent in a single-message transaction must be sent to a transactional queue.

MQ_XA_TRANSACTION

Specifies that the call is part of an externally coordinated, XA-compliant transaction.


To Send a message:

    1.Define the required constants and variables.

    2.Define the MQMSGPROPS structure.

    3.Specify the properties of the message. This example defines the PROPID_M_LABEL property.

    4.Initialize the MQMSGPROPS structure.

    5.Call MQOpenQueue to open the queue with send access.

    6.Call MQSendMessage to send the message.

    7.Call MQCloseQueue to close the opened queue and free resources.





Example Code:

#include "stdafx.h"
#include "windows.h"
#include "mq.h"
#include "tchar.h"
#include




 
HRESULT SendMessage(LPWSTR wszPathName)
{
  QUEUEHANDLE phQueue = new QUEUEHANDLE ;
  HRESULT hr = S_FALSE;
  DWORD dwFormatNameLength = 0;
  WCHAR *wszFormatName = NULL;

  const int NUMBEROFPROPERTIES = 5; 
  DWORD cPropId = 0;
   // Define an MQMSGPROPS structure.
  MQMSGPROPS msgProps;
  MSGPROPID aMsgPropId[NUMBEROFPROPERTIES];
  MQPROPVARIANT aMsgPropVar[NUMBEROFPROPERTIES];
  HRESULT aMsgStatus[NUMBEROFPROPERTIES];
 
 
  // Specify the message properties to be sent.
  aMsgPropId[cPropId] = PROPID_M_BODY;            
  aMsgPropVar[cPropId].vt =VT_VECTOR | VT_UI1;
  aMsgPropVar[cPropId].caub.pElems = (LPBYTE)"Test Message";
  aMsgPropVar[cPropId].caub.cElems = sizeof("Test Message");

 
  cPropId++;
  aMsgPropId[cPropId] = PROPID_M_LABEL;             
  aMsgPropVar[cPropId].vt = VT_LPWSTR;              
  aMsgPropVar[cPropId].pwszVal = L"Test Message";
  cPropId++;
 
  // Initialize the MQMSGPROPS structure.
  msgProps.cProp = cPropId;
  msgProps.aPropID = aMsgPropId;
  msgProps.aPropVar = aMsgPropVar;
  msgProps.aStatus = aMsgStatus;


  // Validate the input parameters.
  if ((wszPathName == NULL) || (phQueue == NULL))
  {
    return MQ_ERROR_INVALID_PARAMETER;
  }


  // Create a buffer for the direct format name.
  dwFormatNameLength = wcslen(wszPathName) + 11;
  wszFormatName = new WCHAR[dwFormatNameLength];
 
  if (wszFormatName)
  {


    // Create the direct format name of the queue.
    memset(wszFormatName, 0, dwFormatNameLength*sizeof(WCHAR));
    if (_snwprintf(
                   wszFormatName,
                   dwFormatNameLength - 1,
                   L"DIRECT=OS:%s",
                   wszPathName
                   ) < 0)
    {
      wprintf(L"The format name is too long for the buffer specified.\n");
      return FALSE;
    }
    else
    {
      wszFormatName[dwFormatNameLength - 1] = L'\0';
    }
 
 
    // Call MQOpenQueue to open the queue with the access and
    // share mode provided by the caller.
    hr = MQOpenQueue(
                     wszFormatName,           // Direct format name of the queue
                     MQ_SEND_ACCESS,                    // Access mode
                     MQ_DENY_NONE,             // Share mode
                     &phQueue                  // OUT: Queue handle
                     );
    delete [] wszFormatName;
    if (FAILED(hr))
    {
      fprintf(stderr, "An error occurred in MQOpenQueue \n",hr);
      return hr;
    }
  }

 
  // Call MQSendMessage to send the message to the queue.
  hr = MQSendMessage(
                     phQueue,                          // Queue handle
                     &msgProps,                       // Message property structure
                     MQ_NO_TRANSACTION               // Not in a transaction
                     );
  if (FAILED(hr))
  {
    MQCloseQueue(phQueue);
    return hr;
  }
 
 
  // Call MQCloseQueue to close the queue.
  hr = MQCloseQueue(phQueue);

  return hr;

 }


int main(array ^args)
{

    LPWSTR wszPathName =L".\\PRIVATE$\\SampleQueue";
    HRESULT hr = SendMessage(wszPathName);
    return 0;
}






Thursday, April 26, 2012

Open Message Queue in C++

Open MSMQ in C++ :


The MQOpenQueue function opens a queue for sending, peeking at, retrieving, or purging messages.

HRESULT APIENTRY MQOpenQueue(
  LPCWSTR lpwcsFormatName, 
  DWORD dwAccess,       
  DWORD dwShareMode,    
  QUEUEHANDLE * phQueue 
);

Parameters:
lpwcsFormatName :

[in] Pointer to the format name string of the queue you want to open.

dwAccess:

[in] Specifies how the application accesses the queue (peek, send, or receive). This setting cannot be changed while the queue is open.

Specify one of the following access modes:

MQ_PEEK_ACCESS

Messages can only be looked at. They cannot be removed from the queue.

MQ_SEND_ACCESS

Messages can only be sent to the queue. A subqueue cannot be opened using this access mode.

MQ_MOVE_ACCESS

Can be used only with a subqueue. Requires the user to have peek permission for the queue.

MQ_RECEIVE_ACCESS

Messages can be retrieved (read and removed) from the queue, peeked at, or purged. Whether a message is removed from the queue in a call to MQReceiveMessage depends on the dwAction parameter of this function.

See the description of the dwShareMode parameter for information on limiting who can receive messages from the queue.

MQ_PEEK_ACCESS | MQ_ADMIN_ACCESS

Messages in the local outgoing queue can only be peeked at (read without being removed from the queue).

MQ_RECEIVE_ACCESS | MQ_ADMIN_ACCESS

Messages in the local outgoing queue can be retrieved (read and removed from the queue), peeked at (read without being removed from the queue), or purged (deleted).

Note   MQ_ADMIN_ACCESS is used to access messages in a local outgoing queue, rather than the corresponding remote destination queue.

dwShareMode:

[in] How the queue will be shared. Specify one of the following:

MQ_DENY_NONE

Default. The queue is available to everyone. This setting must be used if dwAccess is set to MQ_SEND_ACCESS.

MQ_DENY_RECEIVE_SHARE

Limits those who can receive messages from the queue to this process. Once a process opens a queue with this share mode and with dwAccess set to MQ_RECEIVE_ACCESS, no one else, including the process that opened the queue, can open it again to peek or receive messages (this includes attempting to open the queue with multiple threads within the same process) until the original caller closes the queue. However, inside the process, the returned queue handle can be used by several threads.

Once the queue is opened with this share mode and with dwAccess set to MQ_RECEIVE_ACCESS, the MQ_ERROR_SHARING_VIOLATION error is returned when a second attempt is made to open the queue to peek or receive messages.

phQueue

[out] Pointer to a handle to the opened queue. If MQOpenQueue fails, a NULL pointer is returned.

Example Code:

#include "stdafx.h"
#include "windows.h"
#include "mq.h"
#include "tchar.h"
#include

HRESULT OpenQueue(LPWSTR wszPathName)
{
  QUEUEHANDLE phQueue = new QUEUEHANDLE ;
  HRESULT hr = S_FALSE;
  DWORD dwFormatNameLength = 0;
  WCHAR *wszFormatName = NULL;


  // Validate the input parameters.
  if ((wszPathName == NULL) || (phQueue == NULL))
  {
    return MQ_ERROR_INVALID_PARAMETER;
  }


  // Create a buffer for the direct format name.
  dwFormatNameLength = wcslen(wszPathName) + 11;
  wszFormatName = new WCHAR[dwFormatNameLength];
 
  if (wszFormatName)
  {


    // Create the direct format name of the queue.
    memset(wszFormatName, 0, dwFormatNameLength*sizeof(WCHAR));
    if (_snwprintf(
                   wszFormatName,
                   dwFormatNameLength - 1,
                   L"DIRECT=OS:%s",
                   wszPathName
                   ) < 0)
    {
      wprintf(L"The format name is too long for the buffer specified.\n");
      return FALSE;
    }
    else
    {
      wszFormatName[dwFormatNameLength - 1] = L'\0';
    }
 
 
    // Call MQOpenQueue to open the queue with the access and
    // share mode provided by the caller.
    hr = MQOpenQueue(
                     wszFormatName,           // Direct format name of the queue
                     MQ_SEND_ACCESS,                    // Access mode
                     MQ_DENY_NONE,             // Share mode
                     &phQueue                  // OUT: Queue handle
                     );
    delete [] wszFormatName;
    if (FAILED(hr))
    {
      fprintf(stderr, "An error occurred in MQOpenQueue \n",hr);
      return hr;
    }
  }
  return hr;

 }


int main(array ^args)
{

    LPWSTR wszPathName =L".\\PRIVATE$\\SampleQueue";
    HRESULT hr = OpenQueue(wszPathName);
    return 0;
}

Create Message Queue in C++

Create Message Queue in C++

      1. To create a message Queue in C++ we need to include the following header files.
     
#include "stdafx.h"
#include "windows.h"
#include "mq.h"

      2. The function needs to be linked with mqrt.lib. So in  Linker -> Input -> Additional Dependencies we need
to add mqrt.lib.

      3. Define a MQQUEUEPROPS structure and the structures needed to initialize it.
     
      4. Set the Queue Properties like Path name etc.
     
      5. Then call MQCreateQueue method for create a queue.
     
Example Code:


#include "stdafx.h"
#include "windows.h"
#include "mq.h"
#include "tchar.h"




 HRESULT CreateQueue(LPWSTR wszPathName)
{

  const int NUMBEROFPROPERTIES = 4;


  // Define a queue property structure and the structures needed to initialize it.
  MQQUEUEPROPS   QueueProps;
  MQPROPVARIANT  aQueuePropVar[NUMBEROFPROPERTIES];
  QUEUEPROPID    aQueuePropId[NUMBEROFPROPERTIES];
  HRESULT        aQueueStatus[NUMBEROFPROPERTIES];

  HRESULT        hr = MQ_OK;
 
 
  // Validate the input string.
  if (wszPathName == NULL)
  {
    return MQ_ERROR_INVALID_PARAMETER;
  }
 
 
  // Set queue properties.
  DWORD cPropId = 0;
  aQueuePropId[cPropId] = PROPID_Q_PATHNAME;
  aQueuePropVar[cPropId].vt = VT_LPWSTR;
  aQueuePropVar[cPropId].pwszVal = wszPathName;
  cPropId++;

  WCHAR wszLabel[MQ_MAX_Q_LABEL_LEN] = L"Journaling enforced";
  aQueuePropId[cPropId] = PROPID_Q_LABEL;
  aQueuePropVar[cPropId].vt = VT_LPWSTR;
  aQueuePropVar[cPropId].pwszVal = wszLabel;
  cPropId++;

  aQueuePropId[cPropId] = PROPID_Q_JOURNAL;
  aQueuePropVar[cPropId].vt = VT_UI1;
  aQueuePropVar[cPropId].bVal = MQ_JOURNAL;
  cPropId++;

  aQueuePropId[cPropId] = PROPID_Q_JOURNAL_QUOTA;
  aQueuePropVar[cPropId].vt = VT_UI4;
  aQueuePropVar[cPropId].ulVal = 1000;
  cPropId++;


  // Initialize the MQQUEUEPROPS structure.
  QueueProps.cProp = cPropId;                     //Number of properties
  QueueProps.aPropID = aQueuePropId;              //IDs of the queue properties
  QueueProps.aPropVar = aQueuePropVar;            //Values of the queue properties
  QueueProps.aStatus = aQueueStatus;              //Pointer to the return status


  // Call MQCreateQueue to create the queue.
  WCHAR wszFormatNameBuffer[256];
  DWORD dwFormatNameBufferLength = sizeof(wszFormatNameBuffer)/sizeof(wszFormatNameBuffer[0]);
  hr = MQCreateQueue(NULL,                        // Default security descriptor
                     &QueueProps,                 // Address of queue property structure
                     wszFormatNameBuffer,         // Pointer to format name buffer
                     &dwFormatNameBufferLength);  // Pointer to receive the queue's format name length


return hr;


}


int main(array ^args)
{

    LPWSTR wszPathName =L".\\PRIVATE$\\SampleQueue";
    CreateQueue(wszPathName);
    return 0;
}

Tuesday, April 10, 2012

Multithreading using CreateThread function in C++


        Multithreading is a specialized form of multitasking. In general, there are two types of multitasking: process-based and thread-based. A process is, in essence, a program that is executing. Thus, process-based multitasking is the feature that allows your computer to run two or more programs concurrently.

Creates a thread to execute within the virtual address space of the calling process.
To create a thread that runs in the virtual address space of another process, use the CreateRemoteThread function.

Syntax

HANDLE WINAPI CreateThread(
  __in_opt   LPSECURITY_ATTRIBUTES lpThreadAttributes,
  __in       SIZE_T dwStackSize,
  __in       LPTHREAD_START_ROUTINE lpStartAddress,
  __in_opt   LPVOID lpParameter,
  __in       DWORD dwCreationFlags,
  __out_opt  LPDWORD lpThreadId
);

Parameters

lpThreadAttributes [in, optional]
A pointer to a SECURITY_ATTRIBUTES structure that determines whether the returned handle can be inherited by child processes. If lpThreadAttributes is NULL, the handle cannot be inherited. The lpSecurityDescriptor member of the structure specifies a security descriptor for the new thread. If lpThreadAttributes is NULL, the thread gets a default security descriptor.
dwStackSize [in]
The initial size of the stack, in bytes. The system rounds this value to the nearest page. If this parameter is zero, the new thread uses the default size for the executable. For more information, see Thread Stack Size.
lpStartAddress [in]
A pointer to the application-defined function to be executed by the thread. This pointer represents the starting address of the thread. For more information on the thread function, see ThreadProc.
lpParameter [in, optional]
A pointer to a variable to be passed to the thread.
dwCreationFlags [in]
The flags that control the creation of the thread. 

Return value

If the function succeeds, the return value is a handle to the new thread. If the function fails, the return value is NULL.

 Example

// MultiThread_App.cpp : main project file.

#include "stdafx.h"
#include "windows.h"
#include "strsafe.h"
#include "stdio.h"

using namespace System;

// Thread Function 1
DWORD WINAPI Thread_no_1( LPVOID lpParam )
{
    Console::WriteLine(L"Thread_no_1");
      return 0;
}

// Thread Function 2
DWORD WINAPI Thread_no_2( LPVOID lpParam )
{
    Console::WriteLine(L"Thread_no_2");
      return 0;
}

int main()
{
    int Data_Of_Thread_1 = 1;            // Data of Thread 1
    int Data_Of_Thread_2 = 2;            // Data of Thread 2

    HANDLE Handle_Of_Thread_1 = 0;       // variable to hold handle of Thread 1
    HANDLE Handle_Of_Thread_2 = 0;       // variable to hold handle of Thread 1
 
     HANDLE Array_Of_Thread_Handles[2];   // Aray to store thread handles

    printf("All threads are started \n");
     // Create thread 1.
    Handle_Of_Thread_1 = CreateThread( NULL, 0, Thread_no_1, &Data_Of_Thread_1, 0, NULL);
    if ( Handle_Of_Thread_1 == NULL)  ExitProcess(Data_Of_Thread_1);
 
    // Create thread 2.
    Handle_Of_Thread_2 = CreateThread( NULL, 0, Thread_no_2, &Data_Of_Thread_2, 0, NULL);
    if ( Handle_Of_Thread_2 == NULL)  ExitProcess(Data_Of_Thread_2);

    Array_Of_Thread_Handles[0] = Handle_Of_Thread_1;
    Array_Of_Thread_Handles[1] = Handle_Of_Thread_2;

    // Blocks/waits till all child threads are finished
    WaitForMultipleObjects( 2, Array_Of_Thread_Handles, TRUE, INFINITE);

    printf("Since All threads executed lets close their handles \n");

    // Close all thread handles upon completion.
    CloseHandle(Handle_Of_Thread_1);
    CloseHandle(Handle_Of_Thread_2);
    getchar();
    return 0;
}

Function Templates with Examples

             Templates are a feature of the C++ programming language that allow functions and classes to operate with generic types. This allows a function or class to work on many different data types without being rewritten for each one.

Example :

#include <iostream>

using namespace std;


template <class T>
T Add (T a, T b) {
  T result;
  result = a+b;
  return (result);
}

int main()
{
    int i=5, j=6, k;
    k=Add<int>(i,j);
    cout << k << endl;
    return 0;
}