3.11.4.1.14 Receive (Opnum 20)
The Receive method is received by the server in an RPC_REQUEST packet. In response, the server retrieves the Message at the head of the referenced queue's MessagePositionList and removes it.
-
HRESULT Receive( [in, optional] VARIANT* Transaction, [in, optional] VARIANT* WantDestinationQueue, [in, optional] VARIANT* WantBody, [in, optional] VARIANT* ReceiveTimeout, [in, optional] VARIANT* WantConnectorType, [out, retval] IMSMQMessage4** ppmsg );
Transaction: A pointer to a VARIANT that MUST contain either of the following:
-
A VT_DISPATCH or a VT_DISPATCH | VT_BYREF that points to an MSMQTransaction object.
-
A VT_I4 that corresponds to one of the MQTRANSACTION (section 2.2.2.1) enumeration values.
-
If this parameter is not specified by the client, the server MUST use the default value MQ_MTS_TRANSACTION (0x00000001) in place of the unspecified value.
WantDestinationQueue: A pointer to a VARIANT (VT_BOOL).
-
If this parameter is not specified by the client, the server MUST use the default value VARIANT_FALSE (0x0000) in place of the unspecified value.
-
Value
Meaning
VARIANT_TRUE
0xFFFF
The server MUST return an MSMQMessage object that has the DestinationQueueInfo property set.
VARIANT_FALSE
0x0000
Default. The server MUST return an MSMQMessage object that does not have the DestinationQueueInfo property set.
WantBody: A pointer to a VARIANT (VT_BOOL).
-
If this parameter is not specified by the client, the server MUST use the default value VARIANT_TRUE (0xFFFF) in place of the unspecified value.
-
Value
Meaning
VARIANT_TRUE
0xFFFF
Default. The server MUST return an MSMQMessage object that has the Body property set.
VARIANT_FALSE
0x0000
The server MUST return an MSMQMessage object that does not have the Body property set.
ReceiveTimeout: A pointer to a VARIANT that contains a long value (VT_I4) that specifies the time, in milliseconds, that the server MUST NOT exceed while waiting for a new message to arrive.
-
If this parameter is not specified by the client, the server MUST use the default value INFINITE (0xFFFFFFFF).
WantConnectorType: A pointer to a VARIANT (VT_BOOL).
-
If this parameter is not specified by the client, the server MUST use the default value VARIANT_FALSE (0x0000) in place of the unspecified value.
-
Value
Meaning
VARIANT_TRUE
0xFFFF
The server MUST return an MSMQMessage object that has the ConnectorTypeGuid property set.
VARIANT_FALSE
0x0000
Default. The server MUST return an MSMQMessage object that does not have the ConnectorTypeGuid property set.
ppmsg: A pointer to a pointer to an IMSMQMessage4 interface that MUST be set by the server with the received message.
Return Values: The method MUST return S_OK (0x00000000) on success or an implementation-specific error HRESULT on failure.
When processing this call, the server MUST follow these guidelines:
If the IsInitialized instance variable equals False:
Return an error OLE_E_BLANK (0x80040007), and take no further action.
If the IsClosed instance variable equals True:
Return an error MQ_ERROR_INVALID_HANDLE (0xC00E0007), and take no further action.
If refQueue.AccessType is not equal to ReceiveAccess or ReceiveAdminAccess:
Return an error MQ_ERROR_ACCESS_DENIED (0xC00E0025), and take no further action.
If the ppmsg output parameter is NULL:
Return E_INVALIDARG (0x80070057), and take no further action.
If the Transaction input parameter is not NULL:
If the Transaction input parameter is a VT_DISPATCH or a VT_DISPATCH | VT_BYREF that points to an enlisted MSMQTransaction object:
Obtain the MSMQTransaction instance that corresponds to the Transaction parameter by invoking the IDispatch::QueryInterface method (see section 3.1) on the Transaction parameter with the interface identifier of IMSMQTransaction3.
Define transaction identifier as MSMQTransaction.Transaction.TransactionIdentifier.
Else, if the Transaction input parameter is a VT_I4:
Define and retrieve transaction identifier as described in section 2.2.2.1, using the enum numeric value represented by the Transaction input parameter.
Else:
Return an error, and take no further action.
Identify the Transaction from the TransactionCollection of the QueueManager, where the value of the Transaction.Identifier property equals the value of the transaction identifier.
If a Transaction cannot be located:
Create a new Transaction, and set the Transaction.Identifier property to the value of the transaction identifier. Refer to this Transaction as the identified Transaction from here on.
Add the created Transaction to the TransactionCollection of the QueueManager.
Define suitable message as the first Message from the head of the MessagePositionList of the referenced queue for which the MessagePosition.State attribute does not equal Locked.
Attempt to retrieve the suitable message by raising the Dequeue Message event with the following arguments:
iQueueDesc: This MUST be set to the OpenQueueDescriptor for the referenced queue.
iTimeout: The amount of time to wait, in seconds.
iCursor: This MUST be set to a reference to the Cursor instance variable.
iTransaction: If the Transaction input parameter is not NULL, this MUST be set to a reference to the newly created Transaction object that provides the unit-of-work for the dequeue operation.
Based on the rStatus, take the following actions:
If the rStatus is not MQ_OK:
If the ReceiveTimeout input parameter is 0:
Set the ppmsg output parameter to NULL.
Return MQ_ERROR_MESSAGE_NOT_FOUND (0xc00e0008), and take no further action.
If the ReceiveTimeout input parameter is INFINITE (0xFFFFFFFF):
Block this call until a suitable message is available.
Retrieve the suitable message, and instantiate an MSMQMessage instance and initialize it with the suitable message, observing the requirements set forth by the WantBody, WantDestinationQueue, and WantConnectorType input parameters. For details of initializing the MSMQMessage object, refer to section 3.17.3.
Set the ppmsg output parameter to the newly instantiated MSMQMessage instance.
If the rStatus is MQ_ERROR_IO_TIMEOUT and if the ReceiveTimeout input parameter is neither 0 nor INFINITE (0xFFFFFFFF):
Block the call until either of the following events occurs:
The time-out specified by the ReceiveTimeout input parameter expires:
Set the ppmsg output parameter to NULL.
Return MQ_ERROR_IO_TIMEOUT (0xc00e001b), and take no further action.
If rStatus is MQ_OK:
Retrieve the suitable message, and instantiate an MSMQMessage instance and initialize it with the suitable message, observing the requirements set forth by the WantBody, WantDestinationQueue, and WantConnectorType input parameters. For details of initializing the MSMQMessage object, refer to section 3.17.3.
Set the ppmsg output parameter to the newly instantiated MSMQMessage instance.
Else, if one or more suitable messages are available:
Retrieve the suitable message, and instantiate an MSMQMessage instance and initialize it with the suitable message, observing the requirements set forth by the WantBody, WantDestinationQueue, and WantConnectorType input parameters. For details of initializing the MSMQMessage object, refer to section 3.17.3.
Set the ppmsg output parameter to the newly instantiated MSMQMessage instance.
If the Transaction input parameter is equal to MQ_MTS_TRANSACTION (0x00000001), MQ_XA_TRANSACTION (0x00000002), or a pointer to an MSMQTransaction instance:
Set the State property of the suitable message to Locked.
Create a new TransactionalOperation, and set:
The MessageReference property with the suitable message.
The OperationType property to the OperationType.Receive enumeration value.
Add the newly created TransactionalOperation to the TransactionalOperationCollection of the Transaction previously identified.
Else:
If QueueType is NOT set to System for the referenced queue and its Journaling property is True:
Copy the suitable message to the MessagePositionList of the queue referenced by the JournalQueueReference property of the referenced queue.
Remove the suitable message from the MessagePositionList of the referenced queue.
Return S_OK (0x00000000), and take no further action.