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
Define the queue property structures.
Set required queue properties. The following properties are required to create a transactional queue:
PROPID_Q_PATHNAME, (required)
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.
Set optional queue properties. This function also sets the PROPID_Q_LABEL property of the queue.
Initialize the MQQUEUEPROPS structure.
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;
}