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

  1. Define constants, variables, and structures needed by the function.

  2. Specify the message properties. This example sets the following message properties.

  3. Initialize the MQMSGPROPS structure.

  4. Call MQRegisterCertificate to register the internal certificate.

  5. 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.

  1. Call MQOpenQueue to open the destination queue with send access.

  2. Call MQSendMessage to send the message to the destination queue.

  3. 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;  
}