C-C++ Code Example: Requesting Authentication Using an Internal Certificate
Applies To: Windows 10, Windows 7, Windows 8, Windows 8.1, Windows Server 2008, Windows Server 2008 R2, Windows Server 2012, Windows Server 2012 R2, Windows Server Technical Preview, Windows Vista
This example provides an application-defined function that requests authentication based on a given authentication level. This function sets the PROPID_M_AUTH_LEVEL property of the message using the supplied authentication level value, registers the internal certificate provided by Message Queuing, if one is not found, and then sends the message to a known destination queue. This function could be used to send HTTP and non-HTTP messages.
For information on how Message Queuing authenticates messages, see Message Authentication.
To request authentication
Define constants, variables, and structures needed by the function.
Specify the message properties. This example sets the following message properties.
•PROPID_M_AUTH_LEVEL: Specifies the authentication level for the message.
•PROPID_M_LABEL: Identifies the message.
Initialize the MQMSGPROPS structure.
Call MQRegisterCertificate to register the internal certificate.
Construct a direct format name for opening the destination queue.
Note
wcslen properly handles only null-terminated strings. This code example does not verify that the strings passed to it are null-terminated. It is the responsibility of the caller to ensure that the strings passed are null-terminated.
Call MQOpenQueue to open the destination queue with send access.
Call MQSendMessage to send the message to the destination queue.
Call MQCloseQueue to close the destination queue and free resources.
Code Example
The following example may require different versions of MSMQ, depending on the authentication level provided by the caller.
HRESULT RequestInternalAuthentication(
WCHAR * wszQueueName,
WCHAR * wszComputerName,
ULONG ulAuthLevel
)
{
// Validate the input strings.
if (wszQueueName == NULL || wszComputerName == NULL)
{
return MQ_ERROR_INVALID_PARAMETER;
}
// Define constants, variables, and structures.
const int NUMBEROFPROPERTIES = 1; // Number of properties
DWORD cPropId = 0; // Property counter
HRESULT hr = MQ_OK; // Return code
MQMSGPROPS msgProps;
MSGPROPID aMsgPropId[NUMBEROFPROPERTIES];
MQPROPVARIANT aMsgPropVar[NUMBEROFPROPERTIES];
HRESULT aMsgStatus[NUMBEROFPROPERTIES];
// Specify the message properties to be sent.
aMsgPropId[cPropId] = PROPID_M_AUTH_LEVEL;
aMsgPropVar[cPropId].vt = VT_UI4;
aMsgPropVar[cPropId].ulVal = ulAuthLevel;
cPropId++;
// Initialize the MQMSGPROPS structure.
msgProps.cProp = cPropId;
msgProps.aPropID = aMsgPropId;
msgProps.aPropVar = aMsgPropVar;
msgProps.aStatus = aMsgStatus;
// Call MQRegisterCertificate to register the internal certificate.
hr = MQRegisterCertificate(
MQCERT_REGISTER_IF_NOT_EXIST,
NULL,
0
);
if (FAILED(hr))
{
return hr;
}
// Generate the format name required for opening the queue.
WCHAR * wszFormatName = NULL;
DWORD dwFormatNameLength = 0;
dwFormatNameLength = wcslen(wszQueueName) + wcslen(wszComputerName) + 12;
wszFormatName = new WCHAR[dwFormatNameLength];
if (wszFormatName == NULL)
{
return MQ_ERROR_INSUFFICIENT_RESOURCES;
}
memset(wszFormatName, 0, dwFormatNameLength*sizeof(WCHAR));
// ************************************
// You must concantenate "DIRECT=OS:", wszComputerName, "\", and
// wszQueueName into the wszFormatName variable.
// wszFormatName = "DIRECT=OS:" + wszComputerName + "\" +
// wszQueueName
// If the format name is too long for the buffer, return FALSE.
// ************************************
// Call MQOpenQueue to open the destination queue with send access.
HANDLE hQueue = NULL; // Queue handle
hr = MQOpenQueue(
wszFormatName, // Format name of queue
MQ_SEND_ACCESS, // Access mode
MQ_DENY_NONE, // Share mode
&hQueue // [out] Queue handle
);
// Free the memory that was allocated for the format name string.
delete [] wszFormatName;
// Handle any error returned by MQOpenQueue.
if (FAILED(hr))
{
return hr;
}
// Call MQSendMessage to send the message to the destination queue.
hr = MQSendMessage(
hQueue, // Queue handle
&msgProps, // Message property structure
MQ_NO_TRANSACTION // Not in a transaction
);
if(FAILED(hr))
{
MQCloseQueue(hQueue);
return hr;
}
// Call MQCloseQueue to close the destination queue.
hr = MQCloseQueue(hQueue);
return hr;
}