Export (0) Print
Expand All
1 out of 1 rated this helpful - Rate this topic

C/C++ Code Example: Returning Acknowledgment Messages (Connector Applications)

This example provides an application-defined function that returns an acknowledgment message to the specified administration queue.

ms703238.note(en-us,VS.85).gifNote
This function should only be called from a connector application when it is sending messages to foreign queues.

For information on connecting to a foreign messaging system, see Message Queuing Connector Services.

Code Example

The following code example requires MSMQ 2.0 or later.

HRESULT CreateAck(
                  LPWSTR lpstrAdminQueue,
                  USHORT AckValue,
                  MQMSGPROPS* pmsgprops,
                  GUID g_guidConnectorType
                  )
{
  MQMSGPROPS SendMsgProp;
  MSGPROPID aPropID[40];
  MQPROPVARIANT aPropVar[40];
  HRESULT aStatus[40];
  HRESULT hr = MQ_OK;
  HANDLE hQueue = NULL;
  DWORD cProp = 0;


  // Validate the input parameters.
  if (lpstrAdminQueue == NULL || pmsgprops == NULL)
  {
    return MQ_ERROR_INVALID_PARAMETER;
  }


  // Open the administration queue.
  // specified by the original message.
  hr = MQOpenQueue(
                   lpstrAdminQueue,
                   MQ_SEND_ACCESS,
                   0,
                   &hQueue
                   );
  if (FAILED(hr))
  {
    //
    // Handle failure.
    //
  return hr;
  }

  DWORD dwExtensionMsgSize = 0;
  DWORD dwSenderidLen = 0;
  DWORD dwBodySize = 0;
  DWORD dwLabelLen = 0;
  BOOL fEncrypted = FALSE;
  DWORD i;


  // Set the acknowledgment message default values.
  aPropID[cProp] = PROPID_M_CLASS;
  aPropVar[cProp].vt = VT_UI2;
  aPropVar[cProp].uiVal = AckValue;
  cProp++;

  aPropID[cProp] = PROPID_M_ACKNOWLEDGE;
  aPropVar[cProp].vt = VT_UI1;
  aPropVar[cProp].bVal = MQMSG_ACKNOWLEDGMENT_NONE;
  cProp++;

  aPropID[cProp] = PROPID_M_TIME_TO_BE_RECEIVED;
  aPropVar[cProp].vt = VT_UI4;
  aPropVar[cProp].ulVal = INFINITE;
  cProp++;

  aPropID[cProp] = PROPID_M_TIME_TO_REACH_QUEUE;
  aPropVar[cProp].vt = VT_UI4;
  aPropVar[cProp].ulVal = INFINITE;
  cProp++;

  aPropID[cProp] = PROPID_M_JOURNAL;
  aPropVar[cProp].vt = VT_UI1;
  aPropVar[cProp].bVal = MQMSG_JOURNAL_NONE;
  cProp++;


  // Set all other message properties to 
  // the values of the original message.


  // Get the size and length of the properties.
  for (i = 0; i < pmsgprops->cProp ; i++)
  {
    switch(pmsgprops->aPropID[i])
    {
      case PROPID_M_EXTENSION_LEN:
        dwExtensionMsgSize = pmsgprops->aPropVar[i].ulVal;    
        break;
        
      case PROPID_M_SENDERID_LEN:
        dwSenderidLen = pmsgprops->aPropVar[i].ulVal;
        break;
        
      case PROPID_M_BODY_SIZE:
        dwBodySize = pmsgprops->aPropVar[i].ulVal;
        break;
        
      case PROPID_M_PRIV_LEVEL:
        fEncrypted = (pmsgprops->aPropVar[i].ulVal == MQMSG_PRIV_LEVEL_BODY_BASE);
        break;
        
      default:
        break;
    }
  }

  for (i = 0; i < pmsgprops->cProp ; i++)
  {
    switch (pmsgprops->aPropID[i])
    {

      // Set the correlation identifier.
      case PROPID_M_MSGID:
        aPropID[cProp] = PROPID_M_CORRELATIONID;
        aPropVar[cProp].vt = VT_UI1 | VT_VECTOR;
        aPropVar[cProp].caub.cElems = pmsgprops->aPropVar[i].caub.cElems;
        aPropVar[cProp].caub.pElems = pmsgprops->aPropVar[i].caub.pElems;
        cProp++;
        break;
        
      // Set the message priority.
      case PROPID_M_PRIORITY:
        aPropID[cProp] = PROPID_M_PRIORITY;
        aPropVar[cProp].vt = VT_UI1;
        aPropVar[cProp].bVal = pmsgprops->aPropVar[i].bVal;
        cProp++;
        break;
        
      // Set the delivery mode.
      case PROPID_M_DELIVERY:
        aPropID[cProp] = PROPID_M_DELIVERY;
        aPropVar[cProp].vt = VT_UI1;
        aPropVar[cProp].bVal = pmsgprops->aPropVar[i].bVal;
        cProp++;
        break;
        
      // Set application-specific information.
      case PROPID_M_APPSPECIFIC:
        aPropID[cProp] = PROPID_M_APPSPECIFIC;
        aPropVar[cProp].vt = VT_UI4;
        aPropVar[cProp].ulVal = pmsgprops->aPropVar[i].ulVal;
        cProp++;
        break;
        
      // Set the message label to the same.
      case PROPID_M_LABEL:
        aPropID[cProp] = PROPID_M_LABEL;
        aPropVar[cProp].vt = VT_LPWSTR;
        aPropVar[cProp].pwszVal = pmsgprops->aPropVar[i].pwszVal;
        cProp++;
        break;
        
      // Set the extension information.
      case PROPID_M_EXTENSION:
        aPropID[cProp] = PROPID_M_EXTENSION;
        aPropVar[cProp].vt = VT_UI1|VT_VECTOR;
        aPropVar[cProp].caub.cElems = dwExtensionMsgSize;
        aPropVar[cProp].caub.pElems = pmsgprops->aPropVar[i].caub.pElems;
        cProp++;
        break;
        
      // Set Sender ID information.
      case PROPID_M_SENDERID:
        aPropID[cProp] = PROPID_M_SENDERID;
        aPropVar[cProp].vt = VT_UI1|VT_VECTOR;
        aPropVar[cProp].caub.cElems = dwSenderidLen;
        aPropVar[cProp].caub.pElems = pmsgprops->aPropVar[i].caub.pElems;
        cProp++;
        break;
  
      // Set the acknowledgment message response queue to 
      // the destination queue of the original message.
      case PROPID_M_DEST_QUEUE:
        aPropID[cProp] = PROPID_M_RESP_QUEUE;
        aPropVar[cProp].vt = VT_LPWSTR;
        aPropVar[cProp].pwszVal = pmsgprops->aPropVar[i].pwszVal;
        cProp++;           
        break;

      // Set the message body. If the acknowledgment is negative 
      // and the original message is not encrypted, add 
      // the message body of original message.
      case PROPID_M_BODY:
        if (MQCLASS_NACK(AckValue) && ! fEncrypted)
        {
          aPropID[cProp] = PROPID_M_BODY;
          aPropVar[cProp].vt = VT_UI1|VT_VECTOR;
          aPropVar[cProp].caub.cElems = dwBodySize;
          aPropVar[cProp].caub.pElems = pmsgprops->aPropVar[i].caub.pElems;
          cProp++;
        }
        break;

      default:
      switch (pmsgprops->aPropID[i]){

        // The following fields were handled elsewhere:
       case PROPID_M_EXTENSION_LEN:
       case PROPID_M_SENDERID_LEN:
       case PROPID_M_BODY_SIZE:
       case PROPID_M_PRIV_LEVEL:
       case PROPID_M_CLASS:
       case PROPID_M_ACKNOWLEDGE:
       case PROPID_M_TIME_TO_BE_RECEIVED:
       case PROPID_M_TIME_TO_REACH_QUEUE:
       case PROPID_M_JOURNAL:
       case PROPID_M_CONNECTOR_TYPE:
       case PROPID_M_CORRELATIONID:
       case PROPID_M_RESP_QUEUE:
         break;

       // If it is a field that does not need special handling,
       // simply set it as it is.
       default:
         aPropID[cProp] = pmsgprops->aPropID[i];
         aPropVar[cProp] = pmsgprops->aPropVar[i];
         break;

       }
         break;
    }
  }


  // Set the connector type identifier (GUID) to 
  // indicate who generated the acknowledgment message.
  aPropID[cProp] = PROPID_M_CONNECTOR_TYPE;
  aPropVar[cProp].vt = VT_CLSID;
  aPropVar[cProp].puuid = &g_guidConnectorType;
  cProp++;

  SendMsgProp.aStatus = aStatus;
  SendMsgProp.aPropID = aPropID;
  SendMsgProp.aPropVar = aPropVar;
  SendMsgProp.cProp = cProp;


  // Send the acknowledgment message back to the 
  // administration queue specified by the 
  // original message.
  hr = MQSendMessage(
                     hQueue,
                     &SendMsgProp,
                     MQ_NO_TRANSACTION
                     );

  if (FAILED(hr))
  {
    // Handle failure.
    MQCloseQueue(hQueue);
    return hr;
  }
  hr = MQCloseQueue(hQueue);
  return hr;
}
Did you find this helpful?
(1500 characters remaining)
Thank you for your feedback
Show:
© 2014 Microsoft. All rights reserved.