3.1.4.17 rpc_QMOpenQueueInternal (Opnum 19)

A client calls rpc_QMOpenQueueInternal to obtain a local queue context handle, to determine if a queue is located at a remote queue manager (section 4.2), or to obtain a local context handle for an opened remote queue. If the call to RemoteQMOpenQueue ([MS-MQQP] section 3.1.4.3) fails, the result MUST be returned to the client, and the remote open queue sequence is discontinued. In the case of failure, any state changes need to be rolled back.

 HRESULT rpc_QMOpenQueueInternal(
   [in] handle_t hBind,
   [in] QUEUE_FORMAT* pQueueFormat,
   [in] DWORD dwDesiredAccess,
   [in] DWORD dwShareMode,
   [in] DWORD hRemoteQueue,
   [in, out, ptr, string] WCHAR** lplpRemoteQueueName,
   [in] DWORD* dwpQueue,
   [in] GUID* pLicGuid,
   [in, string] WCHAR* lpClientName,
   [out] DWORD* pdwQMContext,
   [out] RPC_QUEUE_HANDLE* phQueue,
   [in] DWORD dwRemoteProtocol,
   [in] DWORD dwpRemoteContext
 );

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

pQueueFormat: MUST be a pointer to a QUEUE_FORMAT ([MS-MQMQ] section 2.2.7) structure, which identifies an existing queue to be opened. MUST NOT be NULL and MUST conform to the format name syntax rules defined in [MS-MQMQ].

dwDesiredAccess: A DWORD that specifies the access mode requested for the queue. The access mode defines the set of operations which can be invoked using the returned queue handle. The value MUST be one of the following:

Value

Meaning

MQ_RECEIVE_ACCESS

0x00000001

The server MUST permit only the following operations using the returned queue handle:

  • Message peek

  • Message receive (peek and delete)

  • Queue purge

MQ_SEND_ACCESS

0x00000002

The server MUST permit only message send operations using the returned queue handle.

MQ_PEEK_ACCESS

0x00000020

The server MUST permit only message peek operations using the returned queue handle.

MQ_RECEIVE_ACCESS|MQ_ADMIN_ACCESS

0x00000081

The returned queue handle MUST perform operations on the outgoing queue associated with the queue identified by pQueueFormat. Additionally, the server MUST permit only the following operations using the returned queue handle:

  • Message peek

  • Message receive (peek and delete)

  • Queue purge

MQ_PEEK_ACCESS|MQ_ADMIN_ACCESS

0x000000a0

The returned queue handle MUST perform operations on the outgoing queue associated with the queue identified by pQueueFormat. Additionally, the server MUST permit only message peek operations using the returned queue handle.

If pQueueFormat contains an HTTP or multicast format name, R_QMOpenRemoteQueue (section 3.1.4.2) MUST be MQ_SEND_ACCESS (0x00000002).

If pQueueFormat identifies a sub-queue, dwDesiredAccess MUST NOT be MQ_SEND_ACCESS (0x00000002).

If pQueueFormat identifies a system, journal, machine, or connector queue, dwDesiredAccess MUST be MQ_RECEIVE_ACCESS (0x00000001) or MQ_PEEK_ACCESS (0x00000020).

If pQueueFormat identifies a remote queue, dwDesiredAccess MUST be MQ_RECEIVE_ACCESS (0x00000001) or MQ_PEEK_ACCESS (0x00000020).

dwShareMode:  Specifies the exclusivity level for the opened queue. The value MUST be one of the following:

Value

Meaning

MQ_DENY_NONE

0x00000000

The queue is not opened exclusively.

MQ_DENY_RECEIVE_SHARE

0x00000001

The queue is opened for exclusive read access. If the queue has already been opened for read access, the server MUST return a failure HRESULT. If the queue is opened successfully for exclusive read access, subsequent attempts to open the same queue for read access MUST return a failure HRESULT until the queue has been closed.

If dwDesiredAccess is MQ_SEND_ACCESS (0x00000002), dwShareMode MUST be MQ_DENY_NONE (0x00000000).

hRemoteQueue: MUST be 0x00000000, or MUST contain a DWORD value obtained from the phQueue out-parameter of the R_QMOpenRemoteQueue method invoked at a remote queue manager.

lplpRemoteQueueName:  On input, the server MUST ignore lplpRemoteQueueName. If hRemoteQueue is 0x00000000 and the queue identified by pQueueFormat is located at a remote queue manager, the server MUST set this string to a null-terminated path name, from which the client can determine the computer name of the remote queue manager, as specified in [MS-MQMQ] section 2.1.1.

If pQueueFormat identifies a queue local to the supporting server, the server MUST set lplpRemoteQueueName to NULL.

dwpQueue: If hRemoteQueue is 0x00000000, dwpQueue MUST be NULL; otherwise, dwpQueue MUST contain a DWORD value obtained from the dwpQueue out-parameter of the R_QMOpenRemoteQueue method invoked at a remote queue manager.

pLicGuid:  MUST be a pointer to a valid GUID which uniquely identifies the client.<45><46> The server MAY ignore this parameter.<47>

lpClientName:  MUST be a null-terminated string containing the client's computer name.<48> Servers MAY use this parameter in concert with the pLicGuid parameter to implement limits on the number of unique clients which can open queue handles.<49> Implementing connection limits is optional and not recommended.

pdwQMContext: A pointer to a variable to receive a DWORD value that identifies either an OpenQueueDescriptor ([MS-MQDMPR] section 3.1.1.16) ADM element instance at the server or a RemoteQueueProxyHandle (section 3.1.1.5) ADM element instance that contains information pertaining to an OpenQueueDescriptor ADM element instance at a remote server. When the client calls rpc_ACReceiveMessageEx (section 3.1.5.3), it specifies a queue by providing the value that is returned by this parameter. On return, the client MUST ignore pdwQMContext if the value returned via lplpRemoteQueueName is non-NULL.

phQueue:  A pointer to a variable to receive a new RPC_QUEUE_HANDLE (section 2.2.1.1.2) context handle. On return, the client MUST ignore phQueue if the value returned via lplpRemoteQueueName is non-NULL.

dwRemoteProtocol: Clients MUST set this parameter to 0x00000000. Servers SHOULD ignore this parameter.<50>

Value

Meaning

0x00000000

The TCP/IP protocol sequence is to be used.

0x00000003

The IPX/SPX protocol sequence is to be used.

dwpRemoteContext: If hRemoteQueue is 0x00000000, dwpRemoteContext MUST contain 0x000000000; otherwise, dwpRemoteContext MUST contain a DWORD value obtained from the pdwContext out-parameter of the R_QMOpenRemoteQueue (section 3.1.4.2) method invoked at a remote queue manager.

Return Values:  On success, this method MUST return MQ_OK (0x00000000); otherwise, if an error occurs, the server MUST return a failure HRESULT,<51> and the client MUST treat all failure HRESULTs identically. Additionally, if a failure HRESULT is returned, the client MUST disregard all out-parameter values.

Exceptions Thrown: In addition to the exceptions thrown by the underlying RPC protocol, as specified in [MS-RPCE], the method can throw HRESULT failure codes as RPC exceptions. The client MUST treat all thrown HRESULT codes identically. Additionally, the client MUST disregard all out-parameter values when any failure HRESULT is thrown.

This method is invoked at the dynamically assigned endpoint returned by the R_QMGetRTQMServerPort (section 3.1.4.24) method when IP_HANDSHAKE (0x00000000) or IPX_HANDSHAKE (0x00000002) is the interface specified by the fIP parameter.

When processing this call, the server MUST do the following:

  • Determine if input parameter values violate constraints specified above. If an invalid parameter is detected, the server MUST take no further action and return a failure HRESULT.

  • If hRemoteQueue is nonzero:

    • By providing a nonzero value for hRemoteQueue, the client indicates that it has successfully obtained a PCTX_OPENREMOTE_HANDLE_TYPE (section 2.2.1.1.3) by invoking R_QMOpenRemoteQueue (section 3.1.4.2) at a remote server. In response, this server attempts to contact the remote server to validate the provided handle, and to return a new RPC_QUEUE_HANDLE to the client.

    • Raise a Get Queue Path ([MS-MQDMPR] section 3.1.7.1.26) event with the input argument iFormatName set to pQueueFormat. If the rStatus returned by the event is not MQ_OK (0x00000000) or the rPathName return argument is empty, take no further action and return a failure HRESULT; otherwise, set remoteServer to the rMachineName return argument value.

    • Declare the iPathName variable and set its value to the rPathName return argument value obtained from the Get Queue Path event.

    • Invoke the MSMQ: Queue Manager to Queue Manager Protocol to open the queue, as specified in [MS-MQQP] section 3.2.4.1, and provide the following inputs:

      • RemoteServer set to remoteServer

      • QueueHandle set to hRemoteQueue

      • QueueDescriptor set to dwpQueue

      • OpenContext set to the value pointed to by dwpRemoteContext

        If the method is unsuccessful for any reason, including transport failures, errors raised by [MS-MQQP], timeouts, and unbind, take no further action, and return a failure HRESULT.

    • Declare iNewRemoteQueueProxyHandle as a RemoteQueueProxyHandle ADM element instance and set its attributes to the following values:

      • Handle := New RPC_QUEUE_HANDLE context handle.

      • Context := A new DWORD value that uniquely identifies the RemoteQueueProxyHandle ADM element instance within iRemoteQueueProxyHandleTable.

      • RemoteHandle := The phContext out-parameter value received from RemoteQMOpenQueue.

      • RemoteBindingHandle := The binding handle established preceding.

      • RemoteContext := hRemoteQueue

      • FormatName := pQueueFormat

      • PathName := iPathName

    • Add iNewRemoteQueueProxyHandle to iRemoteQueueProxyHandleTable (section 3.1.1.4).

    • Set lplpRemoteQueueName to NULL.

    • Set phQueue to iNewRemoteQueueProxyHandle.Handle.

    • Set pdwQMContext to iNewRemoteQueueProxyHandle.Context.

    • Take no further action and return MQ_OK (0x00000000).

  • Else: hRemoteQueue is 0x00000000.

    • Generate an Open Queue ([MS-MQDMPR] section 3.1.7.1.5) event with the following argument values:

      • iFormatName := pQueueFormat

      • iRequiredAccess := dwDesiredAccess, according to the following values:

        • MQ_RECEIVE_ACCESS (0x00000001): ReceiveAccess

        • MQ_SEND_ACCESS (0x00000002): SendAccess

        • MQ_PEEK_ACCESS (0x00000020): PeekAccess

      • iSharedMode := dwShareMode, according to the following values:

        • MQ_DENY_NONE (0x00000000): DenyNone

        • MQ_DENY_RECEIVE_SHARE (0x00000001): DenyReceive

    • If the rStatus out-argument of the Open Queue event indicates success:

      • Add a new LocalQueueContextHandle (section 3.1.1.3) ADM element instance to the server's iLocalQueueContextHandleTable (section 3.1.1.2) with the following values:

        • Handle := New RPC_QUEUE_HANDLE context handle.

        • OpenQueueDescriptorReference := The rOpenQueueDescriptor out-argument of the Open Queue event.

      •  Set lplpRemoteQueueName to NULL.

      • Set phQueue to the iLocalQueueContextHandleTable.Handle.

      • Set pdwQMContext to rOpenQueueDescriptor.Handle.

      •  Take no further action and return MQ_OK (0x00000000).

    • Else, if rStatus indicates MQ_ERROR_QUEUE_NOT_FOUND, and dwDesiredAccess is not MQ_SEND_ACCESS (0x00000002):

      • Attempt to resolve the format name in pQueueFormat to a path name by raising a Get Queue Path event ([MS-MQDMPR] section 3.1.7.1.26) with the input argument iFormatName set to pQueueFormat.

      • If rStatus returned in the preceding step is not MQ_OK (0x00000000) or the rPathName return argument is empty, take no further action and return a failure HRESULT.

      • Set lplpRemoteQueueName to the resolved path name.

      • Set phQueue to NULL.

      •  Set pdwQMContext to zero (0x00000000).

      • Take no further action and return MQ_OK (0x00000000).

    • Else:

      • Return rStatus.