3.17.4.1.48 Send (Opnum 54)
The Send method is received by the server in an RPC_REQUEST packet. In response, the server MUST send a message.
-
HRESULT Send( [in] IDispatch* DestinationQueue, [in, optional] VARIANT* Transaction );
DestinationQueue: A pointer to an IDispatch interface that can reference either an MSMQQueue object instance or an MSMQDestination object instance.
Transaction: A pointer to a VARIANT that contains either:
A VT_DISPATCH or a VT_DISPATCH | VT_BYREF that points to an MSMQTransaction object.
A VT_I4 that references one of the following enumeration values as defined in section 2.2.2.1.
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 DestinationQueue input parameter is NULL:
Return E_INVALIDARG (0x80000003), and take no further action.
If either Message.Class OR Message.SenderIdentifier OR Message.SymmetricKey OR Message.Signature OR Message.AuthenticationProviderName properties of the represented Message were set after this object was initialized AND the represented Message.ConnectorTypeIdentifier equals the NULL GUID ({00000000-0000-0000-0000-000000000000}):
Return MQ_ERROR_MISSING_CONNECTOR_TYPE (0xC00E0055), and take no further action.
If (the represented Message.AuthenticationProviderType is not NULL AND the represented Message.AuthenticationProviderName is NULL) OR (the represented Message.AuthenticationProviderType is NULL AND the represented Message.AuthenticationProviderName is not NULL):
Return MQ_ERROR_INSUFFICIENT_PROPERTIES (0xC00E003F), and take no further action.
Define transactionalSend as a Boolean value set to False.
If the Transaction input parameter is NOT NULL:
If the Transaction input parameter is VT_DISPATCH or VT_DISPATCH | VT_BYREF:
Define transactionIdentifier as the value of the TransactionIdentifier instance variable of the ITransaction object obtained by the MSMQTransaction::get_ITransaction method on the MSMQTransaction object obtained from the Transaction input parameter.
Set transactionalSend to True.
Else, if the Transaction input parameter is VT_I4:
If the numeric value represented by the Transaction input parameter equals either MQ_MTS_TRANSACTION (0x00000001) or MQ_XA_TRANSACTION (0x00000002):
Define and retrieve transactionIdentifier as described in section 2.2.2.1, using the enum numeric value represented by the Transaction input parameter.
Set transactionalSend to True.
Else:
Return an error HRESULT, and take no further action.
If transactionalSend is True:
Identify the Transaction of the local QueueManager.TransactionCollection where the Transaction.Identifier equals the value of transactionIdentifier.
If a Transaction cannot be located:
Generate a Create Transaction event with the following inputs:
iTransactionIdentifier = transactionIdentifier
If the represented Message.SenderIdentifier equals NULL:
If the SenderIdentifierCache instance variable equals NULL:
Set the represented Message.SenderIdentifier to the SID of the caller.<151>
Else:
Set the represented Message.SenderIdentifier to the value of the SenderIdentifierCache instance variable.
If the represented Message.SenderCertificate equals NULL:
If the SenderCertificateCache instance variable is NOT NULL:
Set the represented Message.SenderCertificate to the value of the SenderCertificateCache.
Else:
Set the represented Message.SenderCertificate to the Certificate ADM attribute of the InternalCertificate ([MS-MQDMPR] section 3.1.1.19) ADM element instance from the InternalCertificateCollection ADM attribute of the local QueueManager ADM element instance whose InternalCertificate.User ADM attribute matches the user identified by the represented Message.SenderIdentifier.
Else:
If the SenderCertificateCache instance variable equals NULL OR the certificate in the SenderCertificateCache does not match the Message.SenderCertificate:
The server MAY impose additional requirements on the represented Message.SenderCertificate for authentication purposes.<152>
Set the represented Message.SourceMachineIdentifier to the local QueueManager.Identifier.
If the represented Message.ConnectorTypeIdentifier equals the NULL GUID ({00000000-0000-0000-0000-000000000000}):
Set the represented Message.Class to MQMSG_CLASS_NORMAL (0x00000000).
Set the represented Message.Identifier to a new and unique value as specified by [MS-MQMQ] section 2.2.8.
Define queueFormatName as follows:
If the DestinationQueue input parameter represents an MSMQQueue object:
Set queueFormatName to the result of calling MSMQQueueInfo::get_FormatName on the MSMQQueueInfo object returned as a result of calling the MSMQQueue::get_QueueInfo method on the MSMQQueue object represented by the DestinationQueue input parameter.
If the DestinationQueue input parameter represents an MSMQDestination object:
Set queueFormatName to the result of calling the MSMQDestination::get_FormatName method on the MSMQDestination object represented by the DestinationQueue input parameter.
Set the represented Message.DestinationQueueFormatName to queueFormatName.
Set the represented Message.SentTime to the current time.
If the represented Message.TimeToReachQueue is greater than Message.TimeToBeReceived:
Set the represented Message.TimeToBeReceived to the same value as Message.TimeToReachQueue.
If the represented Message.Signature equals NULL:
If the RequestedAuthenticationLevel instance variable is NOT equal to MQMSG_AUTH_LEVEL_NONE (0x00000000):
Calculate the hash value using the specified represented Message.HashAlgorithm and in the manner identified by the RequestedAuthenticationLevel instance variable.
Obtain the private key for the certificate contained in the represented Message.SenderCertificate.
Set the represented Message.Signature to the signature calculated using the specified Message.AuthenticationProviderType and Message.SenderCertificate and the obtained private key applied to the calculated hash value.
Set the represented Message.AuthenticationLevel to the associated value from the RequestedAuthenticationLevel instance variable. Refer to section 2.2.2.16 for details of the translation.
If the SOAPBody instance variable is NOT NULL:
Append the SOAPBody instance variable value to the end of the represented Message.SoapBody.
If the SOAPHeader instance variable is NOT NULL:
Append the SOAPHeader instance variable value to the end of the represented Message.SoapHeader.
Define targetQueue as an OpenQueueDescriptor and set it as follows:
If the DestinationQueue input parameter represents an MSMQQueue object:
Set targetQueue to the value of the OpenQueueDescriptor instance variable of the MSMQQueue object represented by the DestinationQueue input parameter.
If the DestinationQueue input parameter represents an MSMQDestination object:
Set targetQueue to the value of the DestinationOpenQueueDescriptor instance variable of the MSMQDestination object represented by the DestinationQueue input.
Generate an Enqueue Message to an Open Queue event ([MS-MQDMPR] section 3.1.7.1.27) with the following inputs:
iOpenQueueDescriptor = targetQueue
iMessage = The represented Message
iTransaction = The identified Transaction
If the rStatus return value is not equal to MQ_OK (0x00000000):
Return an error HRESULT, and take no further action.