Sending Private Messages

To send a private message, the sending application must set the privacy level (PROPID_M_PRIV_LEVEL) of the message, and, optionally, specify the encryption algorithm (PROPID_M_ENCRTYPTION_ALG) to be used to encrypt the body of the message.

The functions used to send a private message are no different from those used to send other messages.

When sending (and receiving) private messages, the application has no part in encrypting (or decrypting) the message. (For information on how MSMQ encrypts and decrypts messages, see Private Messages.)

Note  Each MSMQ message can have no more than 4 MB of data.

    To send a private message
  1. Define the MQMSGPROPS structure.
    #define NMSGPROPS 10             //Number of message properties.
      MSGPROPID aMsgPropId[NMSGPROPS];     
      PROPVARIANT aMsgPropVar[NMSGPROPS];
      HRESULT aMsgStatus[NMSGPROPS], hr;
      MQMSGPROPS MsgProps;
      DWORD PropIdCount = 0;
     
  2. Specify the properties of the message. The example below specifies the label, body, privacy level, and encryption algorithm for the message. The value of PROPID_M_PRIV_LEVEL indicates that the message is private.
    //Set the label of the message (PROPID_M_LABEL).
    aMsgPropId[PropIdCount] = PROPID_M_LABEL;    // Property identifier
    aMsgPropVar[PropIdCount].vt = VT_LPWSTR;     // Type indicator
    aMsgPropVar[PropIdCount].pwszVal = L"Private Message"; // Label
    PropIdCount++;
    
    //Set the body of the message (PROPID_M_BODY).
    aMsgPropId[PropIdCount] = PROPID_M_BODY;     // Property identifier
    aMsgPropVar[PropIdCount].vt = VT_VECTOR | VT_UI1;  // Type
    aMsgPropVar[PropIdCount].caub.pElems = (LPBYTE)MESSAGE_BODY; //Body
    aMsgPropVar[PropIdCount].caub.cElems = sizeof(MESSAGE_BODY); //Len
    PropIdCount++;
    
    //Set the privacy level of the message (PROPID_M_PRIV_LEVEL).
    aMsgPropId[PropIdCount] = PROPID_M_PRIV_LEVEL; // Property ID
    aMsgPropVar[PropIdCount].vt = VT_UI4;          // Type indicator
    aMsgPropVar[PropIdCount].ulVal = MQMSG_PRIV_LEVEL_BODY;
    PropIdCount++;
    
    //Set the encryption algorithm (PROPID_M_ENCRYPTION_ALG).
    aMsgPropId[PropIdCount] = PROPID_M_ENCRYPTION_ALG;  //Property ID
    aMsgPropVar[PropIdCount].vt = VT_UI4;         //Type indicator
    aMsgPropVar[PropIdCount].ulVal = CALG_RC4;    //Encryption alg
    PropIdCount++;
        
  3. Set the MQMSGPROPS structure.
    MsgProps.cProp = PropIdCount;         //Number of properties
    MsgProps.aPropID = aMsgPropId;        //Ids of properties
    MsgProps.aPropVar = aMsgPropVar;      //Values of properties
    MsgProps.aStatus = aMsgStatus;        //Error reports
    
  4. Obtain the format name of the destination queue. The example below calls MQPathNameToFormatName to obtain a format name from a known pathname.
    hr = MQPathNameToFormatName(L"machine_name\\queue_name",
                                szFormatNameBuffer,
                                &dwFormatNameBufferLength);
    
  5. Call MQOpenQueue to open the destination queue with send access.
    hr = MQOpenQueue(szFormatNameBuffer, MQ_SEND_ACCESS, 0, &hQueue);
    
  6. Call MQSendMessage to send the message.
    hr = MQSendMessage(hQueue, &MsgProps, NULL);
    
  7. Call MQCloseQueue to close the destination queue.
    hr = MQCloseQueue(hQueue);
        

Example

This example sends a single private message to a known destination queue. Starting with the known pathname of the queue, the example translates the pathname into a format name, opens the destination queue with send access, sets the properties of the message (label, body, privacy level, and encryption algorithm), and then sends the message to the destination queue.

#include <windows.h>
#include <wincrypt.h>                      //CrpytoAPI header file.
#include <stdio.h>
#include <mq.h>                            //MSMQ header file


int main(int arg, char *argv[])

{
  ////////////////////////////
  //  Define structures.
  ////////////////////////////

  // Define MQMSGPROPS
  #define NMSGPROPS 10             // Number of message properties.
  MSGPROPID aMsgPropId[NMSGPROPS];     
  PROPVARIANT aMsgPropVar[NMSGPROPS];
  HRESULT aMsgStatus[NMSGPROPS], hr;
  MQMSGPROPS MsgProps;
  DWORD PropIdCount = 0;

  // Define format name buffer
  DWORD dwFormatNameBufferLength = 256;
  WCHAR szFormatNameBuffer[256];

  // Define message body
  # define MESSAGE_BODY L"Private massage."

  // Define queue handle
  HANDLE hQueue;

  /////////////////////////////////////////
  // Specify the message properties. For   
  // private messages, PROPID_M_PRIV_LEVEL
  // must be specified.
  ////////////////////////////////////////
  
  // Set the label of the message (PROPID_M_LABEL).
  aMsgPropId[PropIdCount] = PROPID_M_LABEL;    // Property identifier
  aMsgPropVar[PropIdCount].vt = VT_LPWSTR;     // Type indicator
  aMsgPropVar[PropIdCount].pwszVal = L"Private Message"; // Label
  PropIdCount++;
  
  // Set the body of the message (PROPID_M_BODY).
  aMsgPropId[PropIdCount] = PROPID_M_BODY;     // Property identifier
  aMsgPropVar[PropIdCount].vt = VT_VECTOR | VT_UI1;  // Type indicator 
  aMsgPropVar[PropIdCount].caub.pElems = (LPBYTE)MESSAGE_BODY; // Body
  aMsgPropVar[PropIdCount].caub.cElems = sizeof(MESSAGE_BODY); // Len
  PropIdCount++;
  
  // Set the privacy level of the message (PROPID_M_PRIV_LEVEL).
  aMsgPropId[PropIdCount] = PROPID_M_PRIV_LEVEL; // Property ID
  aMsgPropVar[PropIdCount].vt = VT_UI4;          // Type indicator
  aMsgPropVar[PropIdCount].ulVal = MQMSG_PRIV_LEVEL_BODY; //Priv level
  PropIdCount++;
  
  // Set the encryption algorithm for the message (PROPID_M_ENCRYPTION_ALG).
  aMsgPropId[PropIdCount] = PROPID_M_ENCRYPTION_ALG;  // Property ID
  aMsgPropVar[PropIdCount].vt = VT_UI4;         // Type indicator
  aMsgPropVar[PropIdCount].ulVal = CALG_RC4;    // Encryption alg
  PropIdCount++;
    
  
  /////////////////////////////////
  // Set the MQMSGPROPS structure.
  /////////////////////////////////
  MsgProps.cProp = PropIdCount;         // Number of properties
  MsgProps.aPropID = aMsgPropId;        // IDs of properties
  MsgProps.aPropVar = aMsgPropVar;      // Values of properties
  MsgProps.aStatus = aMsgStatus;        // Error reports
  
  
  ////////////////////////////
  //Get format name of queue.
  ////////////////////////////
 
  hr = MQPathNameToFormatName(L"machine_name\\queue_name",
                              szFormatNameBuffer,
                                  &dwFormatNameBufferLength);
  if (FAILED(hr))
  {
  fprintf(stderr, "Failed in MQPathNameToFormatName, error = 0x%x\n",hr);
  return -1;
  }
 
 
  ////////////////////////////
  // Open queue.
  ////////////////////////////
 
  hr = MQOpenQueue(szFormatNameBuffer, MQ_SEND_ACCESS, 0, &hQueue);
  if (FAILED(hr))
  {
  fprintf(stderr, "Failed in MQOpenQueue, error = 0x%x\n",hr);
  return -1;
  }
  
  
  ////////////////////////////
  // Send message.
  ////////////////////////////
 
  hr = MQSendMessage(hQueue, &MsgProps, NULL);
  if (FAILED(hr))
  {
   fprintf(stderr, "Failed in MQSendMessage, error = 0x%x\n",hr);
   return -1;
   }
 
  
  ////////////////////////////
  // Close queue.
  ////////////////////////////
  
  MQCloseQueue(hQueue);
  if (FAILED(hr))
  {
   fprintf(stderr, "Failed in MQCloseQueue, error = 0x%x\n",hr);
   return -1;
  }


  printf("The private message was sent successfully.\n");
  return 0;
 
}