C-C++ Code Example: Creating a Transactional Queue

 

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 creates a public or private transactional queue based on a given queue path name. The function returns the public or private format name of the queue created and the length of format name including the null-terminating character.

Note

Creating transactional and nontransactional queues is very similar. The only difference is the setting of the transactional level property for the queue. For example, the same function described in this example is also used in the example on creating a nontransactional queues.

If a NULL pointer to a SECURITY_DESCRIPTOR structure is passed to this function in pSecurityDescriptor, the queue is created with the default security descriptor. For an example of creating a security descriptor, see C/C++ Code Example: Creating a Security Descriptor.

It is the responsibility of the calling function that pdwOutFormatNameLength points to the number of WCHARs in the buffer supplied to receive the format name of the queue.

The following procedure shows how the function creates the queue.

To create a transactional queue

  1. Define the queue property structures.

  2. Set required queue properties. The following properties are required to create a transactional queue:

Note

In this example, a period (".") is used to indicate the local computer. For Message Queuing servers and independent clients, the local machine is the local computer. However, for dependent clients, the local machine is the dependent client's supporting server.

  1. Set optional queue properties. This function also sets the PROPID_Q_LABEL property of the queue.

  2. Initialize the MQQUEUEPROPS structure.

  3. Call MQCreateQueue to create the queue.

Example

The following code example contains no version-specific Message Queuing calls.

HRESULT CreateXactMSMQQueue(  
                            LPWSTR wszPathName,   
                            PSECURITY_DESCRIPTOR pSecurityDescriptor,  
                            LPWSTR wszOutFormatName,  
                            DWORD *pdwOutFormatNameLength  
                            )  
{  
  
  // Define the maximum number of queue properties.  
  const int NUMBEROFPROPERTIES = 3;  
  
  // Define a queue property structure and the structures needed to initialize it.  
  MQQUEUEPROPS   QueueProps;  
  MQPROPVARIANT  aQueuePropVar[NUMBEROFPROPERTIES];  
  QUEUEPROPID    aQueuePropId[NUMBEROFPROPERTIES];  
  HRESULT        aQueueStatus[NUMBEROFPROPERTIES];  
  DWORD          cPropId = 0;  
  HRESULT        hr = MQ_OK;  
  
  // Validate the input parameters.  
  if (wszPathName == NULL || pdwOutFormatNameLength == NULL || pdwOutFormatNameLength == NULL)  
  {  
    return MQ_ERROR_INVALID_PARAMETER;  
  }  
  
  // Set the PROPID_Q_PATHNAME property with the path name provided.  
  aQueuePropId[cPropId] = PROPID_Q_PATHNAME;  
  aQueuePropVar[cPropId].vt = VT_LPWSTR;  
  aQueuePropVar[cPropId].pwszVal = wszPathName;  
  cPropId++;  
  
  // Set optional queue properties. PROPID_Q_TRANSACTIONAL  
  // must be set to make the queue transactional.  
  aQueuePropId[cPropId] = PROPID_Q_TRANSACTION;  
  aQueuePropVar[cPropId].vt = VT_UI1;  
  aQueuePropVar[cPropId].bVal = MQ_TRANSACTIONAL;  
  cPropId++;  
  
  WCHAR wszLabel[MQ_MAX_Q_LABEL_LEN] = L"Test Queue";  
  aQueuePropId[cPropId] = PROPID_Q_LABEL;  
  aQueuePropVar[cPropId].vt = VT_LPWSTR;  
  aQueuePropVar[cPropId].pwszVal = wszLabel;  
  cPropId++;  
  
  // Initialize the MQQUEUEPROPS structure   
  QueueProps.cProp = cPropId;               //Number of properties  
  QueueProps.aPropID = aQueuePropId;        //IDs of the queue properties  
  QueueProps.aPropVar = aQueuePropVar;      //Values of the queue properties  
  QueueProps.aStatus = aQueueStatus;        //Pointer to return status  
  
  // Call MQCreateQueue to create the queue, first declaring  
  // a buffer to receive the return queue format name.  
  WCHAR wszFormatNameBuffer[256];  
  DWORD dwFormatNameBufferLength = 256;  
  
  hr = MQCreateQueue(pSecurityDescriptor,         // Security descriptor  
                     &QueueProps,                 // Address of queue property structure  
                     wszFormatNameBuffer,         // Pointer to format name buffer  
                     &dwFormatNameBufferLength);  // Pointer to receive the queue's format name length  
  
  // Return the format name if the queue is created successfully.  
  if (hr == MQ_OK || hr == MQ_INFORMATION_PROPERTY)  
  {  
    if (*pdwOutFormatNameLength >= dwFormatNameBufferLength)  
    {  
  // ************************************  
        // You must copy wszFormatNameBuffer into the wszOutFormatName   
        // buffer.   
        // ************************************  
  
      wszOutFormatName[*pdwOutFormatNameLength - 1] = L'\0';  
      *pdwOutFormatNameLength = dwFormatNameBufferLength;  
    }  
    else  
    {  
      wprintf(L"The queue was created, but its format name cannot be returned.\n");  
    }  
  }  
  return hr;  
}