Windows Dev Center

C/C++ Code Example: Requesting Authentication Using an Internal Certificate

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.

ms700149.note(en-us,VS.85).gifNote
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;
}
Show:
© 2015 Microsoft