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.
#define NMSGPROPS 10 //Number of message properties.
MSGPROPID aMsgPropId[NMSGPROPS];
PROPVARIANT aMsgPropVar[NMSGPROPS];
HRESULT aMsgStatus[NMSGPROPS], hr;
MQMSGPROPS MsgProps;
DWORD PropIdCount = 0;
//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++;
MsgProps.cProp = PropIdCount; //Number of properties
MsgProps.aPropID = aMsgPropId; //Ids of properties
MsgProps.aPropVar = aMsgPropVar; //Values of properties
MsgProps.aStatus = aMsgStatus; //Error reports
hr = MQPathNameToFormatName(L"machine_name\\queue_name",
szFormatNameBuffer,
&dwFormatNameBufferLength);
hr = MQOpenQueue(szFormatNameBuffer, MQ_SEND_ACCESS, 0, &hQueue);
hr = MQSendMessage(hQueue, &MsgProps, NULL);
hr = MQCloseQueue(hQueue);
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;
}