3.1.4.11 RemoteQMStartReceiveByLookupId (Opnum 10)

The RemoteQMStartReceiveByLookupId method reads a message from the opened remote queue by using the lookup identifier.<27>

 HRESULT RemoteQMStartReceiveByLookupId(
   [in] handle_t hBind,
   [in] ULONGLONG LookupId,
   [out] PCTX_REMOTEREAD_HANDLE_TYPE* pphContext,
   [in, out] REMOTEREADDESC2* lpRemoteReadDesc2
 );

hBind: MUST be set to an RPC binding handle, as specified in [MS-RPCE] section 2.

LookupId: Lookup identifier of the message to be returned.

pphContext: The server MUST return a non-NULL value for this handle, on success for receive calls. This handle is used by the client in subsequent calls to RemoteQMEndReceive. This handle MUST NOT be set on failure, or for peek calls. If this method returns an error, pphContext is undefined and MUST NOT be used as an argument for a call to RemoteQMEndReceive.

lpRemoteReadDesc2: A REMOTEREADDESC2 (section 2.2.2.2) instance that contains the remote description accompanied by a sequential ID. The members of the pRemoteReadDesc member of the lpRemoteReadDesc2 parameter MUST be assigned in the same manner as that specified in RemoteQMStartReceive and section 2.2.2.1. In addition, the SequentialId member MUST be set to the least significant 7 bytes of the Message.LookupIdentifier ([MS-MQDMPR] section 3.1.1.12) of the message that is returned by this method.

The client must provide all parameters of lpRemoteReadDesc2.pRemoteReadDesc that are marked as to be set by the client in section 2.2.2.1.

lpRemoteReadDesc2.pRemoteReadDesc.ulAction MUST be set to one of the following values.

Value of ulAction

Meaning

MQ_LOOKUP_PEEK_CURRENT

0x40000010

Read the message that is specified by the LookupId parameter, but do not remove it from the queue.

The lpRemoteReadDesc2.pRemoteReadDesc.hCursor parameter MUST be set to zero.

The LookupId parameter MUST NOT be set to 0.

The lpRemoteReadDesc2.pRemoteReadDesc.ulTimeout parameter MUST be set to 0x00000000.

MQ_LOOKUP_PEEK_NEXT

0x40000011

If LookupId is 0, read the first message. Otherwise, read the message following the message that is specified by LookupId. In either case, do not remove the message.

The lpRemoteReadDesc2.pRemoteReadDesc.hCursor parameter MUST be set to zero.

The lpRemoteReadDesc2.pRemoteReadDesc.ulTimeout parameter MUST be set to 0x00000000.

MQ_LOOKUP_PEEK_PREV

0x40000012

If LookupId is 0xFFFFFFFFFFFFFFFF, read the last message. Otherwise, read the message preceding the message that is specified by the LookupId parameter. In either case, do not remove the message from the queue.

The lpRemoteReadDesc2.pRemoteReadDesc.hCursor parameter MUST be set to zero.

The LookupId parameter MUST NOT be set to 0.

The lpRemoteReadDesc2.pRemoteReadDesc.ulTimeout parameter MUST be set to 0x00000000.

MQ_LOOKUP_RECEIVE_CURRENT

0x40000020

Read the message that is specified by the LookupId parameter, and remove it from the queue.

The lpRemoteReadDesc2.pRemoteReadDesc.hCursor parameter MUST be set to zero.

The LookupId parameter MUST NOT be set to 0.

The lpRemoteReadDesc2.pRemoteReadDesc.ulTimeout parameter MUST be set to 0x00000000.

MQ_LOOKUP_RECEIVE_NEXT

0x40000021

If LookupId is 0, read the first message. Otherwise, read the message following the message that is specified by the LookupId parameter. Remove the message from the queue.

The lpRemoteReadDesc2.pRemoteReadDesc.hCursor parameter MUST be set to zero.

The lpRemoteReadDesc2.pRemoteReadDesc.ulTimeout parameter MUST be set to 0x00000000.

MQ_LOOKUP_RECEIVE_PREV

0x40000022

If LookupId is 0xFFFFFFFFFFFFFFFF, read the last message. Otherwise, read the message preceding the message that is specified by the LookupId parameter. Remove the message from the queue.

The lpRemoteReadDesc2.pRemoteReadDesc.hCursor parameter MUST be set to zero.

The LookupId parameter MUST NOT be set to 0.

The lpRemoteReadDesc2.pRemoteReadDesc.ulTimeout parameter MUST be set to 0x00000000.

Return Values: The method MUST return MQ_OK (0x00000000) on success; otherwise, it MUST return a failure HRESULT and the client MUST treat all failure HRESULTs identically.

MQ_OK (0x00000000)

MQ_ERROR_INVALID_HANDLE (0xC00E0007)

MQ_ERROR_INVALID_PARAMETER (0xC00E0006)

MQ_ERROR_IO_TIMEOUT ((0xC00E001B))

MQ_ERROR_MESSAGE_ALREADY_RECEIVED ((0xC00E001D))

Exceptions Thrown: No exceptions are thrown except those thrown by the underlying RPC protocol, as specified in [MS-RPCE].

While processing this method, the server MUST:

  • Return MQ_ERROR_INVALID_HANDLE (0xC00E0007) if lpRemoteReadDesc2 is NULL.

  • Return MQ_ERROR_INVALID_PARAMETER (0xC00E0006) if:

    • lpRemoteReadDesc2.pRemoteReadDesc.hRemoteQueue is set to 0.

    • lpRemoteReadDesc2.pRemoteReadDesc.ulTimeout is not set to 0.

    • lpRemoteReadDesc2.pRemoteReadDesc.hCursor is not set to 0.

  • Search the rOpenQueueEntryCollection where OpenQueueEntry.OpenQueueDescriptorHandle= lpRemoteReadDesc2.pRemoteReadDesc.hRemoteQueue.

  • If the OpenQueueDescriptorHandle is not found, return MQ_ERROR_INVALID_PARAMETER (0xC00E0006).

  • For each queue present in the QueueManager.QueueCollection:

    • For each OpenQueueDescriptor in Queue.OpenQueueDescriptorCollection:

      • If OpenQueueDescriptor.Handle= lpRemoteReadDesc2.pRemoteReadDesc.hRemoteQueue, use that OpenQueueDescriptor for processing.

  • Create a new RemoteReadEntry, referred to as rrEntry, with the following attributes:

    • OpenQueueDescriptorHandle= lpRemoteReadDesc2.lpRemoteReadDesc.hRemoteQueue

    • Timeout= lpRemoteReadDesc2.pRemoteReadDesc.ulTimeout

    • UserMessagePacket= lpRemoteReadDesc2.pRemoteReadDesc.lpBuffer

    • Action= lpRemoteReadDesc2.pRemoteReadDesc.ulAction

    • RequestId= lpRemoteReadDesc2.pRemoteReadDesc.dwRequestID

  • Add rrEntry to rRemoteReadEntryCollection.

  • Generate a Read Message By Lookup Identifier event with the following inputs ('*' is used as a wildcard for possible symbolic names of lpRemoteReadDesc2.pRemoteReadDesc.ulAction as specified in the preceding Value of ulAction table):

    • iQueueDesc:=QueueReference member of the OpenQueueDescriptor obtained earlier

    • iLookupId:= LookupId

    • iPeekOperation:= true if the value for lpRemoteReadDesc2.pRemoteReadDesc.ulAction is MQ_LOOKUP_PEEK_*; otherwise, false

    • iLookupOperation:=

      • SeekFirst, if lpRemoteReadDesc2.pRemoteReadDesc.ulAction is MQ_LOOKUP_*_NEXT, and LookupId is 0.

      • SeekLast, if lpRemoteReadDesc2.pRemoteReadDesc.ulAction is MQ_LOOKUP_*_PREV, and LookupId is 0xFFFFFFFFFFFFFFFF.

      • SeekPrevious, if lpRemoteReadDesc2.pRemoteReadDesc.ulAction is MQ_LOOKUP_*_PREV, and LookupId does not equal 0xFFFFFFFFFFFFFFFF.

      • SeekCurrent, if lpRemoteReadDesc2.pRemoteReadDesc.ulAction is MQ_LOOKUP_*_CURRENT.

      • SeekNext, if lpRemoteReadDesc2.pRemoteReadDesc.ulAction is MQ_LOOKUP_*_NEXT, and LookupId does not equal 0.

  • If the rStatus value returned from the Read Message By Lookup Identifier event is MQ_OK (0x00000000), the server MUST process the returned rMessage as follows:

    • Generate a Construct a UserMessage Packet ([MS-MQDMPR] section 3.1.7.1.30) event with the following argument:

      • iMessage := rMessage

    • Generate a Serialize Message to Buffer ([MS-MQDMPR] section 3.1.7.1.32) event with the following arguments:

      • iMessage := rMessage

      • iBuffer := rUserMessage returned by the  Construct a UserMessage Packet event.

    • Assign rUserMessage to lpRemoteReadDesc2.pRemoteReadDesc.lpBuffer.

    • Assign rUserMessage.BaseHeader.PacketSize to lpRemoteReadDesc2.pRemoteReadDesc.dwSize.

    • Assign the least significant 7 bytes of rMessage.LookupIdentifier to the SequentialId member of lpRemoteReadDesc2.

  • Remove the RemoteReadEntry ADM element instance from rRemoteReadEntryCollection for which RemoteReadEntry.RequestId equals lpRemoteReadDesc2.pRemoteReadDesc.dwRequestID and RemoteReadEntry.OpenQueueDescriptorHandle equals lpRemoteReadDesc2.pRemoteReadDesc.hRemoteQueue.

  • If rStatus is MQ_OK (0x00000000) and lpRemoteReadDesc2.pRemoteReadDesc.ulAction is MQ_LOOKUP_RECEIVE_*, set pphContext to rrEntry; otherwise, delete rrEntry.

  • Return rStatus.