Message Queuing (MSMQ)

Purpose

Message Queuing (MSMQ) technology enables applications running at different times to communicate across heterogeneous networks and systems that may be temporarily offline. Applications send messages to queues and read messages from queues. The following illustration shows how a queue can hold the messages used by both sending and receiving applications.

Where Applicable

Message Queuing provides guaranteed message delivery, efficient routing, security, and priority-based messaging.

It can be used to implement solutions to both asynchronous and synchronous scenarios requiring high performance. The following list shows several places where Message Queuing can be used.

  • Mission-critical financial services: for example, electronic commerce

  • Embedded and hand-held applications: for example. underlying communications to and from embedded devices that route baggage through airports by means of an automatic baggage system.

  • Outside Sales: for example. sales automation applications for traveling sales representatives.

  • Workflow: Message Queuing makes it easy to create a workflow that updates each system. A typical design pattern is to implement an agent to interact with each system. Using a workflow-agent architecture also minimizes the impact of changes in one system on the other systems. With Message Queuing, the loose coupling between systems makes upgrading individual systems simpler.

Developer Audience

Message Queuing applications can be developed using C++ APIs or COM objects. Applications can be built in any of the popular development environments: for example, Microsoft® Visual Basic®, Visual Basic® Scripting Edition, Visual C++®, Visual J++®, Borland Delphi, and Powersoft Powerbuilder. This allows applications to be developed for the Internet as well, including both server-side (Internet Information Server) and client-side (Internet Explorer) applications.

Run-Time Requirements

MSMQ 1.0 can be deployed on computers running Windows NT® 4.0, Windows 95, and Windows 98.

MSMQ 2.0 can be deployed on computers running Microsoft® Windows® 2000.

In addition, with the MSMQ-MQSeries Bridge available from Microsoft System Network Architecture (SNA), Message Queuing can be used to communicate with IBM MQSeries systems.

What's New in Message Queuing

New features for each version of Message Queuing.

Further Information on Message Queuing

Sources of information on installation and administration and books on Message Queuing.

About Message Queuing

Message Queuing concepts and services.

Using Message Queuing

Examples using functions and COM components.

Message Queuing Reference

Message Queuing functions, properties, structures, and COM components.

Message Queuing Mail Reference

Message Queuing mail functions, properties, structures, and COM components.

Message Queuing Glossary

Technical terms used in the Message Queuing documentation.

Message Queuing Appendix

Supplementary information not covered in the body of the Message Queuing documentation.

Feedback

Make error reports and feature requests directly to Microsoft.

Microsoft Platform SDK, February 2001 Edition.
This content last built on Thursday, February 01, 2001.


What's New in Message Queuing

The following topics cover the new features added in different versions of Message Queuing. The new features for the latest version of Message Queuing are listed first.

For information on | See
Changes in Message Queuing 3.0, release with Whistler | New Features for Whistler
Changes in MSMQ 2.0, released with the Microsoft® Windows® 2000 operating system | New Features for Windows 2000


New Features for Whistler

The following features are introduced in Message Queuing 3.0, released with the Windows 2000 version 3.0.

  • Sending messages to multiple destinations

    Message Queuing 3.0 provides distribution list, multicast address, and multiple-element format name support for sending messages to multiple destinations. For more details, see Sending Messages to Multiple Destinations.

  • Specifying multiple administration and response queues

    Message Queuing 3.0 provides message properties for specifying more than one administration and response queue. For more details, see Administration Queues and Response Queues.

  • Retrieving or peeking at a specific message

    Message Queuing 3.0 provides functions and COM methods for reading a message based on its lookup identifier. For more details, see Message Lookup Identifier.

  • HTTP support

    Message Queuing 3.0 provides support for referencing queues by URLs. For more details, see HTTP Messages.

For new administrator features that effect the deployment of Message Queuing, see the Windows 2000 Help.


Sending Messages to Multiple Destinations

Beginning with Whistler, Message Queuing provides means for sending a message to multiple destination queues. This involves three new programming elements, distribution lists, multicast addresses, and multiple-element format names, to specify any number of destination queues for the message.

Distribution lists, multicast addresses, and multiple-element format names can be used to do the following:

  • Send transactional and non-transactional messages to multiple destinations.
  • Specify sets of administration queues for acknowledgment messages.
  • Specify sets of response queues for response messages.

The main difference between distribution lists and multiple-element format names is that distribution lists are public lists that are published in Microsoft® Active Directory™, and multiple-element format names are private lists that are created and maintained at the application level.

Distribution Lists

Distribution lists are Active Directory group objects that can contain references to public queues, queue aliases, and other distribution lists. The following programming considerations should be taken into account when you use distribution lists.

  • To create or maintain distribution lists, use the methods provided by the IADsGroup interface.
  • Distribution lists are referenced through the following distribution list format name. The distribution list identifier (GUID) is the value of the objectGUID property of the distribution list group in Active Directory.
    DL=DistListGUID
  • Distribution lists can contain explicit references to public queues, queue aliases, and other distribution lists.
  • Private queues can be referenced only through queue aliases.
  • HTTP queue names can be referenced only through queue aliases.
  • Distribution lists cannot be used in a workgroup environment or in off-line operations because there is no connection to Active Directory.
Distribution lists are group objects in Active Directory and are created and managed by means of the IADsGroup interface. Distribution lists may contain multiple references to the same destination . However, Message Queuing ignores duplicate references when it opens the destination s for sending messages. For example, if distribution list D1 explicitly specifies Q1 and another distribution list D2, it may be possible for distribution list D2 to also contain Q1 or D1. If this is the case, the second reference to Q1 or D1 is ignored.

Multiple-Element Format Names

Multiple-element format names are extensions of the single-element format names used to send one message to one destination queue. They are a concatenation of one or more public, private, direct, or distribution list format names (note that if a distribution list is included, the multiple-element format name cannot be used when there is no connection to Active Directory).

The following example shows a multiple-element format name that contains a direct format name, public format name, and distribution list format name.

Direct=Address\queuename,PUBLIC=QueueGUID,DL=dlGUID

Multiple-element format names cannot contain the format names of read-only queue, such as queue journals, computer journals, or dead-letter queues. An error is returned if the format name of a read-only queue is included in the multiple-element format name.

Unlike distribution lists, multiple-element format names are not stored in Active Directory and must be created and maintained by the application that is sending the messages.

Backwards Compatibility

To ensure backwards compatibility when using distribution lists or multiple-element format names, the source queue manager sets the explicit destination of the message and the distribution list or multiple-element used to send the message in each message packet that is sent.

For example, when a message is sent using a distribution list (D1) that references three queues (Q1, Q2, and Q3), the message packet sent to the three computer will contain the explicit destinations Q1, Q2, and Q3 respectively and the distribution list D1. If one of the computers is running MSMQ 2.0 or earlier, Message Queuing will use the explicit destination Q1, Q2, or Q3. If the computer is running MSMQ 3.0, Message Queuing will use D1. By providing the explicit destination and the distribution list, the sending application does not have to worry about what version of Message Queuing is running on the computer where the destination queues reside.

Queue Aliases

Queue aliases provide a way to indirectly reference private, public, direct, and distribution list format names within a distribution list. Using queue aliases provide the following benefits.

  • When a queue alias object is deleted, the alias is automatically removed from all distribution lists that reference the alias.
  • The queue referenced by the queue alias can be changed without having to change the distribution list.
  • Queue aliases can be used to reference a private queue in a distribution list.

Queue aliases are referenced by their ADs path, not by a format name such as queues or distribution lists. The following Visual Basic routine creates an InputQueue alias for the format name (qFormatName) passed to the routine (this example assumes that a myQueueAliases organizational unit (OU) exists in the domain).

Sub CreateAlias(qFormatName As String)
    Dim myContainer AS IADsContainer
    Set myContainer = GetObject("LDAP://OU=myQueueAliases,DC=myDomain,DC=COM")

    Dim qAlias As IADs
    Set qAlias = myContainer.Create("InputQueue", CN=myQueueAliases")
    qAlias.Put "InputQueue", qFormatName
    qAlias.SetInfo
End Sub

Using the alias created by the code above, the sending applications can send messages to the InputQueue alias without knowing what queue the messages are destined for. A second application could then monitor the input queues and change the format name in the alias when one input queue is full.

API Component Changes

The following functions and properties were modified or added to support distribution lists and multiple-element format names.

  • MQOpenQueue

    This function now accepts single-element format names (including a single distribution list format name) and multiple-element format names when opening queues with send access. If an attempt is made to open a multiple queues with peek or receive access, the function call returns an MQ_ERROR_UNSUPPORTED_FORMATNAME_OPERATION error code.

  • PROPID_M_ADMIN_FORMAT_NAME

    This property specifies one or more administration queues used for returned acknowledgment messages.

    PROPID_M_ADMIN_FORMAT_NAME supersedes PROPID_M_ADMIN_QUEUE.

  • PROPID_M_ADMIN_FORMAT_NAME_LEN

    This property indicates the length (in Unicode characters) of the format name string specified in PROPID_M_ADMIN_FORMAT_NAME.

  • PROPID_M_RESP_FORMAT_NAME

    This property specifies a set of response queues used for application generated response messages.

    PROPID_M_RESP_FORMAT_NAME supersedes PROPID_M_RESP_QUEUE.

  • PROPID_M_RESP_FORMAT_NAME_LEN

    This property indicates the length (in Unicode characters) of the format name string specified in PROPID_M_RESP_FORMAT_NAME.

  • PROPID_M_DEST_FORMAT_NAME

    This is a read only property that indicates the destination queues for messages sent with multiple-element format names or single-element format names (including a single distribution list format name).

    PROPID_M_DEST_FORMAT_NAME and PROPID_M_DEST_QUEUE are used together to specify multiple destinations and a specific destination respectively.

  • PROPID_M_DEST_FORMAT_NAME_LEN

    This property indicates the length (in Unicode characters) of the format name string specified in PROPID_M_DEST_FORMAT_NAME.

COM Component Changes

The following methods, and properties have been modified or added to support distribution lists and multiple-element format names.

  • MSMQMessage.AdminDestination

    This property specifies a set of administration queues using distribution lists or multiple-element format names.

  • MSMQMessage.ResponseDestination

    This property specifies a set of response queues using distribution lists or multiple-element format names.

  • MSMQMessage.Destination

    This read-only property specifies the set of destination queues using distribution lists or multiple-element format names.

  • MSMQDestination object

    This new object provides multicast support for sending messages. The methods and properties of this object include:

    • MSMQDestination.Open

      A method that explicitly opens the MSMQDestination object for sending messages

    • MSMQDestination.Close

      A method that explicitly closes the MSMQDestination object for sending messages

    • MSMQDestination.ADsPath

      A read/write property that specifies the ADs path to a distribution list, public queue, or queue alias object stored in Active Directory. Setting this property initializes the MSMQDestination object for sending messages.

    • MSMQDestination.FormatName

      A read/write property that specifies one or more format names for sending messages using a multiple-element format name. Setting this property initializes the MSMQDestination object for sending messages.

    • MSMQDestination.PathName

      A read/write property that specifies the pathname to a distribution list, public queue, or queue alias object stored in Active Director. Setting this property initializes the MSMQDestination object for sending messages.

    • MSMQDestination.IsOpen

      A read-only property that indicates if the destination object is open for sending messages or closed.


Message Lookup Identifier

Message Queuing 3.0 provides a way to peek at or retrieve a specific message without navigating through the queue to find the message. This functionality is based on a 64-bit lookup identifier that is assigned to the message when the message is placed in the queue. The local queue manager generates the lookup identifier and sets the lookup identifier property of the message (PROPID_M_LOOKUPID or MSMQMessage.LookupId) whenever it places a message in a queue. Message Queuing generates a lookup identifier for messages placed in application-generated queues such as destination queues, administration, response, and report queues, as well as copies of messages placed in system-generated journals, dead-letter, and connector queues.

API Function and Property Changes

The following API functions and properties were added to support reading messages by the lookup identifier of the message.

  • MQReceiveMessageByLookupId: This function synchronously peeks at or retrieves a specific message based on the PROPID_M_LOOKUPID property of the message.
  • PROPID_M_LOOKUPID: A read-only message property that indicates the lookup identifier of the message. The lookup identifier is a 64-bit number (unique to the queue) that is set by the local queue manager when the message is placed in the queue.

COM Component changes

The following methods, and properties were added to support reading messages by the lookup identifier of the message.

  • MSMQQueue.PeekFirstByLookupId: This method synchronously peeks at the first message in the queue.
  • MSMQQueue.PeekPreviousByLookupId: This method synchronously peeks at the message preceding the message specified by the supplied message identifier.
  • MSMQQueue.PeekByLookupId: This method synchronously peeks at the message specified by the supplied message identifier.
  • MSMQQueue.PeekNextByLookupId: This method synchronously peeks at the message immediately following the message specified by the supplied message identifier.
  • MSMQQueue.PeekLastByLookupId: This method synchronously peeks at the last message in the queue.
  • MSMQQueue.ReceiveFirstByLookupId: This method synchronously retrieves the first message in the queue.
  • MSMQQueue.ReceivePreviousByLookupId: This method synchronously retrieves the message preceding the message specified by the supplied message identifier.
  • MSMQQueue.ReceiveByLookupId: This method synchronously retrieves the message specified by the supplied message identifier.
  • MSMQQueue.ReceiveNextByLookupId: This method synchronously retrieves the message immediately following the message specified by the supplied message identifier.
  • MSMQQueue.ReceiveLastByLookupId: This method synchronously retrieves the last message in the queue.
  • MSMQMessage.LookupId: A read-only message property that indicates the lookup identifier of the message. The lookup identifier is a 64-bit number (unique to the queue) that is set by the local queue manager when it places the message in the queue.


HTTP Messages

Message Queuing 3.0 provides HTTP support for referencing queues, formatting messages, and HTTP message authentication.

In opening queues, direct format names can include the URL to the queue. The following two format names reference a queue that resides on a computer that is running Message Queuing. The difference between these two examples is that the second format name invokes HTTP security by using "HTTPS".

DIRECT=HTTP://URLAddressSpecification\msmq\myPublicQueue
DIRECT=HTTPS://URLAddressSpecification\msmq\myPublicQueue

HTTP format names can use forward slashes, "/", or back slashes, "\", to separate Message Queuing information (other format names require back slashes to separate information). For example, the following two format names can be used to reference "myPublicQueue".

DIRECT=HTTP://URLAddressSpecification/msmq/myPublicQueue
DIRECT=HTTP://URLAddressSpecification\msmq\myPublicQueue


New Features for Windows 2000

The following features are introduced in Message Queuing 2.0, released with the Windows 2000 version 5.0.

Note For new administrator features that effect the deployment of Message Queuing, see the Microsoft Windows 2000 online help.

  • New directory service
  • DNS pathname support
  • Registering certificates programmatically
  • New digital signatures for authenticating messages
  • 128-bit encryption support
  • Transaction boundary support
  • Private computer properties
  • COM component support for all message properties
  • Improved COM Transaction Support
  • COM support for retrieving the machine name for a computer
  • Multi-threaded apartment (MTA) support for COM components
  • Asynchronous receives inside Internet Explorer
  • Create and Modify times for private queues

New Directory Service

Message Queuing now supports two directory services: MSMQ information store (MQIS) and Microsoft® Active Directory™. Active Directory replaced MQIS with the release of MSMQ 2.0, allowing Message Queuing to be fully integrated with Windows 2000. Using Active Directory as the directory services allows your Message Queuing enterprise to automatically encompass all your Windows 2000 domains. To access Active Directory, you must have MSMQ 2.0 running on at least one domain controller, referred to as the as the MSMQ DS server, in each Windows 2000 domain. When operating in an MSMQ 2.0 enterprise, the boundaries of the Message Queuing enterprise are now the boundaries of the Windows 2000 forest.

DNS Pathname Support

You can now specify a full domain name service (DNS) pathname when you create a queue, and you can also retrieve the DNS pathname of an existing queue or computer. This change effects the existing queue pathname property used to create the queue and, and it requires two new read-only properties, one for the DNS path name of the queue and one for the DNS path name of the computer.

When you create a queue, the queue pathname property can now except NetBIOS and full DNS pathnames.

To retrieve the DNS pathname of a queue or computer, you can look at one of the two read-only DNS pathname properties, the one for queues or the one for computers. In both cases, the DNS pathname returned is generated at the time of the call. DNS pathnames are not stored in the directory service.

For information on this these properties see:

  • PROPID_Q_PATHNAME
  • MSMQQueueInfo.PathName
  • PROPID_Q_PATHNAME_DNS
  • MSMQQueueInfo.PathNameDNS
  • PROPID_QM_PATHNAME_DNS

Registering Certificates Programmatically

Message Queuing now allows you to register internal and external certificates form within Message Queuing applications. Certificates are registered in the directory service, and consequently this new functionality cannot be used when operating in a workgroup environment.

Note For MSMQ 1.0 applications, certificates must be registered manually by using MS Message Queue in the Control Panel.

For more information, see the following:

  • Registering a certificate
  • MQRegisterCertificate
  • MSMQApplication.RegisterCertificate

New Digital Signatures for Authenticating Messages

Message Queuing uses two different types of signatures to authenticate messages. When requesting authentication, you can now specify which signature you want to use.

For more information, see the following:

  • Message Authentication
  • PROPID_M_AUTH_LEVEL
  • PROPID_M_AUTHENTICATED_EX
  • MSMQMessage.AuthLevel
  • MSMQMessage.ReceivedAuthenticationLevel

128-Bit Encryption Support

Message Queuing now provides 128-bit and 40-bit encryption for sending private messages. When requesting encryption, you can now specify which type of encryption you want to use.

For more information, see the following:

  • Message Encryption
  • PROPID_M_PRIV_LEVEL
  • PROPID_QM_ENCRYPTION_PK_BASE
  • PROPID_QM_ENCRYPTION_PK_ENHANCED
  • MSMQMessage.PrivLevel

Transaction Boundary Support

Message Queuing now provides three new read-only message properties for checking the boundaries of a transaction. These properties are set by Message Queuing and can be used to identify which transaction a message belongs to and if the message is the first or last message in the transaction. For more information, see

  • Checking for Transaction Boundaries when Receiving Messages
  • PROPID_M_XACTID
  • PROPID_M_FIRST_IN_XACT
  • PROPID_M_LAST_IN_XACT
  • MSMQMessage.IsLastInTransaction
  • MSMQMessage.IsFirstInTransaction
  • MSMQMessage.TransactionId

Private Computer Properties

Message queuing now provides private computer properties for the local computer. These private computer properties can be used to determine if Message Queuing is connected to Active Directory and what version of Message Queuing is running.

For more information, see the following:

  • MQGetPrivateComputerInformation
  • PROPID_PC_VERSION
  • PROPID_PC_DS_ENABLED
  • MSMQApplication.MSMQVersionBuild
  • MSMQApplication.MSMQVersionMajor
  • MSMQApplication.MSMQVersionMinor
  • MSMQApplication.MSMQVersionMinor

COM Component Support for All Message Properties

Message Queuing COM components now supports all the same message properties as the function-call API, allowing you to now test transaction boundaries when reading messages, send application-encrypted messages, manage application authenticated messages, and write connector applications for communicating with foreign queues.

The following properties were added to the MSMQMessage object.

  • MSMQMessage.AuthenticationProviderName
  • MSMQMessage.AuthenticationProviderType
  • MSMQMessage.ConnectorTypeGuid
  • MSMQMessage.DestinationSymmetricKey
  • MSMQMessage.Extension
  • MSMQMessage.IsFirstInTransaction
  • MSMQMessage.IsLastInTransaction
  • MSMQMessage.MsgClass
  • MSMQMessage.ReceivedAuthenticationLevel
  • MSMQMessage.Signature
  • MSMQMessage.SenderVersion
  • MSMQMessage.TransactionId
  • MSMQMessage.TransactionStatusQueueInfo

Improved COM Transaction Support

Message Queuing now allows you to attach to an external transaction using MSMQTransaction.InitNew.

Message Queuing provides improved Microsoft Transaction Server (MTS) (COM+) transaction support.

  • Message Queuing queues and messages no longer have to be created inside the MTS component in order to participate in the component's transaction. In MSMQ 2.0, queues and message COM objects can be created outside the MTS component and passed in as parameters. In MSMQ 1.0, the Message Queuing COM objects work correctly only when they are created inside the MTS component and when the MTS component is apartment threaded.
  • When you send or retrieve messages, the send and receive methods are always called within the transaction context of the caller. In MSMQ 1.0, the send and receive methods are called in the context of the creator of the object.

COM Support for Retrieving the Machine Name for a Computer

Message Queuing now provides a COM method that can be called to retrieve the name of a specific computer.

For information, see the following:

  • MSMQApplication.MachineNameOfMachineId

Multi-Threaded Apartment (MTA) Support for COM Components

Message Queuing provides better support for applications that initialize their threads in a COM multi-threaded apartment (MTA).

Note For information on COM apartment models, see COM+ Apartment Models.

  • Message Queuing has improved the performance of its COM objects by using MTA. This allows Message Queuing to execute object methods on the caller's thread. For MSMQ 1.0, Message Queuing executes methods only on the creator's thread. There is a thread switch from MTA to STA, causing a bottleneck in COM's STA. In MSMQ 1.0, STA served all MSMQ COM objects.
  • Message Queuing has now reduced call blocking. Because method are executed on the caller's thread, any blocking call (such as a receive call with a long time) will block only the caller's thread. For MSMQ 1.0, a single blocking call blocks the creator's thread, which in turn blocks all calls.
  • Applications that share Message Queuing objects perform faster because the caller thread manipulates the object. For MSMQ 1.0, all calls are switched to the creator's thread before they can be executed.

Asynchronous Receives Inside Internet Explorer

Message Queuing now allows you to do asynchronous receives inside Internet Explorer using DHTML and the MSMQEvent object.

Create and Modify Times for Private Queues

Message Queuing now allows you to use COM components for retrieving the time when private queues were created time and the time when they were last modified.

For information, see the following:

  • MSMQQueueInfo.CreateTime
  • MSMQQueueInfo.ModifyTime

Multi-Threaded Apartment

(MTA) An apartment model defined by COM. Objects in an MTA execute on any thread and allows any number of methods to execute simultaneously. Message Queuing uses this model for its COM objects in MSMQ 2.0.

For information on COM apartment models, see COM+ Apartment Models.

Single-Threaded Apartment

(STA) An apartment model defined by COM. Objects in an STA execute on the thread in which they were created and allow only one method to execute at a time. Message Queuing uses this model for its COM objects in MSMQ 1.0.

For information on COM apartment models, see COM+ Apartment Models.


Further Information on Message Queuing

The following resources contain additional information of Message Queuing.

For information on installing and administering Message Queuing, see Windows 2000 Help.

In addition the following books on Message Queuing are available:

Crane, Neil. MSMQ From Scratch. Macmillan USA Publishing, 1999. ISBN: 0789721279 .

Dickman, Alan. Designing Applications With MSMQ: Message Queuing for Developers. Addison-Wesley Publishing Co., 1998. ISBN: 0201325810.

Fischer, Peter. Building Distributed Component Systems Using MSMQ. New Riders Publishing. ISBN: 0735709742.

Homer, Alex and David Sussman. Professional MTS and MSMQ Programming with VB and ASP. Wrox Professional Series. Wrox Press Inc., 1998. ISBN: 1861001460.

Lewis, Rhys. Advanced Messaging Applications with MSMQ and MQSeries. Que, 1999. ISBN: 078972023X.

Mohr, Stephen T. and Stephen F. Mohr. Designing Distributed Applications With XML ASP IE5 LDAP and MSMQ. Wrox Press Inc., 1999. ISBN: 1861002270.


About Message Queuing

About Message Queuing (MSMQ) contains conceptual information on queues, messages, properties, computers, and information on the services provided by Message Queuing.

For information on | See
What Message Queuing is | Message Queuing Overview
The different types of queues used by Message Queuing applications | Message Queuing Queues
The messages used to send data | Message Queuing Messages
Reading messages with cursors | Navigating with Cursors
Sending and retrieving messages within a transaction | Message Queuing Transactions
Running applications offline | Message Queuing Offline Support
Message authentication, access control, private (encrypted) messages, and auditing | Message Queuing Security Services
Connecting to non–Message Queuing enterprises | MSMQ Connector Servers
Using the Message Queuing Mail API | Message Queuing Mail Services
The COM object model used by Message Queuing | Message Queuing COM Support


Message Queuing Overview

Message Queuing is a message infrastructure and a development platform for creating distributed, loosely-coupled, messaging applications for the Microsoft® Windows® operating system. Message Queuing applications can use the Message Queuing infrastructure to communicate across heterogeneous networks and with computers that may be offline. Message Queuing provides guaranteed message delivery, efficient routing, security, transaction support, and priority-based messaging.

This overview covers the types of Message Queuing applications that can be written and the types of Message Queuing environments that these applications can operate within. (For information and procedures on deploying the Message Queuing infrastructure, see Windows Help.)

Naming Conventions

With the release of Microsoft Windows 2000 version 5.0, the name of Microsoft's message queuing solution changed from Microsoft Message Queue Services to Message Queuing. In the Windows Platform SDK, the term Message Queueing refers to all versions of the product. The specific versions of Message Queuing include:

  • MSMQ 1.0—the Microsoft Message Queue Services 1.0 product that operates with Microsoft Windows NT 4.0, Microsoft Windows 95, and Microsoft Windows 98.
  • MSMQ 2.0—the Message Queuing service included in Microsoft Windows 2000, version 5.0.
  • MSMQ 3.0—the Message Queuing service included in Microsoft Windows 2000, version 5.1 (Whistler).
For information on | See
Applications that send or read messages | Message Queuing Applications
The types of queues provided by Message Queuing | Message Queuing Queues
The types of messages provided by Message Queuing | Message Queuing Messages


Message Queuing Applications

Message Queueing applications can be divided in two categories: sending applications that send messages to queues and receiving applications that read the messages in the queue. The following illustration shows several sending applications sending messages to a queue and several receiving applications reading the messages in the queue. (Using the directory service is not required; messages can be sent to the queue and read from the queue without accessing the directory service.)

Sending Applications

Sending application send their messages to a queue, not to the receiving application. Using a queue as the destination allows the sending application to operate independently of the receiving application.

Developers have several options to consider when designing sending applications:

  • Transactional Messages Versus Non-Transactional Messages. Transactional messages can be included with other operations—such as updating a database—in an atomic process that can be aborted if any part of the transaction fails. Transactional messages guarantee exactly-once and ordered delivery. Non-transactional messages, on the other hand, cannot guarantee exactly-once or ordered delivery.
  • Express delivery versus recoverability. Recoverable messages are delivered even if a computer crashes, a copy of the message is stored locally on every computer the sends the message. Express messages are stored only until the message is delivered to the next computer.
  • Direct routing versus store-and-forward routing. Direct messages are sent directly to the computer where the queue resides and do not access the directory service. Store-and-forward routing requires a connection to the directory service and the path the message takes is determined by Message Queuing.
  • Authenticated messages versus non-authenticated messages. Authenticated messages are digitally signed and authenticated by Message Queuing. When a message is authenticated, Message Queuing guarantees that no one has tampered with the message, and it verifies the identity of the sender.
  • Encrypted messages versus non-encrypted messages.: Encrypted message are encrypted before they leave the source computer to the time they reach the target computer. Information in non-encrypted messages can be read while the message is on the wire.
  • Online versus off-line operations. When online, the sending application has access to information stored in the directory service. When operating off-line, the sending application cannot make any calls the require access to the directory service.

Receiving applications

Receiving applications read the messages in the queue in two different ways. The receiving application can peek at a message in the queue, leaving the message in the queue, or it can retrieve the message, taking the message out of the queue.

The developer should consider the following when designing their receiving applications:

  • Local versus remote read. Messages should always be read locally. Reading messages remotely consumes a lot of resources.
  • Transactional versus non-transactional messages.
  • Synchronous versus asynchronous. Asynchronously reading messages allows the receiving operation to continue its processing while it waits for the messages to be read from the queue. Synchronously reading messages blocks processing until the messages are read from the queue or a timeout expires.
  • Peek versus retrieve. Peeking at message allows the receiving application to look at the message and leave a copy of the message in the queue. Retrieving messages from the queue removes the messages from the queue.
  • Online versus off-line operations.: When online, the receiving application has access to information stored in the directory service. When operating off-line, the receiving application cannot make any calls the require access to the directory service.


Message Queuing Queues

Queues are logical containers that Message Queuing uses to store and later forward messages, providing the bases for the loosely coupled aspects of Message Queuing. For example, sending applications and Message Queuing can send messages to queues without needing to know when the messages are delivered or when the receiving application will process the messages in the queue. The act of sending messages to a queue is independent of when the message reaches the queue and when the receiving application reads the messages in the queue.

Applications can create queues, locate existing queues, open queues, send messages to queues, read messages in queues, set and retrieve queue properties, and set and retrieve the security descriptors of queues. For information on how the application references the queue is referenced when performing these operations, see Referencing a Queue.

Queues can be created by applications and by Message Queuing. Queues created by applications are referred to as application queues. Queues created by Message Queuing are referred to as system queues.

Note Message Queuing also uses private internal queues for routing messages between computers. However, these queues cannot be manipulated by applications.

For information on | See
Queues created by applications | Application-Generated Queues
Queues created by Message Queuing | System-Generated Queues
Methods of referencing a queue | Referencing a Queue


Application-Generated Queues

Queues that are generated, or created, by an application or the Message Queuing administrator are often referred to as application queues. Depending on the service provided by the queue, application queues can be public, private, transactional, or non-transactional (for example, administration queues cannot be transactional).

Application queues include the following types of queues:

  • Destination queues—any queue that the sending application sends messages to or that the receiving application reads messages from.
  • Administration queues—queues used for acknowledgment messages returned by Message Queuing or connector applications.
  • Response queues—queues used by receiving applications to return response messages to the sending application.
  • Report queues—queues used for report messages returned by Message Queuing.
For information on | See
What destination queues are and how they are used | Destination Queues
What administration queues are and how they are used | Administration Queues
What response queues are and how they are used | Response Queues
What report queues are and how they are used | Report Queues


Destination Queues

Destination queues are any application queue that is used to store messages sent from an application. Typically, the destination queue is a local queue on a server. Client applications send messages to the destination queue on the server computer (in this case the server computer can also be referred to as the target computer), and the server applications process the messages after they arrive.

The following illustration shows a single destination queue used by two applications. The sending application on the client computer sends the message to the queue and the receiving application on the server computer reads the messages from the queue. Typically, destination queues are located on the same computer as the receiving application in order to minimize network traffic.

Destination queues can be public queues, private queues, transactional queues, or non-transactional queues. When designing a distributed Message Queuing application, you must decide if the destination queues should be public or private queues, and whether the public or private queues used should be transactional or non-transactional. Whether a queue is public, private, transactional, or non-transactional is specified when the queue is created.

Public Versus Private Queues

The decision to use public or private destination queues depends primarily on whether you want other applications to be able to locate the queues.

The advantage of public destination queues is that they are registered in the directory service where they can be located by other Message Queuing applications. Public queues are persistent, and their registration information can be backed up on the enterprise, making them good for long-term use.

Private queues are registered on the local computer, not in the directory service, and typically cannot be seen by other Message Queuing applications. Message Queuing registers private queues by storing a description of the queue in the LQS (local queue storage) directory on the local computer (the default LQS directory is \program files\msmq\storage\lqs).

Private queues have the advantage of no directory service overhead (faster to create, no latency, and no replication). They can be created and deleted when the directory service is not working, making private queues attractive for offline operations where the directory service may not be available.

Private queues can be exposed to other applications by making the location of the private queue known to the applications. To distribute the location of a private queue, an application can send the format name of the private queue as the response queue property of a message.

Transactional Versus Non-Transactional Queues

The decision to use transactional or non-transactional queues is based on whether the applications accessing the queue will be sending and receiving messages within the context of a transaction.

When sending messages, only transactional queues can accept messages sent in the context of a transaction. These messages are also referred to as transactional message. In a similar way, non-transactional queues can only accept messages sent outside the context of a transaction.

When receiving messages, only local transactional queues can be accessed within the context of a transaction. The transactional queue must be local to the receiving application. On the other hand, non-transactional queues can be accessed within or outside of a transaction.

For information on | See
What administration queues are and how they are used | Administartion Queues
What response queues are and how they are used | Response Queues
Queue registration files in the MSMQ\Storage\Lqs folder | Storage Folder Files


Administration Queues

Administration queues are application-generated queues used to store system-generated negative and positive acknowledgment messages that are created by Message Queuing or connector applications. Any available non-transactional queue can be used as an administration queue.

The system-generated acknowledgment messages returned to these queues can indicate whether a message arrived at its destination queue, whether it was retrieved from the destination queue, or both. Each acknowledgment message contains information that describes what triggered the acknowledgment and which message the acknowledgment refers to.

When requesting acknowledgment messages, the sending application must specify the queues to be used as the administration queue and the acknowledgment level of the message. Typically, administration queues should be local queues so that the sending application can read the acknowledgment messages locally.

Message Queuing provides the following message properties for specifying administration queues.

  • PROPID_M_ADMIN_FORMAT_NAME or MSMQMessage.AdminDestination

    This property (introduced in MSMQ 3.0) can be used to specify one or more administration queues. Multiple administration queues can be specified with distribution lists, multicast addresses, and multiple-element format names.

  • PROPID_M_ADMIN_QUEUE or MSMQMessage.AdminQueueInfo

    This property is superseded by PROPID_M_ADMIN_FORMAT_NAME and MSMQMessage.AdminDestination respectively and should be used only in existing applications. This property specifies a single administration queue.

When both an administration queue and a response queue are needed, their functionality can be combined in a single queue. However, this means that the response queue must also be non-transactional. These queues cannot be combined if the response queue needs to be a transactional queue.

For information on | See
An introduction to acknowledgment messages | Acknowledgment Messages
What are the classes of acknowledgement messages | Acknowledgment Message Classes
What information is returned in the properties of an acknowledgment message | Acknowledgment Message Properties
How to match an acknowledgment with the message that caused the acknowledgment | Matching Acknowledgment and Original Messages
Other application-generated queues | Application-generated Queues


Response Queues

Response queues are application-generated queues used to store application-generated response messages that are typically returned by an application that is reading messages from a queue. Any available queue can be specified as a response queue.

The response messages returned to these queues must be understood by the application returning the response messages and the application reading the response message. Message Queuing has no control over what information is sent in response messages.

When requesting response messages, the sending application must specify the queues that it wants to use as response queues. Typically, response queues should be local queues so that the sending application can read the response messages locally.

Message Queuing provides the following message properties for specifying response queues.

  • PROPID_M_RESP_FORMAT_NAME or MSMQMessage.ResponseDestination

    This property (introduced in MSMQ 3.0) can be used to specify one or more response queues. Multiple response queues can be specified with distribution lists, multicast addresses, and multiple-element format names.

  • PROPID_M_RESP_QUEUE or MSMQMessage.ResponseQueueInfo

    This property is superseded by PROPID_M_RESP_FORMAT_NAME and MSMQMessage.ResponseDestination respectively and should be used only in existing applications. This property specifies a single response queue.

When both response queues and administration queues are needed, their functionality can be combined into a single queue. However, this restricts the response queue to non-transactional queues. All administration queues must be non-transactional.

The message properties used to specify response queues can also be used to send the format name of private queues to other application.

For information on | See
What are response messages | Response Messages
Other application-generated queues | Application-generated Queues


Report Queues

Report queues are application-generated queues used to store report messages generated by Message Queuing ot connector applications when tracing is requested by the sending application. When a message is sent with tracing enabled, a report message is generated each time the message leaves or arrives at a Message Queuing computer.

Note Report queues are not limited to report messages. Application-generated messages can be sent to report queues as well.

All report queues must have the following label and queue type identifier.

  • Label: MQReport Queue.
  • Queue type identifier (GUID):
    {55EE8F32-CCE9-11CF-B108-0020AFD61CE9}

Report queues are typically created by the Message Queuing administrator using Active Directory Manager; however, they can also be generated by an application as long as the correct label and queue type identifier is specified when the queue is created. Message Queuing uses the label and queue type identifier to locate and open the appropriate queue when sending report messages.

Typically a single report queue is specified by the source computer where the message is sent. However, each Message Queuing computer can specify its own report queue.

For information on | See
Enabling tracing | Tracing Messages
Other application-generated queues | Application-generated Queues


System-Generated Queues

Queues that are created by Message Queuing are referred to as system queues. System queues include the following types of queues.

  • Queue journals: Queue journals are queues that contain copies of all messages removed from a queue.
  • Computer journals: Computer journals are queues that contain copies of all messages sent from a computer.
  • Dead letter queues: Dead-letter queues contain messages that could not be delivered. Message queuing provides a transactional dead-letter queue and a non-transactional dead-letter queue.
  • Connector queues: Connector queues are used when sending messages to foreign queues.

Applications can only read the messages in system queues.

For information on | See
What queue and computer journals are and how they are used | Journal Queues
What dead-letter queues are and how they are used | Dead-Letter Queues
What connector queues are and how they are used | Connector Queues


Journal Queues

Queue and computer journals are system queues that are automatically created by Message Queuing. The following illustration shows a destination queue and its queue journal, plus several computers with their computer journals. When the sending application sends a message, a copy of the message is optionally stored in the computer journal of each computer it passes through. When the receiving application removes the message from the destination queue, a copy of the message is optionally sent to the queue journal.

Applications can only read the messages in queue and computer journals. They cannot send messages to queue or computer journals. In contrast, Message Queuing never removes messages from queue or computer journals. It is up to the application reading the messages to clear the messages from the queues.

Queue Journals

Queue journals are created whenever an application-generated queue is created. They are used to store copies of all messages removed from the queue. Message queuing creates the queue journal on the same computer where the messages for the application-generated queue are stored.

Message Queuing stores copies of the messages removed from the application-generated queue whenever target journaling is enabled on the queue. To enable target journaling, the journaling property of the queue must be set to MQ_JOURNAL.

Note This does not include message removed from the queue when their time-to-be-received timer expires, or messages purged from the queue using the directory service.

Computer Journals

Computer journals are created whenever a Message Queuing computer is added to the enterprise. They are used to store copies of all messages successfully sent from the computer.

Message Queuing stores copies of the messages sent from the computer whenever positive_source journaling is specified by the sending application. Source journaling is used to track messages as they are routed to the target computer where the messages for the destination queue are stored. To enable positive source journaling, the journaling property of the message must be set to MQ_JOURNAL when the message is sent.

For information on | See
Enabling positive source journaling | Source Journaling
Other system queues | System-Generated Queues


Dead-Letter queues

Dead-letter queues are system-generated queues used for storing messages that could not be delivered. Message Queuing creates a transactional and non-transactional dead letter queue on each computer added to the enterprise.

When a message is sent to a dead letter queue, Message Queuing changes the class of the property to reflect the last known status of the message. For example, Message Queuing will change the class of the message and place it in the appropriate dead letter queue if the message's time-to-reach-queue timer or time-to-be-received timer expired.

Non-Transactional Messages and Dead-Letter Queues

When the journaling property of a non-transactional message is set to MQMSG_DEADLETTER, any Message Queuing computer that cannot send the non-transactional messages will send the undelivered message to the non-transactional dead letter queue of that computer. This can be the source computer, the destination computer, or any Message Queuing routing server in between. When an undelivered message is placed in a dead-letter queue, Message Queuing sets the class property of the message to the appropriate negative acknowledgment.

Note Only one copy of a message is stored on a computer at one time. When a message reaches a computer successfully, it is stored in an internal queue on that computer. If the message cannot be delivered to the next computer, it is then stored in the current computer's dead-letter queue.

Transactional Messages and Dead-Letter Queues

When the journaling property of a transactional message is set to MQMSG_DEADLETTER, the source queue manager sends a copy of the message to the transactional dead letter queue if the source queue manager does not receive a confirmation from the target queue manager that indicates the message was successfully retrieved from the target queue. Confirmation is not returned if the message is not delivered, was not received, or the receiving transaction was aborted. By default, the journaling property of transactional messages is not set to MQMSG_DEADLETTER.

MSMQ 1.0 Restrictions on Source Journaling

MSMQ 1.0 did not allow sending applications to specify source journaling. For MSMQ 1.0, all transactional messages are placed in the transactional dead letter queue after the time-to-be-received timer expires. All later versions of Message Queuing now allow complete control over source journaling.

For information on | See
When to use dead-letter queues | Source Journaling
Other system queues | System-Generated Queues


Connector Queues

Connector queues are system-generated queues used for passing messages from Message Queuing to a foreign site. Message Queuing creates a transactional and non-transactional connector queue for each foreign site associated with a connector server.

When messages are sent to foreign queues, Message Queuing intercepts the messages and places them in the appropriate set of connector queues. The connector application on the connector server must remove the messages from the connector queues, process them, and then pass the messages on to the foreign messaging system.

For information on | See
The elements and syntax of connector format names | Machine and Connector Format Names
Other system queues | System-Generated Queues


Referencing a Queue

To perform an operation on queue, an application must reference the queue in one of three ways, depending on the operation the application is performing:

  • The pathname is used to create the queue.
  • The format name is used to open the queue, reset the properties and security descriptor of the queue, and to delete the queue.
  • The queue handle is used to send messages to the queue, read from the queue, and create cursors for navigating through the queue (a queue handle can also be used to create a format name for the queue that can then be passed on to other processes).
For information on | See
Referencing a queue by its pathname | Queue Pathnames
Referencing a queue by its format name | Format Names
Referencing a queue by its queue handle | Queue Handle


Queue Pathnames

The pathname of the queue provides the information Message Queuing needs to create the queue. The pathname of the queue specifies the name of the computer where the messages in the queue will be stored, an optional PRIVATE$ keyword that indicates if the queue is a private queue, and the name of the queue. The application must provide a unique pathname when the queue is created.

The following examples show the syntax used to create public and private queues. Note that the third example substitutes the string "." for the name of the computer. This is a shortcut to indicate that the messages of the queue will be stored on the local computer. (For dependent clients, the local computer is the client's Message Queuing server.)

MachineName\QueueName
MachineName\PRIVATE$\QueueName
.\QueueName

Queue names have the following characteristics.

  • The name of the queue is case insensitive. For example, "MyQueue" and "myQueue" are treated as the same name.
  • Queue names can be up to 124 Unicode characters.
  • Valid characters for queue names vary slightly depending on what version of Message Queuing is creating the queue. The following table lists the characters that cannot be used.
    Message Queuing version Invalid queue name characters
    MSMQ 1.0 \ (back slash)

    ; semicolons)

    CR (ascii 13); private queues only

    LF (ascii 10); private queues only
    MSMQ 2.0 and later \ (back slash)

    ; (semicolons)

    CR (ascii 13)

    LF (ascii 10)

    + (plus)

    , (comma)

    " (double quote)

Message Queuing supports both NetBIOS and DNS pathnames for creating queues.

Messages for public queues can be stored on any computer in your enterprise. Consiquently, remote queues can be specified in the pathname when creating public queues. However, messages for private queues can be stored only on the local computer. Therefore, only the local computer can be specified in the pathname when creating a private queue.

For information on | See
Referencing a queue by its format name | Format Names
Referencing a queue by its queue handle | Queue Handle
Properties used to specify the queue | PROPID_Q_PATHNAME -or- MSMQQueueInfo.PathName
DNS queue and computer pathname properties | PROPID_Q_PATHNAME_DNS PROPID_QM_PATHNAME_DNS -or- MSMQQueueInfo.PathNameDNS


Format Names

Format names provide the information that Message Queuing needs to open queues for sending messages and retrieving messages, to set or retrieve the properties of the queue, to set or retrieve the security descriptor of the queue, or to delete the queue.

Unlike most other characteristics of a queue, the format name of the queue is not an queue property. It is simply a unique name that is generated by Message Queuing when the queue is created, or it is generated later by the application. Message Queuing never stores the format name of a queue for later reference.

Single and Multiple-Element Format Names

Message Queuing uses single and multiple-element format names (introduced in MSMQ 3.0) to reference queues.

Single-element format names include public, private, direct, distribution list (introduced in MSMQ 3.0), multicast address (introduced in MSMQ 3.0), computer, and connector format names. Each type reflects the type of information that is included in the format name and, consequently, each type has its own syntax.

Multiple-element format names (introduced in MSMQ 3.0) are a string of any number of single-element public, private, direct, and distribution lists format names. Multiple-element format names are used only to send messages.

Format Names in COM Components

The MSMQQueueInfo object and MSMQDestination object (introduced in MSMQ 3.0) both have format name properties.

The MSMQQueueInfo.FormatName property returns the format name of the queue when the queue is created. This format name returned can be used as it is, or it can be modified by the application. For example, to read messages in a queue journal the receive application can retrieve the format name of the destination queue, concatenate the ";JOURNAL" keyword to the end of a destination queue format name, then use this new format name to open the journal queue.

The MSMQDestination.FormatName property returns the format name to a distribution list, or can be used to specify a multiple-element format name for sending messages to multiple queues.

API functions That Use Format Names

The following function calls require a format name:

  • MQOpenQueue
  • MQGetQueueProperties
  • MQSetQueueProperties
  • MQGetQueueSecurity
  • MQSetQueueSecurity
  • MQDeleteQueue
For information on | See
Ways to obtain a format name | Obtaining Format Names
The elements and syntax of private format names | Private Format Names
The elements and syntax of distribution list format names | Distribution List Format Names
The elements and syntax of a multicast format name | Multicast Address Format Names
The elements and syntax of multiple-element format names | Multiple-element Format Names
The elements and syntax of direct format names | Direct Format Names
The syntax of machine and connector format names | Machine and Connector Format Names


Obtaining Format Names

Message Queuing provides several ways to obtain the format names of queues.

When creating queues, Message Queuing returns a format name whenever it creates a destination queue.

Applications using COM components can obtain the format name of a destination queue from the MSMQQueueInfo object used to create the queue.

When locating public queues, applications using API functions can retrieve the pathname or queue identifier (GUID) of a public queue and translate these elements into a format name for the queue by using the MQPathNameToFormatName and MQInstanceToFormatName functions respectively.

Applications using COM components can obtain the format name of a queue from the collection of MSMQQueueInfo objects referenced by the MSMQQueueInfos object returned by a query.

Applications using API functions can translate the queue handle returned by MQOpenQueue to a format name by using the MQHandleToFormatName function.

Applications using COM components can obtain the format name of the queue from the MSMQQueueInfo.FormatName property of MSMQQueueInfo object.

Applications can retrieve the format names of response queues, administration queues, and destination queues by retrieving the appropriate property of the message.

The following message properties hold the format names of queues

  • Response queue properties: These properties are set by the sending application when requesting response messages (or to send the format name of a private queue) and set by Message Queuing when returning acknowledgment messages. In acknowledgment messages, these properties hold the format name of the original destination queue.

    For details about these properties see:
    PROPID_M_RESP_QUEUE (MSMQ 1.0 and MSMQ 2.0 only)
    PROPID_M_RESP_FORMAT_NAME (introduced in MSMQ 3.0)
    MSMQMessage.ResponseQueueInfo (MSMQ 1.0 and MSMQ 2.0 only)
    MSMQMessage.ResponseDestination (introduced in MSMQ 3.0)

  • Administration queue properties: These properties are set by the sending application when requesting acknowledgment messages.

    For details about these properties see:
    PROPID_M_ADMIN_QUEUE (MSMQ 1.0 and MSMQ 2.0 only)
    PROPID_M_ADMIN_FORMAT_NAME (introduced in MSMQ 3.0)
    MSMQMessage.AdminQueueInfo (MSMQ 1.0 and MSMQ 2.0 only)
    MSMQMessage.AdminDestination (introduced in MSMQ 3.0)

  • Destination queue properties: These properties are set by Message Queuing when the message is sent. If a message is sent to multiple destination queues both properties are set.

    For details about these properties see:
    PROPID_M_DEST_QUEUE
    PROPID_M_DEST_FORMAT_NAME (introduced in MSMQ 3.0)
    MSMQMessage.DestinationQueueInfo
    MSMQMessage.Destination (introduced in Whistler)


Public Format Names

Public format names are used to reference public queues. They are used to perform the following operations.

  • To open a public queue to send messages and request routing. A public queue can be opened with public or direct format name. When a public format name is used, Message Queuing uses its internal routing algorithm to define the route to the destination queue. When a direct format name is used, the message is sent directly to the queue.
  • To open a public queue to read messages.
  • To retrieve and set the properties of a public queue.
  • To retrieve or set the security descriptor of a public queue.

When the queue manager detects a public format name, it looks in the directory service to determine what computer is currently hosting the queue, what protocol the host computer uses, and any other information it needs to rout the message to the queue.

Public Format Name Syntax

Public format names contain the string "Public=" followed by the identifier of the queue that is generated by Message Queuing when the queue is created. The following is the general format used to reference a public queue and its associated queue journal:

PUBLIC=QueueGUID                  *Public queues.
PUBLIC=QueueGUID;JOURNAL          *Public queue journals.

A public format name is strictly equivalent to the identifier of the queue (see PROPID_Q_INSTANCE or MSMQQueueInfo.QueueGuid) except that a public format name is formatted as a string rather than as binary data. The following line of code is an example of a public format name string (note that the format name string is a null-terminated Unicode string).

Lpwstr Sz = L"PUBLIC=308FB580-1EB2-11CA-923B-08002B1075A7";

Specifying Multiple Queues

Public format names can also be used to reference a public queue in distribution lists and multiple-element format names. Distribution lists and multiple-element format names can be used to send messages to multiple destinations, specify administration queues, and specify response queues.

Location Independence

The location of the public queue (the specific computer where the messages belonging to the queue are stored) is not part of the public format name. This allows message operations to succeed when using public format names regardless of the location of the queue; a public queue can be relocated to another computer and the format name remains valid. This is not true of direct format names which are bound to a specific location.

For information on | See
Ways to obtain a format name | Obtaining Format Names
The syntax of private format names | Private Format Names
The elements and syntax of distribution list format names | Distribution List Format Names
The elements and syntax of multiple-element format names | Multiple-element Format Names
The elements and syntax of direct format names | Direct Format Names
The syntax of machine and connector format names | Machine and Connector Format Names


Private Format Names

Private format names are used to reference private queues. They are used to perform the following operations.

  • To open a private queue to send messages and request routing. A private queue can be opened with private or direct format name. When a private format name is used, Message Queuing uses its internal routing algorithm to define the route to the destination queue. When a direct format name is used, the message is sent directly to the queue.
  • To open a private queue to read messages.
  • To retrieve and set the properties of a private queue.
  • To retrieve or set the security descriptor of a private queue.

When Message Queuing detects a private format name, it does not refer to the directory service for information about the queue. However, it does use the directory service to look up information on the computer for routing purposes.

Private Format Name Syntax

Private format names contain the string "Private=" followed by the machine identifier of the computer where the queue is registered and a hexadecimal number that identifies the queue. The following is the general format used to reference a private queue and its associated queue journal:

PRIVATE=MachineGUID\QueueNumber              *Private queues.
PRIVATE=MachineGUID\QueueNumber;JOURNAL      *Private queue journals.

The following line of code is an example of a private format name string (note that the format name string is a null-terminated Unicode string).

Lpwstr Sz = L"PRIVATE=ae0c5671-f190-12ce-ae10-00dd0114290f\0000000d";

Specifying Multiple Queues

Private format names can be used in multiple-element format names. (Private format name cannot be explicitly referenced in a distribution list; however, a queue alias can included in the distribution list that references a private queue.)

For information on | See
Ways to obtain a format name | Obtaining Format Names
The elements and syntax of public format names | Public Format Names
The elements and syntax of distribution lists format names | Distribution List Format Names
The elements and syntax of multiple-element format names | Multiple-Element Format Names
The elements and syntax of direct format names | Direct Format Names
The elements and syntax of machine and connector format names | Machine and Connector Format Names


Distribution List Format Names

Distribution list format names (introduced in MSMQ 3.0) are used to reference distribution lists stored in Active Directory. Distribution lists can be used when performing the following operations while online (distribution lists cannot be use if there is no connection to Active Directory).

  • To send messages to multiple destinations (distribution lists cannot be used read messages in a queue).
  • To specify multiple administration queues when requesting acknowledgment messages.
  • To specify multiple response queues when requesting response messages.

Distribution lists can contain references to public queues, queue aliases, and other distribution lists (private queues and HTTP queues can only be referenced through queue aliases).

Distribution List Format Name Syntax

Distribution list format names contain the string "DL=" followed by the distribution list identifier. The distribution list identifier (GUID) can be found in the objectGUID property of the distribution list group in Active Directory. The following is the general format used to reference a distribution list:

DL=DistributionListGUID.

The following line of code is an example of a distribution list format name string (note that the format name string is a null-terminated Unicode string).

Lpwstr Sz = L"DL=ae0c5671-f190-12ce-ae10-00dd0114290f\0000000d";

Creating and Maintaining Distribution Lists

Distribution lists are created and maintained using the methods provided by the IADsGroup interface.

Distribution Lists and Multiple-Element Format Names

Distribution lists and multiple-element format names both reference multiple destinations. The difference between them is that distribution lists are public lists stored in Active Directory and multiple-element format names are private lists that must be created and maintained by the application.

For information on | See
Using distribution lists to open queues |
Using distribution lists to specify multiple administration queues | Administration Queues
Using distribution lists to specify multiple response queues | Response Queues
Ways to obtain a format name | Obtaining Format Names
The elements and syntax of public format names | Public Format Names
The elements and syntax of private format names | Private Format Names
The elements and syntax of multiple-element format names | Multiple-Element Format Names
The elements and syntax of direct format names | Direct Format Names
The elements and syntax of machine and connector format names | Machine and Connector Format Names


Multicast Address Format Names

You can use multicast address format names (introduced in MSMQ 3.0) to reference multiple destination queues when performing the following operations.

  • To send messages to multiple destinations (multicast format names cannot be used read messages in a queue). When sending messages, the message is sent to any queue associated with the specified multicast address. For information on associating a queue with a multicast address, see .
  • To specify multiple administration queues when requesting acknowledgment messages.
  • To specify multiple response queues when requesting response messages.

Multicast Address Format Name Syntax

The following is the general form of a multicast address format name.

MULTICAST=<Addresss>:<port>
For information on | See
Using multicast addresses to send messages | Sending Messages to Multiple Destinations
Associating a queue with a multicast address | PROPID_Q_MULTICAST_ADDRESS MSMQQueueInfo.MulticastAddress
Specifying multiple administration queues | PROPID_M_ADMIN_FORMAT_NAME MSMQMessage.AdminDestination
Specifying multiple response queues | PROPID_M_RESP_FORMAT_NAME MSMQMessage.ResponseDestination
Ways to obtain a format name | Obtaining Format Names
The elements and syntax of public format names | Public Format Names
The elements and syntax of private format names | Private Format Names
The elements and syntax of multiple-element format names | Multiple-Element Format Names
The elements and syntax of direct format names | Direct Format Names
The elements and syntax of machine and connector format names | Machine and Connector Format Names


Multiple-Element Format Names

Multiple-element format names (introduced in MSMQ 3.0) are used to reference multiple destination queues. Multiple-element format names can be used when performing the following operations.

  • To send messages to multiple destinations (multiple-element format names cannot be used read messages in a queue).
  • To specify multiple administration queues when requesting acknowledgment messages.
  • To specify multiple response queues when requesting response messages.

Multiple-element format names can contain public format names, private format names, direct format names, and distribution list format names.

Multiple-Element Format Name Syntax

Multiple-element format names contain any number of single-element format names separated by commas. The following is the general format used to reference multiple destinations:

Formatname1,FormatName2,FormatNameN

Multiple-Element Format Names and Distribution Lists

Multiple-element format names and distribution lists both reference multiple destinations. The difference between them is that distribution lists are public lists stored in Active Directory while multiple-element format names are private lists that must. be created and maintained by the application.

For information on | See
Using multiple-element format names to send messages |
Using multiple-element format names to specify multiple administration queues | Administration Queues
Using multiple-element format names to specify multiple response queues | Response Queues
Ways to obtain a format name | Obtaining Format Names
The elements and syntax of public format names | Public Format Names
The elements and syntax of private format names | Private Format Names
The elements and syntax of distribution list format names | Distribution List Format Names
The elements and syntax of direct format names | Direct Format Names
The elements and syntax of machine and connector format names | Machine and Connector Format Names


Direct Format Names

Direct format names are used to reference public or private queues without accessing the directory. Direct format names can be used when performing the following operations.

  • Sending message directly to a computer.
  • Sending message to computers on the internet.
  • Sending messages while operating in a workgroup environment.
  • Reading messages while operating in a workgroup environment.

When Message Queuing detects a direct format name, it does not contact the directory service. Message Queuing uses the information provided by the format name to send messages directly to their destination.

Direct Format Name Syntax

Direct format names specify the location of the queue and the name of the queue.

The following is the general format of direct format names. Note that public, private , and (for MSMQ 2.0 clients and servers) computer system queues can be accessed directly.

DIRECT=AddressSpecification\QueueName            (For public queues.)
DIRECT=AddressSpecification\PRIVATE$\QueueName   (For private queues.)
DIRECT=AddressSpecification\SYSTEM$;computersystemqueue (introduced in MSMQ 2.0 for computer journal and dead letter queues.)
DIRECT=HTTP://URLAddressSpecification\msmq\QueueName                        (introduced in MSMQ 3.0)
DIRECT=HTTPS://URLAddressSpecification\msmq\QueueName                       (introduced in MSMQ 3.0)

The following lines of code are examples of several direct format name strings (note that the format name string is a null-terminated Unicode string).

For public queues
Lpwstr Sz = L"DIRECT=SPX: 00000012:00a0234f7500\myQueue";  //supported only on Windows NT4 and Windows 2000
Lpwstr Sz = L"DIRECT=TCP:157.18.3.1\myQueue";
Lpwstr Sz = L"DIRECT=OS:elvisp.ms.com\myQueue";
Lpwstr Sz = L"DIRECT=OS:elvisp\MqQueue";

For private queues
Lpwstr Sz = L"DIRECT=SPX: 00000012:00a0234f7500\PRIVATE$\myQueue";  //supported only on Windows NT 4.0 and Windows 2000
Lpwstr Sz = L"DIRECT=TCP:157.18.3.1\PRIVATE$\myQueue";
Lpwstr Sz = L"DIRECT=OS:elvisp.ms.com\PRIVATE$\myQueue";
Lpwstr Sz = L"DIRECT=OS:elvisp\PRIVATE$\MqQueue";

For queues on the Internet
DIRECT=HTTP://myServer/msmq/myQueue
DIRECT=HTTPS://myServer/msmq/myQueue

Address specification

The address specification of the computer can be specified in two forms:

  • As the network address of the target computer (including the network protocol). Message Queuing supports TCP and, only on Windows NT4 and Windows 2000, SPX.
  • As any string that is supported natively by the underlying operating system to identify the target computer (OS is used as the protocol to indicate that the computer's native protocol should be used).
Protocol | Description | Network Address
TCP | Connection-oriented TCP over IP. | Internet address notation (IP address).
SPX | Connection-oriented SPX over IPX. | Network number and host number (separated by the ":" character).
OS | Connection using native machine-naming convention. | Any machine name supported by the underlying operating system. For Microsoft® Windows NT® version 4.0, it is either UNC or DNS (see the following examples).

For information on | See
Ways to obtain a format name | Obtaining Format Names
The elements and syntax of public format names | Public Format Names
The elements and syntax of private format names | Private Format Names
The elements and syntax of distribution list format names | Distribution List Format Names
The elements and syntax of multiple-element format names | Multiple-Element Format Names
The elements and syntax of machine and connector format names | Machine and Connector Format Names


Machine and Connector Format Names

Machine format names are used to reference computer journals and dead-letter queues for a specific computer and connector format names are used to reference the connector queues on a connector server.

Machine format name syntax

Machine format names contain the string "MACHINE=" followed by the identifier of the computer and the keyword that identifies which system queue to open. The following is the general format used to open a computer journals, non-transactional dead-letter queues, and transactional dead-letter queues:

MACHINE=MachineGUID;JOURNAL                  *Computer journal.
MACHINE=MachineGUID;DEADLETTER               *Non-transactional dead-letter queue.
MACHINE=MachineGUID;DEADXACT                 *Transactional dead letter queue.

The following lines of code are example of computer journal, non-transactional dead-letter queue, and transactional dead-letter queue format name strings (note that the format name strings are null-terminated Unicode strings).

Lpwstr Sz = L"MACHINE=308FB580-1EB2-11CA-923B-08002B1075A7;JOURNAL";
Lpwstr Sz = L"MACHINE=308FB580-1EB2-11CA-923B-08002B1075A7;DEADLETTER";
Lpwstr Sz = L"MACHINE=308FB580-1EB2-11CA-923B-08002B1075A7;DEADXACT";

Connector format name syntax

Connector format names contain the string "CONNECTOR=" followed by the identifier of the foreign enterprise. The foreign identifier is the identifier of the foreign site where the foreign queue resides (for MSMQ 1.0 applications, the identifier is the identifier of the foreign connected network where the foreign queue resides). The following is the general format used to open the non-transactional and transactional connector queue:

CONNECTOR=ForeignCNGUID                      *Connector queues.
CONNECTOR=ForeignCNGUID;XACTONLY             *Connector Queues (Transactional)
                                              queues.

The following lines of code are example of non-transactional and transactional connector format name strings (note that the format name strings are null-terminated Unicode strings).

Lpwstr Sz = L"CONNECTOR=308FB580-1EB2-11CA-923B-08002B1075A7";
Lpwstr Sz = L"CONNECTOR=308FB580-1EB2-11CA-923B-08002B1075A7\XACTONLY";
For information on | See
Ways to obtain a format name | Obtaining Format Names
The elements and syntax of public format names | Public Format Names
The elements and syntax of private format names | Private Format Names
The elements and syntax of distribution lists format names | Distribution List Format Names
The elements and syntax of multiple-element format names | Multiple-Element Format Names
The syntax of direct format names | Direct Format Names


Queue Handle

A queue handle references an open queue or, when using distribution lists, multicast addresses, or multiple-element format names to send messages, a set of open queues. While the queue is open, applications can use the handle of the queue to perform the following operations:

  • To send messages using the MQSendMessage function.
  • To read messages using the MQReceiveMessage or MQReceiveMessageByLookupId (introduced in MSMQ 3.0) functions
  • To generate a format name for the queue using the MQHandletoFormatName function.
  • To create a cursor using the MQCreateCursor function.
  • To close the queue using the MQCloseQueue function.

Using the Queue Handle Within COM Components

The queue handle is used internally by Message Queuing COM components even though it is not explicitly used by applications. However, the MSMQQueue object exposes the queue handle in the MSMQQueue.Handle property so that applications can call Message Queuing API functions directly. For example, when using Microsoft® Visual Basic®, you can call Message Queuing functions directly using the Declare Function facility.

For information on | See
Referencing a queue by its pathname | Queue Pathnames
Referencing a queue by its format name | Format Names


Queue Alias

A queue alias is an Active Directory object that can be used to reference queues which might not be listed in Active Directory. Using queue aliases provide the following benefits.

  • When a queue alias object is deleted, the alias is automatically removed from all distribution lists that reference the alias.
  • The queue referenced by the queue alias can be changed without changing the alias reference. The alias can be used as a constant reference, as in a distribution list, even though the queue it represents may change.
  • Queue aliases can be used to reference a queue that is not listed in the directory service. This includes private queues or queues from another organization.
  • Queue aliases can be used to send http messages by referencing the destination queue using a direct format name.

The queue alias object has a single Message Queuing attribute: namely a format name that references a queue. Queue aliases can contain public, private, and direct format names (note that the format name for the queue cannot exceed 255 characters).

Once the queue alias is stored in Active Directory, it can be referenced by its ADs path. The following is an example of the ADs path to a queue alias.

"LDAP://CN=QueueAlias,OU=Domain Controllers,DC=DOM,DC=shush,DC=lab"


Creating Queues

Message Queuing provides a single process for creating all queues. The same calls are made to create public queues, private queues, and transactional queues.

Note System queues, such as queue journals, computer journals, and dead-letter queues, can be created only by Message Queuing.

To create a queue, you must specify a pathname for the queue. This pathname is the only queue property necessary to create the queue. However, you can also specify other queue properties, such as the label of the queue. These properties are optional and are needed only if you want to modify the default behavior of the queue.

To create a queue, specify the pathname in a call to the following function or COM method:

  • MQCreateQueue
  • MSMQQueueInfo.Create
For information on | See
Pathnames | Queue Pathnames
Optional queue properties that can be set when creating a queue | Setting Queue Behavior


Setting Queue Behavior

When you create a queue, you can define the behavior of a queue by setting its optional properties. For example, the following properties specify whether the queue can be used in a transaction, whether the queue will accept private message, and several other characteristics:

  • Authentication level—specifies whether the queue will accept all messages, or only those authenticated by Message Queuing.

    The related function property and COM property are:
    PROPID_Q_AUTHENTICATE
    MSMQQueueInfo.Authenticate

  • Priority level—specifies a base priority level for all messages sent to a public queue (the priority level of private queues is always set to 0).

    The related function property and COM property are:
    PROPID_Q_BASEPRIORITY
    MSMQQueueInfo.BasePriority

  • Privacy level—specifies whether the queue will accept only private messages, only non-private messages, or both.

    The related function property and COM property are:
    PROPID_Q_PRIV_LEVEL
    MSMQQueueInfo.PrivLevel

  • Journaling level—specifies whether target journaling is enabled for the queue.

    The related function properties and COM properties are:
    PROPID_Q_JOURNAL
    MSMQQueueInfo.Journal

  • Queue quota—limits the amount of data that can be placed in the queue.

    The related function property and COM property are:
    PROPID_Q_QUOTA
    MSMQQueueInfo.Quota

  • Journal quota—limits the amount of data that can be placed in the queue journal.

    The related function properties and COM properties are:
    PROPID_Q_JOURNAL_QUOTA
    MSMQQueueInfo.JournalQuota

  • Service type—an application-defined or Message Queuing–defined identifier. Applications can use this property to locate a specific type of public queue in the directory service.

    The related function property and COM property are:
    PROPID_Q_TYPE
    MSMQQueueInfo.ServiceTypeGuid

  • Queue label–an application-defined identifier that can be used to identify the queue.

    The related function property and COM property are:
    PROPID_Q_LABEL
    MSMQQueueInfo.Label

  • Queue multicast address (introduced in Whistler)—specifies an address shared by several queues. Messages sent to a multicast address are sent, in turn, to all queues associated with that address.

    The related function property and COM property are:
    PROPID_Q_MULTICAST_ADDRESS
    MSMQQueueInfo.MulticastAddress

  • Transaction level—specifies whether the messages sent to the queue must be sent within a transaction. This property can be set only when the queue is created. When you are using COM components, you set the transaction level indirectly by setting the IsTransactional parameter of the MSMQQueueInfo.Create method.

    The related function property and COM method parameter are:
    PROPID_Q_TRANSACTION
    MSMQQueueInfo.Create (IsTransactional)


Locating Queues

Message Queuing provides a way to query the directory service for a set of public queues based on the properties of the queues. For example, an application could query the directory service for all the public queues with a specific label or query the directory service for a public queue with a specific queue identifier. (Message Queuing provides no mechanism for locating private queues.)

Note Public queues in Windows 2000 enterprises can also be located through the Active Directory Service Interfaces (ADSI).

The illustration below shows a query that has located two queues based on their labels. In this case, the calling application could open either queue to send or read messages (this type of query could be used to provide load balancing when sending messages to queues on different computers). Note that it does not matter where the messages that compose the queue are stored. The only requirement is that the queues are registered in the directory service and that Message Queuing has access to the directory service.

Note Queries cannot be made when the computer is operating in workgroup mode or while the computer is operating offline. Message Queuing must have access to the directory service to query the directory service.

Calls to Locate Public Queues

The API functions and COM methods used to locate public queues are listed below.

  • MQLocateBegin
  • MQLocateNext
  • MQLocateEnd
  • MSMQQuery.LookupQueue

The process that the calling application must follow to perform a query differs slightly depending on what type of calls are made. These differences are summarized below:

  • API function calls

    The search criteria can be any valid queue property other than the pathname of the queue, and the calling application must specify which queue properties that it wants Message Queuing to return as query results.

  • COM method calls

    The search criteria are limited to the queue label, queue identifier, service type, create time, modify time, and multicast address. Message Queuing returns an MSMQQueueInfos object that contains a MSMQQueueInfo object for each queue found in the query.

However, regardless of which type of calls are used, the basic idea is that the calling application specifies the search criteria for the query; runs the query; then performs some action, such as sending a message to one of the returned queues, based on the queue information returned by Message Queuing.

For information on | See
What is required to locate queues using API function calls | Locating Queues Using Function Calls
What is required to locate queues using COM component calls | Locating Queues Using COM Component Calls


Locating Queues Using Function Calls

When you use API functions to locate public queues, you must specify the queue properties that you want Message Queuing to use to locate the queues, and you must also specify the properties that you want Message Queuing to retrieve when the queues are found.

The calling application must perform the following tasks to locate a queue.

  • Specify which queue properties to use as the search criteria, or restrictions, for locating the queues. The search criteria can be based on any queue property except the pathname of the queue.
  • Specify which queue properties to retrieve. You can ask Message Queuing to retrieve any queue property other than DNS pathname of the queue (this property cannot be returned because the DNS pathname is not stored in the directory service.
  • Start the query by calling MQLocateBegin.
  • Get the results of the query by calling MQLocateNext in a loop.
  • When there are no more queues, call MQLocateEnd to free resources.
For information on | See
The structures used to specify the search criteria | Specifying Search Criteria
The structures used to specify which properties to retrieve | Specifying Queue Properties to Retrieve


Specifying Search Criteria

Message Queuing provides two structures that are used to specify the search criteria or restrictions for a query: MQPROPERTYRESTRICTION and MQRESTRICTION. The following example code shows how these two structures are used to define a single-restriction query based on the queue label.

MQPROPERTYRESTRICTION aPropRestriction[MAX_VAR];
MQRESTRICTION Restriction;
DWORD cRestriction = 0;

aPropRestiction[cRestriction].rel          = PREQ;
aPropRestiction[cRestriction].prop         = PROPID_Q_LABEL;
aPropRestiction[cRestriction].prval.vt     = VT_LPWSTR;
aPropRestiction[cRestriction].pwscval  = L"TestQueue";
cRestriction++;

Restriction.cRes         = cRestriction;
Restriction.paPropRes   = aPropRestriction;

Each MQPROPERTYRESTRICTION defines a single property, or restriction, that will be used in the search criteria. You can use any queue property except the pathname (PROPID_Q_PATHNAME) as a search criterion. Also, you can specify a single restriction, as shown in the previous example code, or you can specify several restrictions for the query. For each restriction you must specify the following:

  • Comparison operator. You can use the following comparison operators: less than (PRLT), less than or equal to (PRLE), equal (PREQ), greater than or equal to (PRGE), and greater than (PRGT).
  • Queue property identifier. In the previous example code, the queue service type is specified.
  • Queue property value. The property value is itself a structure. The first element in this structure is the variant type of the property and the second element is the value of the property.

The MQRESTRICTION structure, on the other hand, specifies the number of restrictions used in the search criteria and an array of those restrictions. In the previous example code, Restriction is an MQRISTRICTION structure that contains the count, cProps, in the cRes element and the array, aPropRestiction, in the paPropRes element. Each element of this array is an MQPROPERTYRESTRICTION structure.

For information on | See
The structures used to specify which properties to retrieve | Specifying Queue Properties to Retrieve


Specifying Queue Properties to Retrieve

The column structure MQCOLUMNSET is used to specify which queue properties Message Queuing will return when it finds a queue. This structure contains a count of the properties to be retrieved and a pointer to a QUEUEPROPID array that contains the set of properties to be retrieved.

Note You cannot retrieve the DNS pathname of a queue because the DNS pathname is not stored in the directory service.

The following example code shows a QUEUEPROPID and MQCOULMNSET structure that specifies two properties, the label and pathname of the queue.

QUEUEPROPID   aPropId[MAX_PROP]
MQCOLUMNSET   Column;
DWORD         cColumn = 0;

aPropId{cColumn] = PROPID_Q_LABEL;
cColumn++;

aqPropId[cColumn] = PROPID_Q_PATHNAME;
cColumn++;

Column.cCol = cColumn;
Column.aCol = aqPropId;
For information on | See
The structures used to specify the search criteria | Specifying Search Criteria


Locating Queues Using COM Component Calls

When using COM components to locate public queues, the calling application must specify the search criteria that Message Queuing will use to locate the queues. This search criteria is limited the identifier of the queue, its label, the type of service it provides, when the queue was created, the last time the queue's properties were modified, and the multicast address associated with the queue.

The calling application must perform the following tasks to locate a queue.

  • Specify the search criteria, or restrictions, for locating the queues.
  • Start the query by calling MSMQQuery.LookupQueue. This method returns an MSMQQueueInfos object that contains a MSMQQueueInfo object for each queue Message Queuing found.
  • Look a the query results by calling MSMQQueueInfos.Next to enumerate through the returned MSMQQueueInfos object. Each MSMQQueueInfo object contains the current settings, as registered in the directory service, of all the properties of the queue.
For information on | See
What is required to locate queues using function calls | Locating Queues Using Function Calls


Opening Queues

An application must open a queue before it can send messages to the queue or receive messages from the queue. When the application opens the queue, Message Queuing returns a queue handle that the application can used to perform the following operations:

  • Send messages to one or more (in MSMQ 3.0) destination queues.
  • Peek at or retrieve messages from a single queue.
  • Create cursors for navigating through the queue (Message Queuing COM components provide a single implicit cursor each time a queue is open).
  • Create format names.
  • Close the queue.

In the call to open the queue, the application must specify three pieces of information:

  • The queue format name.
  • The access mode.
  • The share mode.

Format Names

An application uses different kinds of format names to open a queue depending on how you want messages to be routed and on the type of the destination:

  • Direct format names are used to send messages directly to a specific computer or receive messages from a local queue without accessing the directory service. When messages are sent directly to a remote queue, Message Queuing provides no routing support.
  • Public format names are used to open public queues and their journals. For examples of public format name syntax, see Public Format Names.
  • Private format names are used to open private queues and their journals. For examples of public format name syntax, see Private Format Names.
  • Distribution list format names (introduced in MSMQ 3.0) are used to send messages to multiple destination queues (distribution lists cannot be used to read messages in a queue). For examples of public format name syntax, see Distribution List Format Names.
  • Multicast address format names (introduced in MSMQ 3.0) are used to send messages to all queues associated with a specific multicast address (multicast addresses cannot be used to read messages in a queue). For examples of multicast addresses forma name syntax, see Multicast Address Format Names.
  • Multiple-element format names (introduced in MSMQ 3.0) are used to send messages to multiple destinations (multiple-element format names cannot be used to read messages in a queue). For examples of multiple-element format name syntax, see Multiple-element format names.
  • Machine format names are used to read messages from computer journal and dead-letter queues (machine format names cannot be used to read messages in journal and dead-letter queues). For examples of machine format name syntax, see Machine and Connector Format Names.
  • Connector format names are used by connector applications to read messages from the connector queues on the local connector server (connector format names cannot be used to read messages from connector queues). For examples of connector format name syntax, see Machine and Connector Format Names.

Access Mode

The access mode tells Message Queuing how to open the queue ( with send, peek, or receive access). Message Queuing then compares the specified access mode with the registered access rights of the queue and determines whether to grant or deny the application access to the queue.

Share Mode

The share mode of the queue specifies who else can open the queue while your application has it open. The share mode of the queue can be set to MQ_DENY_NONE (the default) or MQ_DENY_RECEIVE_SHARE.

When opening a queue to send messages, always set the share mode of the queue to MQ_DENY_NONE. This allows everyone full access to send, peek at, or retrieve messages from the queue while you have the queue open.

When opening a queue to peek at or retrieve messages, you can specify MQ_DENY_NONE to share the queue with everyone, or you can set the share mode to MQ_DENY_RECEIVE_SHARE so that only you can peek at or retrieve messages until you close the queue (note that other applications can still send messages to the queue). You can also use MQ_DENY_RECEIVE_SHARE to stop others from deleting messages while you have the queue open.

The following error conditions can occur when the access mode is set to MQ_DENY_RECEIVE_SHARE.

  • After Message Queuing opens the queue, an error message is returned if anyone, including yourself, tries to open the queue with peek or receive access.
  • If you try to open the queue with MQ_DENY_RECEIVE_SHARE and the queue is already open with peek or retrieve access, your call will fail.
For information on | See
How MSMQ opens local queues. | Opening Local Queues
How MSMQ opens remote queues. | Opening Remote Queues
How MSMQ opens queues with a direct format name. | Opening Queues with a Direct Format Name


Opening Local Queues

The following illustration shows how Message Queuing opens local queues when an application specifies a non-direct format name in the call to open the queue (this includes non-direct format names referenced in distribution lists and multiple-element format names).

This process is the same no matter what access mode you choose—send, peek, or receive access.

When an application makes its call to open a local queue, Message Queuing takes the following actions:

  • The Message Queuing run-time contacts the local queue manager, sending a request to open the queue.
  • The local queue manager determines if the queue is a public or private queue.
  • If the queue is public, the local queue manager contacts the directory service to get the registered properties of the queue and then checks to see if the queue is local or remote. In this case, the queue is local so the queue manager contacts the directory service again to retrieve the security descriptor of the queue.
  • If the queue is private, the local queue manager looks at the queue identifier (GUID) included in the format name to see if the queue is local or remote. In this case, the queue is local so the queue manager retrieves the properties and security descriptor of the queue from the local LQS file.
  • After getting the properties and security descriptor for the queue, the queue manager checks the access rights of the queue.
  • If the caller has sufficient access rights to open the queue, the queue manager creates a queue object and returns a handle for this object to the local run-time. (If the queue is being opened with send access, the queue manager checks the access rights of the queue only when it is a local queue. For remote queues, access rights are checked by the queue manager on the remote computer where the queue resides.)
  • The local MSMQ run-time then passes the handle on to the calling application.

After Message Queuing completes this process for each local queue, the application can then send, peek at, or retrieve messages based on the access mode specified in the call to open the queues.

For information on | See
What is required to open a queue | Opening Queues
How MSMQ opens remote queues | Opening Remote Queues
How MSMQ opens queues with a direct format name | Opening Queues with a Direct Format Name


Opening Remote Queues

The process for opening non-direct remote queues varies, depending on whether you are opening the remote queue to send message or whether you are opening the remote queue to peek at or retrieve message.

One of the main differences between opening a remote queue for sending messages, compared to peeking at or retrieving message, is the network traffic that is generated by both the local computer and the remote computer where the queue resides.

When you open remote queues with send access, there is no connection to the remote computer until a message is sent to the computer.

When you open a remote queue to peek at or retrieve its messages, both the local and remote queue managers call the directory service. Both queue managers also exchange RPC calls with each other, and the local run-time and the remote queue manager exchange calls as well.

For information on | See
How MSMQ opens remote queues to send messages. | Opening Remote Queues with Send Access
How MSMQ opens remote queues to peek at or retrieve messages. | Opening Remote Queues with Peek or Receive Access
How MSMQ opens local queues. | Opening Local Queues
How MSMQ opens queues with a direct format name. | Opening Queues with a Direct Format Name
What is required to open a queue. | Opening Queues


Opening Remote Queues with Send Access

The following illustration shows what the local queue manager does when it receives a request to open a remote queue with send access (this is the same process as for opening local queues, with the exception that local queue manager does not check the access rights of the queue). Note that when opening a queue to send messages, there is no contact with the remote computer.

When your application makes its call to open the remote queue, the following actions are taken.

  • The MSMQ run-time contacts the local queue manager, sending a request to open the queue.
  • The local queue manager determines if the queue is public or private .
  • If the queue is public, the queue manager contacts the directory service to get the registered properties of the queue.
  • If the queue is private, the queue manager looks at the queue identifier (GUID) included in the format name to determine if the queue is local or remote.
  • When the queue manager determines that the queue is remote, the queue manager creates a queue object and returns a handle for the queue to the local run-time. Note that the local queue manager does not check the access rights of the queue.
  • The local run-time then passes the handle on to the calling application.

After this process is complete, you can send messages to the remote computer. Since the local queue manager does not check the access rights of the queue when you open a remote queue to send messages, the access rights of the queue are checked by the remote queue manager when you send a message. When opening a queue with send access, the queue's access rights are always checked by the queue manager on the computer where the queue resides.

For information on | See
How MSMQ opens remote queues to peek at or retrieve messages. | Opening Remote Queues with Peek or Receive Access
How MSMQ opens local queues. | Opening Local Queues
What is required to open a queue. | Opening Queues


Opening Remote Queues with Peek or Receive Access

When you open a remote queue to peek at or retrieve messages, both computers, as part of the process, contact the directory service and contact each other, as shown in the following illustration.

When your application makes its call to open the remote queue with peek or receive access, the following actions are taken.

  • The MSMQ run-time contacts the local queue manager, sending a request to open the queue.
  • The local queue manager determines if the queue is public or private.
  • If the queue is public, the queue manager contacts the directory service to get the registered properties of the queue. It then checks to see if the queue is local or remote. When the queue manager determines that the queue is remote, it returns the name of the remote computer to the local run-time.
  • If, on the other hand, the queue is private, the queue manager looks at the queue identifier (GUID) included in the format name to see if the queue is local or remote. When the queue manager determines that the queue is remote, it returns the name of the remote computer to the local run-time, just as for a public queue.
  • The local run-time then contacts the remote queue manager, sending a request to open the queue.
  • The remote queue manager then begins the process of creating the queue object.
  • If the queue is public, the queue manager contacts the directory service, in two separate calls, one to get the properties and one to get the security descriptor of the queue.
  • If the queue is private, it gets the properties and security descriptor of the queue from the local LQS file.
  • Using the properties and security descriptor of the queue, the remote queue manager checks the access rights of the queue, and if the caller has sufficient access rights, the queue manager creates a queue object and returns it to the run-time on the local computer.
  • The local run-time then contacts the local queue manager, passing on the queue handle from the remote queue manager.
  • The local queue manager then makes a proxy object that represents the remote queue object, opens a virtual session with the remote queue manager (using an RPC context handle), and returns a handle to the proxy object it created.
  • The local run-time then passes the handle to the proxy object on to the calling application.

Note Note that when you open a remote queue for peek or receive access, MSMQ can return an MQ_ERROR_QUEUE_NOT_FOUND error message from one of two sources. The error message can be returned by the local queue manager or by the remote queue manager.

For information on | See
How MSMQ opens remote queues to send messages. | Opening Remote Queues with Send Access
How MSMQ opens local queues. | Opening Local Queues
What is required to open a queue. | Opening Queues


Opening Queues with a Direct Format Name

When you open queues with a direct format name, there is no connection to the directory service or the computer where the queue resides. The local queue manager gets the request to open the queue from the local run-time and determines the target computer by the address specification of the format name. The queue manager then creates the queue object and returns a handle to this object to the run-time.

Typically, remote queues are opened with direct format names to send messages directly to the remote queue. However, when you are operating offline, your computer has no connection to the directory service or other remote computers. In these circumstances, you can use direct format names to open local public or private queues without having to obtain and cache their public or private format names in advance while you are still online.

For information on | See
Direct format name syntax | Direct Format Names
How MSMQ opens local queues. | Opening Local Queues
How MSMQ opens remote queues. | Opening Remote Queues
What is required to open a queue. | Opening Queues


Opening Multiple Queues

Message Queuing (MSMQ 3.0 only) provides distribution list and multiple-element format names for sending a message to multiple destination queues. These format names can be used to open any number of queues with send access (Message Queuing returns an error if an attempt is made to open multiple queues with peek or receive access).

Distribution list format names contain the GUID identifier of the distribution list object that is stored in the directory service (distribution lists are public lists stored in the directory service). A distribution list can contain any number of public queues, queue aliases (queue aliases can be used to include private queues), and other distribution lists.

Multiple-element format names are extension of the single element format names used to send one message to one destination queue. They are a concatenation of one or more public format names, private format names, direct format names, or distribution lists.

Unlike distribution lists, multiple-element format names are not stored in Active Directory and must be created and maintained by the application that is sending the messages.

When using distribution lists and multiple-element format names, consider the following issues.

  • Messages sent to multiple destination all have the same message identifier. For example, if a message is sent to three destination queues the message identifier of all three messages in the queues will be the same.
  • Do not include format names for read-only queues such queue journals, computer journals, or dead letter queues. An error is returned if the format name of a read-only queue is included in a distribution lists or multiple-element format name.
  • Distribution lists and multiple-element format names may contain multiple references to the same destination. However, the source Queue Manger ignores duplicate references when it opens the destinations for sending messages. For example, if distribution list D1 explicitly specifies Q1 plus another distribution list D2, it may be possible that distribution list D2 also contains Q1 or D1. In this case, the duplicate Q1 and D1 references in distribution list D2 are ignored by the Queue manager.
For information on | See
Distribution list name syntax | Distribution List Format Names
Multiple-element name syntax | Multiple-Element Format Names


Navigating Queues

When retrieving messages, receiving applications can navigate through the messages of a queue using cursors or message lookup identifiers (introduced in Whistler). When using cursors, the receiving application starts at the front of the queue and moves sequentially toward the end of the queue. When using message lookup identifiers, the receiving application can start at the front of the queue, at a message associated with a specific lookup identifier, or at the end of the queue. Once a message is read using a message identifier, the receiving application can navigate towards the front or the end of the queue.

For information on | See
How lookup Identifiers can be used to read messages in a queue | Navigating with Lookup Identifiers
How cursors can be used to read the messages in a queue | Navigating with Cursors


Navigating with Lookup Identifiers

Lookup identifiers (introduced in Whistler) are a 64-bit identifiers that are assigned to each message when the message is placed in the queue (note that the message identifier has no meaning to the sending application). The local queue manager generates the lookup identifier and sets the lookup identifier property of the message (PROPID_M_LOOKUPID and MSMQMessage.LookupId) whenever it places a message in a queue.

Message Queuing generates a lookup identifier for all messages that are placed in queues. This includes messages sent by sending applications and Message Queuing. Note that if a message is sent to several destination queues, or if a copy of a message is stored in a computer journal or queue journal, each copy of the message will have its own lookup identifier when it is placed in its respective queue.

Lookup identifiers are used to read a specific message in the queue. Once the lookup identifier of a message is known, the receiving application can go directly to that message and then continue navigating the queue from that point. Unlike cursors that must start at the front of the queue an navigate towards the end of the queue, the receiving application can use lookup identifier calls to go directly to a message and navigate toward the front or the end of the queue.

The illustration below shows the different function and method calls used to peek at the first message in the queue, the previous, current, or next message of a specific message, and the last message in the queue.

For Information On | See
Retrieving the lookup identifier of a message | Retrieving the Lookup Identifier of a Message


Retrieving the Lookup Identifier of a Message

The local queue manager generates the lookup identifier and sets the lookup identifier property of the message (PROPID_M_LOOKUPID and MSMQMessage.LookupId) whenever it places a message in a queue. However, the local Queue Manger does not notify the receiving application that a message with a specific lookup identifier arrived at the queue.

Consequently, the receiving application is responsible for retrieving and caching the lookup identifiers of all the messages that it may want to retrieve.

One way the receiving application can do this is to have a Message Queuing trigger associated with the queue so that every time a message is placed in the queue the trigger is fired. The trigger could invoke a component that retrieves the message identifier (or some other message property that identifies the message) and lookup identifier of each message that the receiving application may want to retrieve. The trigger could retrieve the lookup identifier of every messages that is placed in the queue or only those messages that have a specific label, correlation identifier, or some other message property. For information on triggers, see Message Queuing Triggers.


Navigating with Cursors

Cursors are defined by the receiving application or, when using COM components, by Message Queuing. Unlike lookup identifiers that are associated with specific messages, cursors are associated with specific queues.

Cursors are used to navigate queues to filter out messages that have a specific characteristic. For example, all message that have the same message label or correlation identifier. Receiving application can use cursors for reading messages both synchronous and asynchronous.

Note Do not use the same cursor when firing receive calls in overlapping operations. Firing a second receive call (using the same cursor) before the first one is completed leads to unexpected behavior.

Receiving applications using function calls can create and use any number of cursors to navigate through a queue. Each cursor is independent of all other cursors, including cursors created by other applications, so moving one cursor has no effect on where another cursor is pointing.

Receiving applications using COM components can only use a single cursor for each queue object. However, the receiving application can open the queue several times, with each instance of the queue object providing its own cursor.

There is no limit to the number of applications or the number of cursors that can be used to navigate through a specific queue. You can have several applications with different cursors pointing to a single queue; you can have one application using several cursors on a single queue (with applications using COM methods, you can do this by using multiple instances of the queue); or you can have multiple applications as well as multiple cursors pointing to any combination of queues.

When retrieving messages within a transaction, Message Queuing does not roll back cursor movement if the transaction is aborted. For example, given a queue with two messages A and B, if you remove message A while in a transaction, Message Queuing will move the cursor to the next message B. However, if the transaction is aborted for any reason, message A is inserted back into the queue, yet the cursor will remain pointing at message B.

For information on | See
How the message is moved to the first message when the cursor is created. | Cursor Behavior when Creating a Cursor
How the cursor is moved when peeking at messages | Cursor Behavior when Peeking at Messages
How the cursor is moved when retrieving messages | Cursor Behavior when Retrieving Messages
How the cursor is moved when reaching the end of the queue | Cursor Behavior when Reaching the End of the Queue
How multiple cursors interact | Cursor Behavior when using Multiple Cursors
How the cursor behaves when waiting for new messages at the end of the queue. | Cursor Behavior when Waiting for New Messages
How the cursor behaves when trying to read a message that was removed by someone else. | Cursor Behavior when Messages are Not Available
How the behaves when errors occur. | Cursor Behavior Due to Errors
How the cursor behaves when trying to read messages from a deleted queue | Cursor Behavior and Deleted Queue
How the cursor moves when the queue contains messages with different message priority levels. | Cursor Behavior and Message Priority
Summary of COM methods that use cursors for synchronous and asynchronous operations | Cursors and COM Components


Cursor Behavior when Creating a Cursor

Before a cursor can be used, the cursor must be created and moved to the first message location in the queue (note that cursors point to message location, not to specific messages).

Cursors are created in two ways, depending on the type of calls used by the receiving application. When using function calls, the receiving application must create the cursor by calling the MQCreateCursor function. When using COM components, Message Queuing automatically creates a cursor when the queue is opened.

After the cursor is created, the receiving application must explicitly move the cursor to the first message location in the queue (even if there are no messages in the queue). The illustration below shows the function and method call used to move the cursor to the first message location.

For information on | See
How the cursor is moved when peeking at messages | Cursor Behavior when Peeking at Messages
How the cursor is moved when retrieving messages | Cursor Behavior when Retrieving Messages
How the cursor is moved when reaching the end of the queue | Cursor Behavior when Reaching the End of the Queue
How multiple cursors interact | Cursor Behavior when using Multiple Cursors
How the cursor behaves when waiting for new messages at the end of the queue. | Cursor Behavior when Waiting for New Messages
How the cursor behaves when trying to read a message that was removed by someone else. | Cursor Behavior when Messages are Not Available
How the behaves when errors occur. | Cursor Behavior Due to Errors
How the cursor behaves when trying to read messages from a deleted queue | Cursor Behavior and Deleted Queue
How the cursor moves when the queue contains messages with different message priority levels. | Cursor Behavior and Message Priority
Summary of COM methods that use cursors for synchronous and asynchronous operations | Cursors and COM Components


Cursor Behavior when Peeking at Messages

If the receiving application is peeking at the current message (the message is not removed from the queue), the cursor remains pointing at the current message location and the application must move the cursor.

The following illustration shows the function and COM method calls used to peek at the current message then move the cursor to the next message. Note that in this illustration, the first call moves the cursor to the first message location in the queue and peeks at the message at that location, then all subsequent calls move the cursor to the next message location until the cursor is at the end of the queue.

When the cursor reaches the end of the queue, it waits for a new message to arrive or a time-out to occur. If a new message arrives the cursor is always moved to the new messages, regardless of where the message is placed in the queue. Typically messages are inserted at the end of the queue, however, messages can be placed anywhere within the queue depending on their priority level.

For information on | See
How the message is moved to the first message when the cursor is created. | Cursor Behavior when Creating a Cursor
How the cursor is moved when retrieving messages | Cursor Behavior when Retrieving Messages
How the cursor is moved when reaching the end of the queue | Cursor Behavior when Reaching the End of the Queue
How multiple cursors interact | Cursor Behavior when using Multiple Cursors
How the cursor behaves when waiting for new messages at the end of the queue. | Cursor Behavior when Waiting for New Messages
How the cursor behaves when trying to read a message that was removed by someone else. | Cursor Behavior when Messages are Not Available
How the behaves when errors occur. | Cursor Behavior Due to Errors
How the cursor behaves when trying to read messages from a deleted queue | Cursor Behavior and Deleted Queue
How the cursor moves when the queue contains messages with different message priority levels. | Cursor Behavior and Message Priority
Summary of COM methods that use cursors for synchronous and asynchronous operations | Cursors and COM Components


Cursor Behavior when Retrieving Messages

When messages are retrieved from the queue Message Queuing moves the cursor to the next message (or to the end of the queue) for the receiving application. Message Queuing automatically moves the cursor to the next location in the queue when the subsequent peek-current or receive-current operation is performed (this does not apply to other cursors that may be pointing to the same message).

Note Do not perform a peek-next operation immediately after a message is removed from the queue. Message Queuing has already moved the cursor for you. If you do, Message Queuing will return an error indicating you are trying to skip a message. Always perform a peek-current operation or another receive-current operation after removing a message from the queue.

The following illustration shows the function and COM method calls used to retrieve a message from the queue and look at the next message. Note that this example starts with the cursor already pointing a message B. If the receiving application wants to remove the message it makes a receive-current call to remove the message, then the following peek-current call moves the cursor to Message C.

When the last message in a queue is retrieved, Message Queuing moves the cursor to the end of the queue when the next peek or receive current operation is called, and then waits for a new message or a time-out to occur.

When a new message arrives the cursor is always moved to the new messages, regardless of where the message is placed in the queue. Typically messages are inserted at the end of the queue, however, messages can be placed anywhere within the queue depending on their priority level.

For information on | See
How the message is moved to the first message when the cursor is created. | Cursor Behavior when Creating a Cursor
How the cursor is moved when peeking at messages | Cursor Behavior when Peeking at Messages
How the cursor is moved when reaching the end of the queue | Cursor Behavior when Reaching the End of the Queue
How multiple cursors interact | Cursor Behavior when using Multiple Cursors
How the cursor behaves when waiting for new messages at the end of the queue. | Cursor Behavior when Waiting for New Messages
How the cursor behaves when trying to read a message that was removed by someone else. | Cursor Behavior when Messages are Not Available
How the behaves when errors occur. | Cursor Behavior Due to Errors
How the cursor behaves when trying to read messages from a deleted queue | Cursor Behavior and Deleted Queue
How the cursor moves when the queue contains messages with different message priority levels. | Cursor Behavior and Message Priority
Summary of COM methods that use cursors for synchronous and asynchronous operations | Cursors and COM Components


Cursor Behavior when Reaching the End of the Queue

The end of the queue can be thought of as a message location even though no message is there. When the cursor reaches this location, it waits for a new message to arrive or a time-out to occur.

Note If your application tries to move past the end of the queue an MQ_ERROR_ILLEGAL_CURSOR_ACTION error is returned. For example, if you retrieve the last message in the queue and then try to do a peek-next operation, MQ_ERROR_ILLEGAL_CURSOR_ACTION error is returned

The cursor can point to end of the queue as a result of the following operations:

  • The cursor points to a queue that contains no messages.
  • The cursor is moved to the end of the queue by the receiving application performing a peek-next operation.
  • The cursor is moved to the end of the queue by Message Queuing when the last message in the queue is removed.

When the cursor is waiting at the end of the queue and a new message arrives, Message Queuing moves the cursor to the location of the new message, regardless of where the new message is placed in the queue. Typically, messages are inserted at the end of the queue; however, messages can be placed in other locations depending on the priority level of the new message and the priority level of the messages already in the queue.

For information on | See
How the message is moved to the first message when the cursor is created. | Cursor Behavior when Creating a Cursor
How the cursor is moved when peeking at messages | Cursor Behavior when Peeking at Messages
How the cursor is moved when retrieving messages | Cursor Behavior when Retrieving Messages
How multiple cursors interact | Cursor Behavior when using Multiple Cursors
How the cursor behaves when waiting for new messages at the end of the queue. | Cursor Behavior when Waiting for New Messages
How the cursor behaves when trying to read a message that was removed by someone else. | Cursor Behavior when Messages are Not Available
How the behaves when errors occur. | Cursor Behavior Due to Errors
How the cursor behaves when trying to read messages from a deleted queue | Cursor Behavior and Deleted Queue
How the cursor moves when the queue contains messages with different message priority levels. | Cursor Behavior and Message Priority
Summary of COM methods that use cursors for synchronous and asynchronous operations | Cursors and COM Components


Cursor Behavior when using Multiple Cursors

When multiple cursors are being used to read the messages in a single queue, each cursor moves independently of the others. The following illustration shows how two cursors behave independently of a third cursor.

Note Multiple cursors should not be used if any application is reading messages through transactions. When reading messages within a transaction, Message Queuing does not roll back cursor movement if the transaction is aborted. For example, given a queue with two messages A and B, if you remove message A while in a transaction Message Queuing will move the cursor to the next message B. However, if the transaction is aborted for any reason, message A is inserted back into the queue, yet the cursor will remain pointing at message B.

Here, one cursor (Cursor 2) is pointing at a message (Message C) while the other cursor (Cursor 1) is removing messages from the queue. Cursor 1 removes messages from the queue with several receive calls while Cursor 2 remains pointing to Message C. After Cursor 1 removes Message C, Cursor 2 no longer points to a message. Cursor 2 is now pointing to a message placeholder, and an error is returned if the receiving application tries to read a message at the current Cursor 2 location. However, Cursor 2 can still be used in a peek-next operation to move the cursor to the next message.

For information on | See
How the message is moved to the first message when the cursor is created. | Cursor Behavior when Creating a Cursor
How the cursor is moved when peeking at messages | Cursor Behavior when Peeking at Messages
How the cursor is moved when retrieving messages | Cursor Behavior when Retrieving Messages
How the cursor is moved when reaching the end of the queue | Cursor Behavior when Reaching the End of the Queue
How the cursor behaves when waiting for new messages at the end of the queue. | Cursor Behavior when Waiting for New Messages
How the cursor behaves when trying to read a message that was removed by someone else. | Cursor Behavior when Messages are Not Available
How the behaves when errors occur. | Cursor Behavior Due to Errors
How the cursor behaves when trying to read messages from a deleted queue | Cursor Behavior and Deleted Queue
How the cursor moves when the queue contains messages with different message priority levels. | Cursor Behavior and Message Priority
Summary of COM methods that use cursors for synchronous and asynchronous operations | Cursors and COM Components


Cursor Behavior when Waiting for New Messages

When waiting for a message at the end of the queue, the cursor will automatically point to a new message when one arrives. When the new message and the messages already in the queue all have the same priority level, the new message is placed at the end of the queue where the cursor is waiting. In this case, the cursor is already pointing at the location of the new message and the receiving application can process the message and return the cursor to the end of the queue.

However, when messages with different priority levels arrive at the queue, they are placed in the queue according to their priority. In this case, Message Queuing moves the cursor to the location of the new message where the receiving application can process the message, but the receiving application will have to decide how it wants to proceed. Because the cursor may be at some location within the queue, the message at the next location may be a message that the application has already processed.

When waiting for messages, when the cursor is pointing at the end of the queue, the cursor is always moved to the location of the newest message that arrives at the queue.

For information on | See
How the message is moved to the first message when the cursor is created. | Cursor Behavior when Creating a Cursor
How the cursor is moved when peeking at messages | Cursor Behavior when Peeking at Messages
How the cursor is moved when retrieving messages | Cursor Behavior when Retrieving Messages
How the cursor is moved when reaching the end of the queue | Cursor Behavior when Reaching the End of the Queue
How multiple cursors interact | Cursor Behavior when using Multiple Cursors
How the cursor behaves when trying to read a message that was removed by someone else. | Cursor Behavior when Messages are Not Available
How the behaves when errors occur. | Cursor Behavior Due to Errors
How the cursor behaves when trying to read messages from a deleted queue | Cursor Behavior and Deleted Queue
How the cursor moves when the queue contains messages with different message priority levels. | Cursor Behavior and Message Priority
Summary of COM methods that use cursors for synchronous and asynchronous operations | Cursors and COM Components


Cursor Behavior Due to Errors

When errors occur, the cursor is never reset yet it may be advanced. For example, when an error occurs while trying to read the current message the cursor is not moved, yet the peek-next operation will always move the cursor even if an error occurs.

Note The cursor does not move when there is an invalid handle. For example, if you use MSMQQueue.PeekNext and get a buffer overflow error, subsequent MSMQQueue.PeekCurrent operations return the same message and not the message pointed to before MSMQQueue.PeekNext.

For information on | See
How the message is moved to the first message when the cursor is created. | Cursor Behavior when Creating a Cursor
How the cursor is moved when peeking at messages | Cursor Behavior when Peeking at Messages
How the cursor is moved when retrieving messages | Cursor Behavior when Retrieving Messages
How the cursor is moved when reaching the end of the queue | Cursor Behavior when Reaching the End of the Queue
How multiple cursors interact | Cursor Behavior when using Multiple Cursors
How the cursor behaves when waiting for new messages at the end of the queue. | Cursor Behavior when Waiting for New Messages
How the cursor behaves when trying to read a message that was removed by someone else. | Cursor Behavior when Messages are Not Available
How the cursor behaves when trying to read messages from a deleted queue | Cursor Behavior and Deleted Queue
How the cursor moves when the queue contains messages with different message priority levels. | Cursor Behavior and Message Priority
Summary of COM methods that use cursors for synchronous and asynchronous operations | Cursors and COM Components


Cursor Behavior when Messages are Not Available

Although the cursor may point to message location, there is no guarantee that a message is actually there. Messages may be removed by the same receiving application using another cursor, by another receiving application, by Message Queuing when a message time-out occurs, by purging the queue through the Active Directory Manager, or the queue may be deleted.

If the receiving application tries to peek at or retrieve a message that has been removed, the cursor is no longer pointing at a message and an MQ_ERROR_MESSAGE_ALREADY_RECEIVED error is returned to the call.

For information on | See
How the message is moved to the first message when the cursor is created. | Cursor Behavior when Creating a Cursor
How the cursor is moved when peeking at messages | Cursor Behavior when Peeking at Messages
How the cursor is moved when retrieving messages | Cursor Behavior when Retrieving Messages
How the cursor is moved when reaching the end of the queue | Cursor Behavior when Reaching the End of the Queue
How multiple cursors interact | Cursor Behavior when using Multiple Cursors
How the cursor behaves when waiting for new messages at the end of the queue. | Cursor Behavior when Waiting for New Messages
How the behaves when errors occur. | Cursor Behavior Due to Errors
How the cursor behaves when trying to read messages from a deleted queue | Cursor Behavior and Deleted Queue
How the cursor moves when the queue contains messages with different message priority levels. | Cursor Behavior and Message Priority
Summary of COM methods that use cursors for synchronous and asynchronous operations | Cursors and COM Components


Cursor Behavior and Message Priority

When messages with different priority levels are sent to a queue, Message Queuing inserts each message in a location based on its individual priority level and the priority levels of the messages already in the queue; new messages are not necessarily added to the end of the queue. As a result, when you are moving a cursor sequentially through the queue, messages may be inserted before or after the cursor.

This means that if the cursor is pointing to a message (not the end of the queue) whose priority level is 3, your application will miss any higher-priority messages that reach the queue. Messages with the same or lower priority will not be missed because they are inserted between the cursor and the end of the queue.

However, if the cursor is waiting for a new message at the end of the queue, Message Queuing will move the cursor to the location of the new message regardless of where it is placed in the queue.

Note Messages with the same priority are placed in chronological order. For example, a new priority 1 message is placed at the front of the queue if no other priority 1 messages exist, or following any priority 1 messages if others already exist.

For information on | See
How the message is moved to the first message when the cursor is created. | Cursor Behavior when Creating a Cursor
How the cursor is moved when peeking at messages | Cursor Behavior when Peeking at Messages
How the cursor is moved when retrieving messages | Cursor Behavior when Retrieving Messages
How the cursor is moved when reaching the end of the queue | Cursor Behavior when Reaching the End of the Queue
How multiple cursors interact | Cursor Behavior when using Multiple Cursors
How the cursor behaves when waiting for new messages at the end of the queue. | Cursor Behavior when Waiting for New Messages
How the cursor behaves when trying to read a message that was removed by someone else. | Cursor Behavior when Messages are Not Available
How the behaves when errors occur. | Cursor Behavior Due to Errors
How the cursor behaves when trying to read messages from a deleted queue | Cursor Behavior and Deleted Queue
Summary of COM methods that use cursors for synchronous and asynchronous operations | Cursors and COM Components


Cursors and COM Components

When the receiving application calls the COM components provided by Message Queuing, a cursor is automatically created each time a queue is opened to retrieve messages. Once the queue is opened, the following methods can be called to peek at and retrieve the messages in the queue

  • MSMQQueue.PeekCurrent

    Peeks at the message at the current cursor position. When the receiving application peeks at the message, it must call MSMQQueue.PeekNext to move the cursor to the next message.

    This method is also used to move the cursor to the first message location before messages can be retrieved.

  • MSMQQueue.ReceiveCurrent

    Retrieves the message at the current cursor position, removing it from the queue. When a message is removed from the queue Message Queuing moves the cursor to the next message location when the next MSMQQueue.PeekCurrent or MSMQQueue.ReceiveCurrent call is made.

  • MSMQQueue.PeekNext

    Moves the cursor to the next message location and peeks at the message.

  • MSMQQueue.EnableNotification

    Enables notification for asynchronous opererations.

Synchronously Reading Messages

A typical mechanism for synchronously reading the messages in a queue is to call MSMQQueue.PeekCurrent to peek at the first message in the queue (when the cursor is created it does not point to the first message in the queue). Then use a loop construct to process each message in the queue. To remove the message call MSMQQueue.ReceiveCurrent followed by MSMQQueue.PeekCurrent to peek at the next message. To leave the message call MSMQQueue.PeekNext to move the cursor and peek at the next message.

Note When MSMQQueue.ReceiveCurrent is called, Message Queuing moves the cursor to the next message when the next receive or peek operation is called. If you try to move the cursor by calling MSMQQueue.PeekNext directly after calling MSMQQueue.ReceiveCurrent, an error is returned because Message Queuing is already moving the cursor.

Asynchronously Reading Messages

When you asynchronously read the messages in the queue, calls to MSMQQueue.EnableNotification can also affect the cursor. When this method's Cursor parameter is set to MQMSG_NEXT, the cursor is moved to the next message in the queue when the Arrived event is fired.

Note When enabling notification, use caution in making calls to MSMQQueue.Peek or MSMQQueue.Receive. These calls do not use the cursor and are always pointing to the first message in the queue.

Receive Methods That Do Not Use Cursors

The following methods should not be called by the receiving application if the application is using the cursor to navigate through the queue. The first two methods always peek at or retrieve the first message in the queue regardless of cursor position. The remaining methods use the message lookup identifier to identify a message, not the cursor.

  • MSMQQueue.Peek
  • MSMQQueue.Receive
  • MSMQQueue.PeekByLookupId
  • MSMQQueue.PeekFirstByLookupId
  • MSMQQueue.PeekPreviousByLookupId
  • MSMQQueue.PeekNextByLookupId
  • MSMQQueue.PeekLastByLookupId
  • MSMQQueue.ReceiveByLookupId
  • MSMQQueue.ReceiveFirstByLookupId
  • MSMQQueue.ReceivePreviousByLookupId
  • MSMQQueue.ReceiveNextByLookupId
  • MSMQQueue.ReceiveLastByLookupId
For information on | See
How the message is moved to the first message when the cursor is created. | Cursor Behavior when Creating a Cursor
How the cursor is moved when peeking at messages | Cursor Behavior when Peeking at Messages
How the cursor is moved when retrieving messages | Cursor Behavior when Retrieving Messages
How the cursor is moved when reaching the end of the queue | Cursor Behavior when Reaching the End of the Queue
How multiple cursors interact | Cursor Behavior when using Multiple Cursors
How the cursor behaves when waiting for new messages at the end of the queue. | Cursor Behavior when Waiting for New Messages
How the cursor behaves when trying to read a message that was removed by someone else. | Cursor Behavior when Messages are Not Available
How the behaves when errors occur. | Cursor Behavior Due to Errors
How the cursor behaves when trying to read messages from a deleted queue | Cursor Behavior and Deleted Queue
How the cursor moves when the queue contains messages with different message priority levels. | Cursor Behavior and Message Priority
Summary of COM methods that use cursors for synchronous and asynchronous operations | Cursors and COM Components
How lookup Identifiers can be used to read messages in a queue | Navigating with Lookup Identifiers


Cursor Behavior and Deleted Queues

When the receiving application tries to retrieve a message from an open queue that has been deleted (typically by another application or a Message Queuing administrator using Active Directory Manager), Message Queuing returns an MQ_ERROR_QUEUE_DELETED error to any subsequent receive and peek operations.


Queue Properties

The properties of a queue contain the settings that define the behavior of the queue. They contain data that can be provided programmatically, such as the pathname of the queue, as well as data that is set only by Message Queuing.

The properties of a queue are stored in one of the following loactions.

  • For public queues, their properties are stored in the Directory Service.
  • For private queues, their properties are stored on the computer where the queue resides.

Typically, queue properties are set when the queue is created, however most properties can also be changed later when the need arises (changing properties later does not effect any messages that are already in the queue).

Queue properties can be used to locate any number of public queues registered in the Directory Service. For example, applications can query the Directory Service for all queues with the same label or all queues created before (or after) a certain date and time. (Message Queuing COM components limits which properties can be used in the query.)

Message Queuing uses an MQQUEUEPROPS structure to define queue properties. When using API function calls, this structure is explicitly declared and filled in by the application that is setting queue properties, retrieving queue properties, or attempting to locate public queues. When using COM component, the MQQUEUPROPS structure is declared and filled in by Message Queuing when the application references the properties of the MSMQQueueInfo or MSMQQuery objects.


The Queue Property Structure

The MQQUEUEPROPS structure, shown below, includes a property count member to indicate the number of properties included in the structure, an array the identifies each property (aPropID), an array that specifies the value of each property (aPropVar), and an array for the returned status of each property (aStatus). Position i in each of the three arrays contains information about a single property.

typedef struct tagMQQUEUEPROPS
{
  DWORD          cProp;
  QUEUEPROPID    *aPropID;
  MQPROPVARIANT  *aPropVar;
  HRESULT        *aStatus;
} MQQUEUEPROPS;

The MQQUEUEPROPS structure is used in the following calls.

  • To set queue properties when creating a queue.
  • To retrieve and set the properties of an existing queue.
  • To specify search criteria when locating a public queue.

The following illustration shows how Message Queuing uses the data in these three arrays. Note that for each property the corresponding elements of the aPropID array and aPropVar array must be set to the property identifier and value respectively.

When setting properties for queues, if a property is set to the same value more than once, Message Queuing uses the first entry in the aPropVar array and discards all the subsequent entries. In the aStatus array, an information error value of MQ_INFORMATION_DUPLICATE_PROPERTY is returned for each discarded entry.


Allocating Memory when Retrieving Queue Properties

When retrieving queue properties, Message Queuing requires space for the returned property value. For example, space must be allocated before the label of a queue can be retrieved. This space is allocated based on the vt field of the MQPROPVARIANT entry for each element of the aPropVar array. The vt field can contain the specific VARTYPE specified for the property or VT_NULL (VT_NULL is required if the field type of the queue property is VT_LPWSTR).

Typically, applications specify the VARTYPE required by the property and the application is responsible for allocating any corresponding buffers when needed. In the following example, the vt field is set to VT_CLSID (the VARTYPE required by PROPID_Q_INSTANCE) and the puuid field contains the address of the allocated buffer.

CLSID InstanceBuffer;
aPropID[i] = PROPID_Q_INSTANCE;
aPropVar[i].vt = VT_CLSID;
aPropVar[i].puuid = &InstanceBuffer;
i++;

When VT_NULL is specified in the vt field, Message Queuing fills in the appropriate VARTYPE value and allocates memory, if needed, for the returned value. In the following example, the vt field is set to VT_NULL.

aPropID[i] = PROPID_Q_LABEL;
aPropVar[i].vt = VT_NULL;
i++;

When Message Queuing allocates a buffer for a returned value (when VT_NULL is specified in the vt field) it is the application's responsibility to free the memory with the MQFreeMemory function


Message Queuing Messages

Messages are units of information that are sent to and retrieved from destination queues distributed on various computers. Message Queuing uses destination queues to store messages so that the application sending the messages and the application retrieving the message do not have to be running at the same time.

Logically speaking, a message can be considered an object that has a set of properties and contents. The properties specify how Message Queuing delivers the message, and the contents are processed by the receiving application. Physically speaking, a message can be considered a packet of data conforming to a specific protocol that contains information in well defined fields.

The information within the message is stored in different message properties. For example, even the contents of the message (as described above) are stored in the body property of the message. Other message properties include the message identifier (set by Message Queuing), the message label (provided by the sending application, and many more.

Maximum Message Size

Messages can have no more than 4 MB of data. This restriction is due to the memory mapped files used by Message Queuing to store the message data. These memory-mapped files are stored in the MSMQ\Storage folder on the computer where the queue resides.

Message Identifier

Message Queuing provides a message identifier for every message that is sent, including both messages sent by the sending application and system-generated messages sent by Message Queuing. For the most part, each message identifier is unique and can be used to identify the message. However, when a message is sent to multiple destinations using distribution lists or multiple-element format names (distribution lists and multiple-element format names are introduced in MSMQ 3.0), each copy of the message has the same message identifier. In this case, the application reading the message must look at both the message identifier and the destination of the message to identify the message.

For information on | See
Sending messages express or making them recoverable | Express and Recoverable Messaging
Sending a single message to multiple queues | Multiple-Destination Messaging
Sending and retrieving messages within a transaction or without transactions | Transactional and Non-Transactional Messaging
Sending messages directly to their destination queue | Direct Messaging
Sending a retrieving information in the message body. | Message Body Types
Acknowledgment and response messages. | Message Confirmation
Options when sending messages. | Sending Messages
Retrieving and peeking at messages in a queue and copying them to the journal queue. | Reading Messages
Setting the expiration time of a message. | Message Timers
Tracking how messages reach the destination queue. | Tracing Messages


Express and Recoverable Messaging

The sending application can specify express or recoverable messaging by setting the delivery property (PROPID_M_DELIVERY or MSMQMessage.Delivery) of each message that is sent. The choice between the two delivery options is essentially a choice between better performance with minimal resource use (express messaging) and reliability and recovery after a failure (recoverable messaging).

Express Messaging

When express messaging is used to send messages, the messages are stored in RAM memory during routing and delivery. This provides extremely fast performance but the messages are not recoverable if any computer the messages pass through fails. Notably, this means that express messages are lost whenever the Message Queuing Service is stopped.

Caution When running Message Queuing in a server cluster, express messages are lost during a failover from one node to another.

Although storing express messages in RAM provide better performance, this may also cause paging out to the disk if too many messages accumulate in RAM.

Express messages can, however, survive a network failure. For example, if the sending application sends express messages through a Message Queuing server, and the link between the Message Queuing server and the target computer fails, the Message Queuing server continues to store the messages in its memory. However, if the server fails before the link is restored, the express messages on the server are lost.

Recoverable Messaging

When recoverable messaging is used to send messages, the messages are written to disk during routing and delivery. This makes delivery somewhat slower than express messaging, but ideal when failures cannot be tolerated. If a computer fails or is shut down while sending messages, the messages are stored on disk. Then when the computer is restarted and the Message Queuing service restarts, the sending process is automatically resumed.

Messages are stored to disk based on a memory-mapped architecture. Performance gains can be realized by using several physical disks for the stored messages.


Multiple-Destination Messaging

Beginning with MSMQ 3.0, sending applications can send messages to multiple destination queues with a single send operation. Message Queuing provides the following mechanisms for sending messages to multiple destinations.

  • Distribution lists: Distribution lists are public lists that are stored in Microsoft® Active Directory™. For information on the format name used to send messages using distribution lists, see Distribution List Format Names.
  • Multicast addresses: Multicast address can be used to send a message to any queue associated with a specific multicast address. For information on the format name used to send messages using multicast addresses, see Multicast Address Format Names.
  • Multiple-element format names: Multiple-element format names are private lists of destination queues. For information on the multiple-element format names, see Multiple-Element Format Names.

When an application sends messages to multiple destinations, the local queue manager receives the send request, generates a message identifier for the message, determines what destination queues are needed, then sends a copy of the message to each destination queue. Note that this means each copy of a message has the same message identifier.


Transactional and Non-Transactional Messaging

Sending and receiving applications can indicate that they want to send or retrieve messages within the context of a transaction. Sending or retrieving messages within the context of a transaction is referred to as transactional messaging. Sending or retrieving messages outside the context of a transaction is referred to a non-transactional messaging.

Transactional Messaging

Transactional message is only used when you want to perform several tasks in an atomic way. In this context the term "atomic" means that you want to perform several operations, including non-Message Queuing operations, that will all succeed or all fail. When transactional messaging is used, the sending or receiving application has the opportunity to commit to the transaction (all the operations have succeeded) or one of the operations failed (the transaction is aborted) so all changes are rolled back. When a transaction is aborted all operations rolled back to the state when the transaction was invoked.

When sending messages within a transaction, all the messages are sent together and in the order they were sent, or they are not sent at all. Message Queuing guarantees that all messages sent within the transaction will arrive exactly once, if they can be delivered, and in the order that they were sent.

When retrieving messages within a transaction, all the messages are removed from the queue or they are placed back in the queue in their original position in the queue. Note that peeking at messages make no sense in the context of a transaction.

Non-Transactional Messaging

When non-transactional messaging is used, Message Queuing sends each message as a single operation (this includes sending messages to multiple destinations). This means that there is no guarantee that the messages will reach the destination queue in the order they were sent, not does it mean that the message will only arrive once.

For Information On | See
Message Queuing transaction support | Message Queuing Transactions
The types of transactions available | Transaction Types
The confirmation process used when sending messages | Transaction Confirmation Process
Important programming issues to consider when using transactions | Programming Considerations with Transactions


Direct Messaging

Sending and receiving applications can use direct messaging at any time. However, direct messaging is designed to be used when messages must be sent to the destination queue in one hop, or when the application needs to open a queue (for sending or retrieving messages) that is not in the same enterprise. Note that when direct messaging is requested, Messaging Queuing uses information provided by the application to locate and open the queue. In this case Message Queuing does not contact the directory service to open the queue.

To send or retrieve messages directly, the application must use a direct format name to open the queue. Direct format names include the address specification of the computer where the destination queue resides, followed by the local name of the queue.

Note Direct format names can be used in distribution lists or multiple-element format names when sending messages to multiple destination queues.

For Information On | See
How Message Queuing opens queues for direct messaging | Opening Queues with a Direct Format Name
The syntax of a direct format name | Direct Format Names
Other format names (public, private, distribution list, multicast address, and multiple-element format names) | Format Names


Message Body Types

The body of a message can contain information formatted in a variety of ways: from simple integer and string formats to arrays and data record sets. The format of the message body is referred to as the body type of a message.

In general, it is the responsibility of the sending application to specify the message body type when sending messages and it is the responsibility of the receiving application to understand what the sending application has specified when it reads the messages from the queue. However, there are some differences between how Message Queuing handles message body types depending on if the applications are calling API functions or COM methods.

When the sending application calls the MQSendMessage functionto send messages, the application should always specify the body type. If the body type is not specified when MQSendMessage is called, Message Queuing sets the body type property to VT_EMPTY.

When the MSMQMessage.Send method is called to send messages, Message Queuing determines the body type of the message and sets the body type property for you.

Differences When Peeking at or Retrieving Messages

When the MQReceiveMessage or MQReceiveMessageByLookupId function is called to peek at or retrieve message, the receiving application should always check the body type before processing the body of the message. It is the responsibility of the receiving application to understand what type of message it is retrieving.

If the body type of the message was not set by the sending application, the receiving application should assume that the message body is an array of bytes (the Message Queuing COM implementation does this automatically).

When one of the peek or receive methods of the MSMQQueue object is called, Message Queuing determines the message body type for you. However, if the message was sent using MQSendMessage, the following conditions can occur,

  • If the body type property was not set before MQSendMessage was called, the message body is treated as an array of bytes.
  • If the body type was set to an invalid body type (valid types are listed below) before MQSendMessage was called, the message can be retrieved but an error will occur when you try to read the message body.

Message Body Type Property

The PROPID_M_BODY_TYPE) property should be accessed only when you are using one of the following functions to send, peek at, or retrieve a message (as noted earlier, when using COM methods Message Queuing sets and retrieves this property for you).

  • MQSendMessage
  • MQReceiveMessage
  • MQReceiveMessageByLookupId

When setting PROPID_M_BODY_TYPE, one of the defined body type values listed in the following table must be used. If an undefined type is used, problems may occur when an application using the COM components tries to read the body of the messages.

The following table lists all the valid body types.

Type | Body contains
VT_EMPTY | Default. Note that the Message Queuing COM implementation treats this value as an array of bytes.
VT_I1 | A Char (1 byte) type.
VT_I2 | A short integer.
VT_I4 | A long integer.
VT_R4 | A float (4-byte floating point).
VT_R8 | A double-float (8-byte floating point).
VT_CY | A CURRENCY type (8-byte).
VT_DATE | An OLE DATE (8-byte) type.
VT_BSTR | String data in Unicode (does not have to be NULL terminated).
VT_BOOL | A VARIANT_BOOL (2-byte) type where -1 is TRUE and 0 is FALSE.
VT_UI1 | A Char (1 byte) type. An array of bytes when joined by the OR operator with VT_ARRAY (VT_ARRAY | VT_UI1).
VT_UI2 | A short integer.
VT_UI4 | A long integer.
VT_LPSTR | A variable-size, NULL-terminated ANSI string.
VT_LPWSTR | A variable-size, NULL-terminated Unicode string.
VT_STREAMED_OBJECT | A persistent, serialized object whose format is the output of a call to OleSaveToStream using IPersistStream.
VT_STORED_OBJECT | A persistent serialized object whose format is the output of a call to OleSave using IPersistStorage.
VT_ARRAY | VT_UI1 | An array of bytes.


Message Confirmation

Sending applications can receive confirmation that a message has been delivered by requesting acknowledgment messages from Message Queuing (or connector applications) and by requesting response messages from the receiving application. Both requests provide a mechanism for the sending application to confirm what happened to its messages after they were sent.

For information on | See
The types of acknowledgment messages returned by Message Queuing | Acknowledgment Messages
The types of response message returned by the receiving application | Response Messages


Acknowledgment Messages

Acknowledgment messages are system-generated non-transactional messages that are sent to the administration queues specified by the sending application. Acknowledgment messages are typically generated by Message Queuing, however they can also be generated by connector applications when messages are sent to foreign messaging systems.

Note Acknowledgment messages are non-transactional, so the administration queues specified by the sending application must also be non-transactional queues

The system can return different types of acknowledgment messages. These include negative and positive acknowledgments indicating whether a message reached its destination queue, negative and positive acknowledgments indicating whether a message was retrieved by the receiving application, and a combination of both these types. The type of acknowledgment messages returned depends on the acknowledgment level of each message sent by the sending application.

If a message is sent to multiple destination queues, Message Queuing returns an acknowledgment message for each copy of the message delivered).

For information on | See
Administration queues | Administration Queues
The different classes of acknowledgment messages | Acknowledgment Message Classes
The values of the acknowledgment message properties set by the system | Acknowledgment Message Properties
Associating an acknowledgment message with the message it acknowledges | Matching Acknowledgment and Original Messages


Acknowledgment Message Classes

Acknowledgment message classes can be divided into three groups: positive acknowledgments, negative arrival acknowledgments, and negative read acknowledgments. The system sets the class property of the acknowledgment message when it creates the acknowledgment message.

Positive Acknowledgment Classes

MQMSG_CLASS_ACK_REACH_QUEUE
Indicates that the original message reached its destination queue.
MQMSG_CLASS_ACK_RECEIVE
Indicates that the original message was retrieved by the receiving application.

Negative Arrival Acknowledgment Classes

The following classes of negative acknowledgment messages are generated if the message fails to arrive at the destination queue.

MQMSG_CLASS_NACK_ACCESS_DENIED
Indicates that the sender does not have send access rights to the destination queue.
MQMSG_CLASS_NACK_BAD_DST_Q
Indicates that the destination queue is not available to the sender.
MQMSG_CLASS_NACK_BAD_ENCRYPTION
Indicates that the destination queue manager could not decrypt a private message.
MQMSG_CLASS_NACK_BAD_SIGNATURE
Indicates that Message Queuing could not authenticate the original message. The original message's digital signature is not valid.
MQMSG_CLASS_NACK_COULD_NOT_ENCRYPT
Indicates that the source queue manager could not encrypt a private message.
MQMSG_CLASS_NACK_HOP_COUNT_EXCEEDED
Indicates that the message hop count was exceeded. The maximum hop count is set by Message Queuing (hop count = 15) and cannot be changed.
MQMSG_CLASS_NACK_Q_EXCEED_QUOTA
Indicates that the message was not delivered because the destination queue is full.
MQMSG_CLASS_NACK_REACH_QUEUE_TIMEOUT
Indicates that the message did not reach the destination queue. It can be generated by either the time-to-reach-queue timer or time-to-be-received timer.
MQMSG_CLASS_NACK_PURGED
Indicates that the message was purged before reaching the destination queue.
MQMSG_CLASS_NACK_NOT_TRANSACTIONAL_Q
Indicates that a transactional message was sent to a non-transactional queue.
MQMSG_CLASS_NACK_NOT_TRANSACTIONAL_MSG
Indicates that a non-transactional message was sent to a transactional queue.

Negative Read Acknowledgment Classes

The following classes of negative acknowledgment messages are generated if the original message is not retrieved from the destination queue:

MQMSG_CLASS_NACK_Q_DELETED.
Indicates that the queue was deleted before the message could be read from the queue:
MQMSG_CLASS_NACK_Q_PURGED.
Indicates that the queue was purged and the message no longer exists.
MQMSG_CLASS_NACK_RECEIVE_TIMEOUT.
Indicates that the message was not retrieved from the queue before its time-to-be-received timer expired.
For an example of | See
Sending messages that request acknowledgments | Visual Basic
Testing to see if acknowledgment messages are used | Retrieving the Format Name of an Administration Queue


Acknowledgment Message Properties

The properties of an acknowledgment message are set by the system. They provide information that can be used by the sending application that is reading the messages in an administration queue. The following table lists the message properties that the system sets when it generates the acknowledgment message.

Note Connector applications must set these properties when sending positive (including read receipt messages) and negative acknowledgment messages back to the sending application.

  • PROPID_M_ACKNOWLEDGE or MSMQMessage.Ack

    Not set.

  • PROPID_M_ADMIN_QUEUE or MSMQMessage.AdminQueueInfo

    Not set.

  • PROPID_M_APPSPECIFIC or MSMQMessage.AppSpecific

    Same as original message.

  • PROPID_M_BODY or MSMQMessage.Body

    For positive acknowledgment messages, the body of the acknowledgment message is empty. You must refer to the original message to see the message body.

    For negative acknowledgment messages (with the exception of private, encrypted messages) the body of the acknowledgment message contains the message body of the original message.

  • PROPID_M_CLASS or MSMQMessage.MsgClass

    Specifies the appropriate positive or negative acknowledgment class. For information on the different acknowledgment classes, see Acknowledgment Message Classes.

  • PROPID_M_CORRELATIONID or MSMQMessage.CorrelationId

    Specifies the message identifier of the original message sent by the sending application. (Note that if messages were sent to multiple destination queues, the returned message identifier is not unique.)

    If the correlation identifier of the original message contained an application-defined identifier, that information is not included in the acknowledgment message.

  • PROPID_M_DELIVERY or MSMQMessage.Delivery

    Same as the original message.

  • PROPID_M_EXTENSION

    Same as the original message.

  • PROPID_M_JOURNAL or MSMQMessage.Journal

    Same as the original message.

  • PROPID_M_LABEL or MSMQMessage.Label

    Same as the original message.

  • PROPID_M_MSGID or MSMQMessage.Id

    Message identifier of the acknowledgment message.

  • PROPID_M_PRIORITY or MSMQMessage.Priority

    Same as the original message.

  • PROPID_M_RESP_QUEUE or MSMQMessage.ResponseQueueInfo

    Destination queue format name of the original message. When messages are sent to multiple destination queues, this property provides the format name of the destination queue for one copy of the message.

  • PROPID_M_RESP_FORMAT_NAME or MSMQMessage.ResponseDestination

    (Introduced in MSMQ 3.0) Destination queue format names of the original message. When the original message is sent using a distribution list format name, multicast address format name, or multiple-element format name, this property is set to the distribution list, multicast, or multiple-element format name specified when the original message was sent.

  • ROPID_M_TIME_TO_BE_RECEIVED or MSMQMessage.MaxTimeToReceive

    Set to maximum time allowed by Message Queuing.

  • PROPID_M_TIME_TO_REACH_QUEUE or MSMQMessage.MaxTimeToReachQueue

    Set to maximum time allowed by Message Queuing.

For information on | See
Administration queues | Administration Queues
The values of the acknowledgment message properties set by the system | Acknowledgment Message Properties
The different classes of acknowledgment messages | Acknowledgment Message Classes


Matching Acknowledgment and Original Messages

When the sending application reads the acknowledgment messages returned to the administration queue, the application must be able to match the returned acknowledgment message with the original message it sent.

To do this, Message Queuing returns the message identifier and destination of the original message in the following message properties of the acknowledgment message.

  • PROPID_M_CORRELATIONID or MSMQMessage.CorrelationId Provides the message identifier of the original message
  • PROPID_M_RESP_QUEUE or MSMQMessage.ResponseQueueInfo Provides the format name of the destination queue for the original message.

If the sending application has sent each message to a single destination queue, each sent message has a unique message identifier. As a result, that acknowledgment messages can be matched to their corresponding original message simply by comparing the returned message identifier with the message identifier of the sent message.

However, if the sending application has sent messages to multiple destination queues, each copy of the message has the same message identifier. In this case, the sanding application will need to match message identifiers and the destination queues of the original message.

Note Messages can be sent to multiple destination queues using distribution lists, multicast addresses, and multiple element format names. For information sending messages to multiple destination queues, see Multiple-Destination Messaging.

For information on | See
Administration queues | Administration Queues
The values of the acknowledgment message properties set by the system | Acknowledgment Message Properties
The different classes of acknowledgment messages | Acknowledgment Message Classes


Response Messages

Response messages are messages that a receiving application sends in response to a message. A sending application requests a response by providing a response queue with the message its initial message. The receiving application then checks to see if a response queue was sent, sending a response message back to the response queue if one was provided.

This response is an application message that must be in a form understood by the application requesting the response and the application sending the response. Response messages are application-defined and are not defined by Message Queuing.

For information on | See
The type of queues used as response queues | Response Queues
Specifying a response queue using function calls | PROPID_M_RESP_QUEUE
Specifying a response queue and testing to see if a response is needed using object properties | MSMQMessage.ResponseQueueInfo
Contents of response messages | What is in a Response Message

For an example of | See
Sending messages that request response messages | Visual Basic


What is in a Response Message

Response messages are application-defined. So, determining what is in the response message is the responsibility of the application sending the response message as well as the application receiving the response.

Two message properties that can be included in the response message are the identifier and destination of the original message. For example, the destination queue of the original message can be returned in the response queue property of the response message, and the identifier of the original message can be returned in the correlation identifier of the response message.

Other message properties, such as the body of the message, can be included as well. When designing your response message, simply make sure that all applications know how to interpret the information provided by the response message.

For information on | See
The type of queues used as response queues | Response Queues
Retrieving the message identifier using function calls | PROPID_M_MSGID
Retrieving the message identifier using COM components | MSMQMessage.Id
Retrieving destination queue information using function calls | PROPID_M_DEST_QUEUE
Retrieving destination queue information using COM components | MSMQMessage.DestinationQueueInfo

For an example of | See
Sending messages that request response messages | Visual Basic


Sending Messages

Sending messages in Message Queuing is always an asynchronous operation. When you are sure the queue is open, you can continue to send messages without stopping to wait for a reply.

Note Each Message Queuing message can have no more than 4 MB of data.

In addition to the basic asynchronous operation, you can add functionality to your send operation by using the following:

  • Message timers to control how long your messages stay in the system
  • Computer journals to store a copy of the messages you send
  • Administration queues for Message Queuing–generated acknowledgment messages
  • Response queues for application-defined response messages
  • Report queues for tracing the progress of a message

For examples of sending messages, see one of the following

For information on | See
A complete list of all message properties | API properties: Message Queuing Properties COM component properties: MSMQMessage
Reading messages from a queue | Reading Messages
Saving copies of message you send | Source Journaling


Source Journaling

Source journaling allows you to track the messages sent by a computer. It can be used to track messages that were sent successfully, messages that could not be delivered, or both.

To track messages that were successfully sent by the local computer, set the journaling property of the message to MQMSG_JOURNAL. This tells Message Queuing to always save a copy of each message that it successfully sent.

This means that when you send messages to remote computers, a copy of the message is placed in the source computer's journal queue if the message was sent successfully. Note that this does not mean the message has successfully reached its destination queue, only that the computer was able to send the message.

On the other hand, when you send messages to local queues, a copy of the message is saved to the computer's journal queue only after the message has been removed from the local destination queue.

Message Queuing never stores more than one copy of a message on a single computer at one time. Therefore, if the local destination queue has also enabled target journaling, a copy of the message is placed in that queue's journal when the message is removed from the queue; the message is not, however, saved to the computer's journal queue. If, on the other hand, the local destination queue has not enabled target journaling, a copy of the message is placed in the computer's journal when the message is removed from the destination queue.

To track messages that were not delivered, set the journaling property of the message to MQMSG_DEADLETTER. When you specify this type of source journaling, Message Queuing reacts differently depending on the type of message you send.

For non-transactional messages, a copy of the message is placed in the dead-letter queue of any computer that cannot deliver the message. This can be the source computer, or any routing server used to pass the message on to its destination.

For transactional messages, a copy of the message is placed in the transactional dead letter queue of the source computer only if Message Queuing does not confirm that the message was retrieved from its destination queue. Confirmation is not returned if the message is not delivered, was not received, or the receiving transaction was aborted. These messages may be used as a guaranteed negative acknowledgment.

Note For transactional messages, MSMQ 1.0 and MSMQ 2.0 act differently.

MSMQ 1.0 only allows you to choose if you want to save copies of messages sent successfully. MSMQ 1.0 always sends non-confirmed transactional message to the transactional dead-letter queue, regardless of whether MQMSG_DEADLETTER is or is not specified.

MSMQ 2.0 allows complete control over source journaling. (If you are running MSMQ 1.0 applications on an MSMQ 2.0 computer, you can force the computer to use the MSMQ 1.0 semantics by setting the XactDeadLetterAlways registry entry to 1.)

When you store messages in a journal or dead-letter queue, clear these queues periodically to remove messages that are no longer needed. Message stored in journal and dead-letter queues count against the quota for the computer where the queues reside (the computer quota is set by the administrator).

For information on | See
Target journaling | Target Journaling
The type of queues used for computer journals | Journal Queues
The type of queues used for dead-letter queues | Dead-Letter Queues


Reading Messages

The receiving application can read the messages in a queue either synchronously or asynchronously. Messages can be removed from the queue when they are read, or they can be left in the queue. Additionally, a receiving application can read all its messages from within a transaction.

Note Messages cannot be read from a queue on a computer that does not have a direct connection. Opening a queue with receive or peek access requires a direct connection to the computer where the queue is resides.

For information on | See
Synchronous operations | Synchronous Reading
Asynchronous operations | Asynchronous Reading
Removing a message when it is read | Retrieving Messages
Leaving a message when it is read | Peeking at Messages
Saving copies of message removed from a queue | Target Journaling

For an example of | See
Reading the first message in the queue synchronously | C/C++ Visual Basic


Synchronous Reading

When an application synchronously reads messages in a queue, all calls are blocked until the next message is available or a specific amount of time expires. The amount of time the application waits can be 0, a specific amount of time (in milliseconds), or the maximum time allowed by your Message Queuing enterprise. When the time expires for a synchronous read, Message Queuing returns a NULL message (for applications using COM components) or an MQ_ERROR_IO_TIMEOUT error (for applications using functions).

Note Cursors can be used to navigate through a queue when reading messages synchronously. Cursors behave the same way in synchronous and asynchronous operations.

For information on | See
Asynchronous operations | Asynchronous Reading
Leaving a message when it is read | Peeking at Messages
Removing a message when it is read | Retrieving Messages
Reading past the first message in the queue | Navigating with Cursors
How transactions work and the different types of transactions | Message Queuing Transactions
Reading the first message in the queue synchronously | C/C++ Visual Basic


Asynchronous Reading

There are four ways to read messages asynchronously:

  • By using a callback function.
  • By using a Windows Event mechanism.
  • By using a Microsoft® Windows NT®/Windows® 2000 completion port. (Not available for dependent clients.)
  • By using the Message Queuing COM components.

When using a callback function, Message Queuing reads the message by calling the callback function that is currently registered. The function is called if a message is immediately available, when a message arrives, or when the time for reading a message expires. Only 64 callbacks can be registered at the same time.

When using an event mechanism, an OVERLAPPED structure provides a valid handle (hEvent field) to an event object. When a suitable message arrives, or a time-out occurs, the event object is set to the signaled state.

When using a Windows NT®/Windows® 2000 completion port, a queue handle can be associated with the port to receive messages asynchronously. For more information, see CreateIOCompletionPort.

When using the Message Queuing COM components, define an event handler that is notified when a message arrives or a time-out occurs. The user-defined event handler itself is invoked from an internally implemented callback function (limited to 64 callbacks). Therefore, all callback features and restrictions apply when using the COM components.

COM components invoke an ArrivedError event handler with MQ_ERROR_IO_TIMEOUT when a time-out occurs.

Note Cursors behave the same way in synchronous and asynchronous operations. However, when using a cursor to read messages asynchronously do not use the same cursor in overlapping read operations. For example, when moving a cursor you should not fire a second receive operation before the previous receive is completed. This type of action may lead to unexpected behavior.

When reading messages in a queue, Message Queuing can peek at the messages (leaving them in the queue) or retrieve them (removing the messages from the queue).

For information on | See
Leaving a message when it is read | Peeking at Messages
Removing a message when it is read | Retrieving Messages
Reading past the first message in the queue | Navigating with Cursors
How transactions work and the different types of transactions | Message Queuing Transactions
Reading the first message in the queue synchronously | C/C++ Visual Basic


Retrieving Messages

Retrieving a message in a queue removes it from the queue. You can retrieve a specific message from a queue, or purge a queue by retrieving all the messages in a queue.

Message Queuing provides a way to always retrieve the first message in a queue, or retrieve a message at a specific cursor location. This second functionality is used when you use a cursor to navigate through a queue. In addition, messages can be retrieved from their destination queues either synchronously or asynchronously, thus allowing the receiving application to halt processing or continue processing while it is retrieving the messages from their queues.

For information on | See
Synchronous operations | Synchronous Reading
Asynchronous operations | Asynchronous Reading
Leaving a message when it is read | Peeking at Messages
Reading past the first message in the queue | Navigating with Cursors
How transactions work and the different types of transactions | Message Queuing Transactions
Reading the first message in the queue synchronously | C/C++ Visual Basic


Peeking at Messages

Messages can be read from the queue without removing them from the queue. For example, if you are trying to locate a particular message, you may want to peek at the label or identifier of each message in the queue until you find the message you want, then retrieve the complete message.

Message Queuing provides a way to always peek at the first message in a queue, or to peek at a message at a specific cursor location. This second functionality is used when you use a cursor to navigate through a queue.

For information on | See
Synchronous operations | Synchronous Reading
Asynchronous operations | Asynchronous Reading
Removing a message when it is read | Retrieving Messages
Reading past the first message in the queue | Navigating with Cursors
How transactions work and the different types of transactions | Message Queuing Transactions
Reading the first message in the queue synchronously | C/C++ Visual Basic


Target Journaling

When you enable target journaling, Message Queuing sends a copy of any message you retrieve from a queue to that queue's queue journal. Target journaling lets you keep track of messages even after they have been retrieved.

Note This does not include message removed from the queue when their time-to-be-received timer expires, or messages purged from the queue using the directory service.

When you store messages in a queue journal, clear these queues periodically to remove messages that are no longer needed. Message stored in the queue journal count against the quota for the computer where the queue journal resides (the computer quota is set by the administrator).

Target journaling is enabled by setting the journaling level of the queue. The journaling level of a queue can be set when the queue is created or later.

For information on | See
Source journaling | Source Journaling
The type of queues used for journal queues | Journal Queues


Message Timers

Message Queuing provides two timers to help you maintain better control of your messages: a time-to-reach-queue and a time-to-be-received timer.

The time-to-reach-queue timer determines how long a message has to reach the queue manager of the target queue. Typically, this timer is set to a value less than the time-to-be-received setting.

The time-to-be-received timer determines how long a message remains in the system, starting from the time the message is sent to the time it is removed from the target queue.

When both timers are used and the time-to-be-received timer is set to a smaller value than the time-to-reach-queue timer, the time-to-be-received timer takes precedence. For example, if the time-to-be-received timer is set to 3 minutes and the time-to-reach-queue timer is set to 10 minutes, Message Queuing will discard the message after 3 minutes. A message is not allowed to remain in the system longer than the time specified by the time-to-be-received timer.

When a timer expires, Message Queuing discards the message. However, Message Queuing can also send a copy of the discarded message to a dead-letter queue or it can send a negative acknowledgment message to an administration queue.

Discarded messages can be sent to dead-letter queues if the journal property of the message specifies a dead-letter queue. Copies of non-transactional messages are sent to the dead-letter queue on the computer where the timer expired. Copies of transactional messages are sent to the transactional dead-letter queue on the source machine.

Acknowledgment messages are returned if a timer expires and the acknowledgment property of the message specifies full or negative acknowledgments. Message Queuing sends the appropriate negative acknowledgment message to the administration queue specified by the message.

For information on | See
Message property used to set the time-to-reach-queue timer | PROPID_M_TIME_TO_REACH_QUEUE
Message property used to set the time-to-be-received timer | PROPID_M_TIME_TO_BE_RECEIVED
COM message property used to set the time-to-reach-queue timer | MSMQMessage.MaxTimeToReachQueue
COM message property used to set the time-to-be-received | MSMQMessage.MaxTimeToReceive
Sending discarded messages to dead-letter queues | Dead-Letter Queue
Specifying acknowledgments | Acknowledgment Messages


Tracing Messages

Message Queuing provides tracing support that allows you to track how messages reach their destination queues. When tracing is enabled, Message Queuing generates a report message each time a message is sent from or arrives at a computer.

Note Message Queuing does not support tracing under the following conditions.

  • When you send messages to multiple destinations using distribution lists, multicast addresses, and multiple-element format names.
  • When you send HTTP messages.

For example, if a message is sent with direct messaging (the message is sent directly to the target computer), two report messages would be generated. The first report message indicates that the message was sent from the source computer and the second report message indicates that the message arrived at the target computer.

However, when a message passes through several computers the following report messages are generated.

  • A single report message is generated when the message leaves the source computer.
  • Two report messages (arrived and sent) are generated each time the message passes through a server computer.
  • A single report message is generated when the message arrives at the target computer.

To trace a message, you must specify the report queue where Message Queuing (or the connector application) will send its report messages and then enable tracing when you send thew message.

Selecting a Report Queue

Report queues are selected by the Message Queuing administrator through Active Directory Manager. They can be a local queue or remote queue that resides on another computer.

Typically, the report queue is specified on the source computer where the message is sent. When the local queue manager sends the message it adds the path of the report queue to the message so that the next computer will know where to send the report message. If the report queue is not specified by the source computer, Message Queuing will not generate report messages until the message arrives at a computer where a report queue is specified.

In addition to the report queue specified on the source computer, any computer in the enterprise can specify its own report queue. When the message reaches a computer that specifies a report queue that is different from the report queue specified in the message, Message Queuing sends one report message to the queue specified in the message and another report message (containing a conflict report) to the report queue specified by the computer.

When specifying the report queue in the Active Directory Manager, the administrator must supply the complete pathname for the queue. If the queue does not exist, Message Queuing creates the queue for the administrator. For information on selecting the report queue, see the Message Queuing Administrator's Guide in Windows 2000 Help.

Enabling Tracing When Sending Messages

Tracing is enable by setting the tracing property (PROPID_M_TRACE or MSMQMessage.Trace) of a message to MQMSG_SEND_ROUTE_TO_REPORT_QUEUE. When the message is sent, Message Queuing will trace its route to its destination queue.


Specifying Multiple Report Queues

There is no limit to the number of computers that can specify report queues. However, when multiple report queues are used locating the report messages for a single message becomes much more difficult.

The illustration below shows three computers that each specify a different report queue: RQ1 on the source computer from which the message is sent, RQ2 on a routing server, and RQ3 on the target computer where the destination queue resides.

The following report messages are generated when the message leaves or arrives at each computer.

  • When the message is sent from the source computer, the sending queue manager adds RQ1 to the message packet and send a report message to RQ1.
  • When the message arrives at the routing server, the receiving queue manager detects that the computer report queue (RQ2) is different then the report queue specified in the message packet. To resolve this conflict the receiving queue manager sends a report message to RQ1 and a conflict report message to RQ2.
  • When the message leaves the routing server, the sending queue manager also detects the different report queues and sends a report message to RQ1 and another conflict report message to RQ2.
  • When the message arrives at the target computer, the receiving queue manager detects the different report queues (RQ1 and RQ3) and sends a report message to RQ1 and a conflict report message to RQ3.

In summary, after the message reaches the destination queue the three report queues will have the following messages.

Note that when a conflict occurs, Message Queuing sends two report messages. The report message that contains the report is sent to the report queue specified by the message. The report message that contains the conflict report is sent to the queue specified by the computer.


Report Message

Report messages trace the route of a message from its source computer to its destination queue. Each report message has its own message identifier, a specific message class that indicates it is a report message, and a label and body that provides details about the original message that was sent. When reading report messages, the receiving application must look at the label and body of the report message to find out when and where the report message was generated.

When a report message is generated, information is placed in the label and body of the report message.

The label of the report message contains a simplified version of the information in the body of the report message or a message conflict report. The format of the information in the message label is one of the following.

gggg:dddd:hh sent from <computer> to <address> at <time>
gggg:dddd:hh received by <computer> at <time>
Report Message Conflict

where "gggg" is the first four hexadecimal digits of the source queue identifier, "dddd" is an internal report message identifier, and "hh" is the hop count of the sent message.

If the report message label contains the "Report Message Conflict" string, the sent message and the local computer each refer to a different report queue. In this case, the receiving application can use the information in the body of the conflict report to find out where the report message that contains the report is located. Note that when report messages and conflict report message are generated, the label of both messages is set to "Report Message Conflict".

The body of the report message contains the report or, in the case of conflicts, information about where the report can be found. The format of the report message body is one of the following.

For report messages that contain the report, the XML format is as follows.

<MESSAGE ID>{sent message}</MESSAGE ID>
<TARGET QUEUE> {format name of destination}</TARGET QUEUE>
<NEXT HOP> {IP or IPX address of the next hop} </NEXT HOP>
<HOP COUNT> integer </HOP COUNT>

For conflict report messages that provide information about where the report is, the XML format is as follows. Note that the "original queue" in the format below if the report queue where the report is located.

<ORIGINAL QUEUE> {format name of report queue} </ORIGINAL QUEUE>
<MESSAGE ID> {sent message} </MESSAGE ID>
<TARGET QUEUE> {format name of destination queue} </TARGET QUEUE>
<NEXT HOP> {IP or IPX address of the next hop} </NEXT HOP>


Computer Properties

The properties of a Message Queuing computer contain the settings that define the messaging behavior of the computer. Computer properties consist of two groups of properties: queue manager and personal computer properties.

Unlike queue and message properties, computer properties cannot be set programmatically. Applications processing queue manager and personal computer properties can only retrieve these properties.

Message Queuing uses an MQQMPROPS structure to define queue manager properties and a MQPRIVATEPROPS structure to define personal computer properties. When using API function calls, these structures must be explicitly declared by the application that is retrieving the queue manager or personal computer properties. When using COM component calls, these structures are declared by Message Queuing when the application references the properties of the MSMQApplication object.

The MSMQApplication object does not support the following queue manager properties. To retrieve these properties the application must call the MQGetMachineProperties function.

  • PROPID_QM_CONNECTION
  • PROPID_QM_ENCRYPTION_PK
  • PROPID_QM_ENCRYPTION_PK_BASE
  • PROPID_QM_ENCRYPTION_PK_ENHANCED
  • PROPID_QM_SITE_ID


Computer Property Structures

The MQQMPROPS and MQPRIVATEPROPS structures, shown below, includes a property count member to indicate the number of properties included in the structure, an array the identifies each property (aPropID), an array that specifies the value of each property (aPropVar), and an array for the returned status of each property (aStatus). Position i in each of the three arrays contains information about a single property.

typedef struct tagMQQMPROPS
{
  DWORD          cProp;
  QUEUEPROPID    *aPropID;
  MQPROPVARIANT  *aPropVar;
  HRESULT        *aStatus;
} MQQMPROPS;

The MQQMPROPS structure is used in calls to MQGetMachineProperties.

typedef struct tagMQPRIVATEPROPS
{
  DWORD          cProp;
  QUEUEPROPID    *aPropID;
  MQPROPVARIANT  *aPropVar;
  HRESULT        *aStatus;
} MQPRIVATEPROPS;

The MQPRIVATEPROPS structure is used in calls to MQGetPrivateComputerInformation.

The following illustration shows how Message Queuing uses the data in these three arrays. Note that for each property the corresponding elements of the aPropID array and aPropVar array must be set to the property identifier and value respectively.

When setting properties for queues, if a property is set to the same value more than once, Message Queuing uses the first entry in the aPropVar array and discards all the subsequent entries. In the aStatus array, an information error value of MQ_INFORMATION_DUPLICATE_PROPERTY is returned for each discarded entry.


Allocating Memory when Retrieving Computer Properties

When retrieving computer properties, Message Queuing requires space for the returned property value. For example, space must be allocated before the pathname of a computer can be retrieved. This space is allocated based on the vt field of the MQPROPVARIANT entry for each element of the aPropVar array. The vt field can contain the specific VARTYPE specified for the property or VT_NULL (VT_NULL is required if the field type of the queue property is VT_LPWSTR).

Typically, applications specify the VARTYPE required by the property. In this case the application is responsible for allocating the corresponding buffer when appropriate. In the following example, the vt field is set to VT_CLSID (the VARTYPE required by PROPID_QM_MACHINE_ID) and the puuid field contains the address of the allocated buffer.

CLSID MachineIdBuffer;
aPropID[i] = PROPID_QM_MACHIONE_ID;
aPropVar[i].vt = VT_CLSID;
aPropVar[i].puuid = &MachineIdBuffer;
i++;

When VT_NULL is specified in the vt field, Message Queuing fills in the appropriate VARTYPE value and allocates memory, if needed, for the returned value. In the following example, the vt field is set to VT_NULL.

aPropID[i] = PROPID_QM_PATHNAME;
aPropVar[i].vt = VT_NULL;
i++;

When Message Queuing allocates a buffer for a returned value (when VT_NULL is specified in the vt field) it is the application's responsibility to free the memory with the MQFreeMemory function


Message Queuing Triggers

Message Queuing triggers allow you to associate the arrival of incoming messages at a destination queue with the functionality of one or more COM components or standalone executable programs. These triggers can be used to define business rules that can be invoked when a message arrives at the queue without the need for any additional programming. Application developers no longer need to write any infrastructure code to provide this kind of message-handling functionality.

The Message Queuing Triggers Service was introduced as a standalone service in MSMQ 2.0 and then incorporated into Message Queuing in MSMQ 3.0. The following illustration shows how the Message Queuing Triggers Service monitors a queue for incoming messages and executes an action, in the form of an executable file or COM component, when the rules of a trigger are evaluated as true.

The Message Queuing Triggers Service consists of the following programs.

  • mqtgsvc.exe: The mqtgsvc.exe program is the executable file for running the service.
  • mqtrig.dll: The mqtrig.dll program implements the COM components used by the service. Note that these COM components are not available to the application developer.
  • mqtrig.tlb: The mqtrig.tlb program defines the COM components used by the service. Note that these COM components are not available to the application developer.
  • mqtgclus.dll: The mqtgclus.dll program defines cluster resources.

The Message Queuing Triggers Service can be started when Message Queuing is installed (by default the service is not running when Message Queuing is installed) or it can be started at a later time by a Message Queuing administrator. For procedures on starting this service, refer to the online Message Queuing Administrator's Guide provided with Whistler.

Message Queuing does not provide any programmable components for starting or stopping the Message Queuing Triggers Service, for creating triggers and their associated rules, or for associating existing rules with a queue. All these tasks are done by a Message Queuing administrator. Please refer to the online Message Queueing Administrator's Guide provided with Whistler for the procedures for running the service and creating and managing triggers.

For information on | See
The components of Message Queuing triggers | Trigger Components
The two types of triggers supported by the Message Queuing Triggers Service | Serialized and Non-Serialized Triggers
How the Message Queuing Triggers Service reads messages | Reading Incoming Messages


Trigger Components

A Message Queuing trigger is an automated mechanism for implementing an action in response to a message arriving at a queue. Each trigger is comprised of a set of rules, with each rule containing a condition that can be tested and an action to take when the condition is evaluated as true.

A rule is a condition-action pair. Each rule describes a condition that can be evaluated to true or false, and specifies an action to take, a COM component or executable file that can be invoked, when the condition is evaluated to true.

A condition is a test that is applied to the message when the message arrives at the queue. A condition is expressed as a logical equation and, as a result, may have more than on element. For example, a single condition may test both the label and priority properties of a message. Condition can test only the properties of the message.

An action is an executable behavior that is invoked when its associated condition is evaluated as true. The action can be defined by a COM component and its associated parameters or an executable file and its associated arguments.

The following illustration shows the relationships between queues, triggers, and rules. Note that there can be a one-to-many relationship between queues and triggers and triggers and rules, and a one-to-one relationship between rules and their condition-action pair. The condition-action pair of each rule is what defines the business rule for the trigger.

For information on | See
The two types of triggers supported by the Message Queuing Triggers Service | Serialized and Non-Serialized Triggers
How the Message Queuing Triggers Service reads messages | Reading Incoming Messages


Serialized and Non-Serialized Triggers

Message Queuing triggers can be serialized or non-serialized. The type of triggers used affects how the Message Queuing Triggers Service test the incoming messages to the queue.

Serialized triggers process messages in the order that the messages arrive, testing for each trigger associated with the queue before moving on to the next message. When serial triggers are defined, the throughput of the Message Queuing Triggers Service is lower than for non-serialized triggers because messages must be processed one at a time.

Non-serialized triggers process messages faster, but the messages are not necessarily processed in the order that they arrived. Non-serialized triggers provide a faster throughput because one message may be tested for one trigger while a second message is tested for another trigger.

If you specify multiple triggers for a queue, you must define all the triggers as serial or non-serial. It is recommended that you use only one trigger with the serialized option since the order of trigger firing is random according to their GUIDs.

For information on | See
The components of Message Queuing triggers | Trigger Components
How the Message Queuing Triggers Service reads messages | Reading Incoming Messages


Reading Incoming Messages

When the Message Queuing Triggers Service is running, the service reads each message as it arrives at the queue. The Message Queuing Triggers Service does not process the information in the messages, nor does it limit access to the messages (it is possible for other Message Queuing applications to remove messages before the trigger service can peek at a message in the queue).

To read the messages in the queue the service starts at the front of the queue and peeks at or retrieves all the messages in the queue. After checking all the existing messages, the service waits at the end of the queue for a new message. (If the service is stopped and restarted, it will read all messages in the queue again.)

When all the messages sent to the queue have the same priority, new messages are always placed at the end of the queue. After peeking at all the existing messages in the queue, the Message Queuing Triggers Service will fire the trigger each time a new message arrives at the end of the queue. The illustration below shows a queue with four messages. The Message Queuing Triggers Service peeks at msg1, msg2, msg3, and msg4, then continues to peek at messages as they arrive at the end of the queue.

When messages with different priorities are sent to the queue, new message can be placed anywhere in the queue. This means that when a higher priority message is placed somewhere in the queue, the Message Queuing Triggers Service peeks at the new message wherever it is placed in the queue, then continues to peek at all the lower priority messages that follow the new message in the queue.

In the previous illustration, the MSMQ Triggers Service makes one pass through the queue peeking at messages msg1, msg2, msg3, and msg4. Then when msg5 arrives at the queue, a new priority 1 message, it is placed between msg2 and msg3. The service goes back and peeks at msg5, then continues to peek at msg3, and msg4 again. Note that in this case, the trigger is tested twice for messages msg3 and twice for msg4.

For information on | See
The components of Message Queuing triggers | Trigger Components
The two types of triggers supported by the Message Queuing Triggers Service | Serialized and Non-Serialized Triggers


Message Queuing Security Services

The Message Queuing security services provide digital signatures for authenticating messages, security descriptors for access control of queues, encryption services for private messages, and auditing services for tracking performance.

For information on | See
Digital signatures | Message Authentication
Security descriptors | Access Control
Encryption services | Message Encryption
Auditing services | Auditing


Message Authentication

Message authentication provides two services. It provides a way to ensure message integrity and a way to verify who sent the message. To request authentication, the sending application must set the authentication level of the message to be authenticated and attach a security certificate to the message. This certificate can be attached directly by the sending application, or it can be attached by Message Queuing using security context information.

Authenticating for message integrity ensures that no one has tampered with the message or changed its content. When authentication is requested, the Message Queuing run-time digitally signs the message when it is sent, and the receiving queue manager verifies the digital signature when it receives the message. Once message integrity is established, Message Queuing verifies who sent the message.

Note The Message Queuing run-time uses a private signing key to sign the message digitally. The receiving queue manager then uses the associated public signing key to verify this digital signature.

By default, Message Queuing authenticates who sent the message. However, the sending application can disable this type of authentication by not sending a sender identifier with the message. For Message Queuing to verify who sent the message, the sending application must register the certificate in the directory service before sending the message. The receiving queue manager then looks in the directory service and finds the identifier of the user that registered the certificate. The queue manager then compares this identifier to the SID attached to the message, and if they are the same, the queue manager authenticates the message and passes it on to the destination queue.

Note Message Queuing cannot perform sender authentication in a Windows® 2000 Workgroup environment. The Workgroup environment does not use the directory service, so you cannot register the certificate.

The process Message Queuing uses to authenticate a message is the same regardless of the type of certificate you attach to the message. The following paragraphs provide a brief description of what information each type of certificate contains and how the receiving application can use that information.

Internal Certificates

Internal certificates are used when operating in a Windows 2000 domain, where the sender identifier registered with the certificate is an SID. Without this SID, Message Queuing would not be able to authenticate who sent the message.

An internal certificate contains the public key and sender identifier (SID) of the user that registered the certificate. Due to the fact that the SID is already attached to the message in its sender identifier property (PROPID_M_SENDERID and MSMQMessage.SenderId), the information in the certificate is of little use to the receiving application.

External Certificates

External certificates are used when you send messages to operating environments other than Windows 2000—environments where the sender's security identifier (SID) is meaningless. External certificates are also used when you are working in a Windows 2000 Workgroup environment or when you are working in a Windows 2000 domain environment and want to use more than just the sender identifier attached to the message to validate who sent the message.

Each external certificate contains the public key of the sender along with additional information requested by the certification authority that created the certificate. This additional information is not used by Message Queuing, but it may be used by the receiving application to further validate who sent the message.

Note The information provided by external certificates is guaranteed by the certification authority that created the certificate. Message Queuing does not validate the information in the certificate.

For information on | See
Using security context information | When to Use Security Context Information
Registering internal or external certificates | Registering a Certificate
The process of authenticating messages | How Message Queuing Authenticates Messages


Registering a Certificate

You must register a certificate in the directory service whenever you want Message Queuing to verify the sender of the message to which the certificate will be attached (by default Message Queuing verifies who sent the message whenever an authenticated message is sent). Message Queuing provides two ways to register a certificate. Internal and external certificates can be registered programmatically, or they can be registered by way of Message Queuing in Control Panel.

Note For MSMQ 1.0 applications, certificates must be registered manually by using the MS Message Queue in Control Panel.

To register a certificate using MS Message Queue

  1. Using Control Panel, open MS Message Queue.
  2. Select the Security tab.
  3. Click Register. Message Queuing creates the internal certificate locally when Register is clicked the first time MS Message Queue is run.
  4. Select the internal certificate from the list of available certificates. (This list includes the internal certificate and all external certificates that have been put into your personal store.)
  5. Click OK. The selected certificate is now registered in the directory service.
For information on | See
Registering a certificate using function calls | MQRegisterCertificate
Registering a certificate using COM method calls | MSMQApplication.RegisterCertificate
Using security context information | When to Use Security Context Information
The process of authenticating messages | How Message Queuing Authenticates Messages


When to Use Security Context Information

Use security context information when you are sending a large number of messages using the same certificate or when you are impersonating a user.

The Message Queuing run-time uses the security context information to attach a certificate to the messages without having to fetch the certificate from the certificates store and extract information each time a message is sent.

Note Security context information is used only by the sending application. It is used to attach a certificate to a message and is not available to the receiving application.

When sending authenticated messages, you can extract security context information from a certificate, or you can use the default security context initialized by Message Queuing run time.

To extract the security context information from a certificate, the sending application must call MQGetSecurityContext or MSMQMessage.AttachCurrentSecurityContext.

To use the default security context, simply send the authenticated message without specifying a certificate and without specifying a security context. The default security context is initialized when you open the queue to send messages.

Note MQGetSecurityContext does not associate the cached information with a specific message. It places the extracted information in a buffer, Consequently, you must specify the handle to this security context buffer in the security context property (PROPID_M_SECURITY_CONTEXT) of the message before you send it.

Once the security context information is obtained, you should not attach the certificate to message; the Message Queuing run-time will do this for you. Security context information is ignored if the security certificate property of the message (PROPID_M_SENDER_CERT or MSMQMessage.SenderCertificate) contains a certificate.

When impersonating another user, the sending application must call MQGetSecurityContext before it sends a message. Once the security information for the impersonated user is retrieved, the sending application can revert to the original user and later use the impersonated security context to send another message without needing to impersonate the user again.

For information on | See
Message integrity and sender authentication | Message Authentication
The process of authenticating messages | How Message Queuing Authenticates Messages


Impersonating a User

Message Queuing provides you with a means to impersonate another user when passing authenticated messages that were not sent by you. Typically, this happens when server applications need to pass messages they have received on to other destination queues.

To impersonate another user you must first retrieve the security information of the user you want to impersonate, cache that information in the security context buffer, then later use the information in security context buffer to send the impersonated messages. Note that you can revert back to the original user as soon as the impersonated information is in the security context buffer.

To retrieve the security context of another user

  1. Call the Win32 API function RegLoadKey to load the registry hive of the impersonated user.
  2. Call RegCloseKey (HKEY_CURRENT_USER) to close the current user registry.
  3. Call ImpersonateLoggedOnUser and MQGetSecurityContext to access the registry of the impersonated user and retrieve information about the impersonated user. The call to MQGetSecurityContext will retrieve the security context information and place it in the security context buffer for later use.

The calls to RegCloseKey, ImpersonateLoggedOnUser, and MQGetSecurityContext and any other calls that may access the registry under HKEY_CURRENT_USER must be protected by the same critical section object.

Once the security information for the impersonated user is retrieved, the sending application can revert back to the original user and later use the impersonated security context information to send messages without needing to impersonate the user again.


How Message Queuing Authenticates Messages

Message Queuing authenticates messages at the request of the sending application. When the sending application indicates that a message is to be authenticated, the Message Queuing run-time code performs the following tasks:

  • Retrieves the internal certificate, external certificate, or security context information provided by the sending application.

    For internal certificates, the certificate is provided by Message Queuing.

    For external certificates, the certificate is provided in the sender certificate property (PROPID_M_SENDER_CERT or MSMQMessage.SenderCertificate) of the message

    For security context information, the information is provided in the security context information property (PROPID_M_SECURITY_CONTEXT or MSMQMessage.AttachCurrentSecurityContext) of the message

  • Obtains the private signing key of the sending application and caches it in the security context information buffer.

    For internal certificates, Message Queuing locates the private signing key internally.

    For external certificates, Message Queuing searches for the private signing key in the Internet Explorer personal certificate store. (This is why the external certificate must be registered in the Internet Explorer personal certificate store.)

  • Computes a hash value of the message using the algorithm specified by the hash algorithm property (PROPID_M_HASH_ALG or MSMQMessage.HashAlgorithm) of the message.

    The hash value is based on several message properties. For a description of what properties are used, see Digital Signatures.

  • Encrypts the hash value using the private signing key. This is the digital signature that will be attached to the message.
  • Attaches the certificate and the digital signature to the message and sends the message on to the receiving queue manager.

When the receiving queue manager receives the message, it performs the following tasks:

  • Computes the hash value of the message by means of the algorithm specified in PROPID_M_HASH_ALG or MSMQMessage.HashAlgorithm. The hash value is based on several message properties. For a description of what properties are used, see Digital Signatures.
  • Extracts the public key from the certificate.
  • Decrypts the digital signature by means of the public key, obtaining the hash value sent with the message.
  • Compares the hash value computed by the queue manager to the hash value decoded from the digital signature.
If the hash values are | The receiving queue manager
The same and the sender identifier is attached to the message | Verifies who sent the message (see next bullet).
The same and the sender identifier is not attached to the message | Verifies the access rights of the queue (skip next bullet).
The hash values are not the same | Discards the message, and a negative acknowledgment is returned to the sending application if such an acknowledgment was requested.

  • To verify who sent the message, the receiving queue manager looks in the directory service and finds the identifier of the user that registered the certificate. It then compares the sender identifier (SID) in the directory service with the SID in the sender identifier property (PROPID_M_SENDERID or MSMQMessage.SenderId) of the message.

    If they are the same, the SID in the message is valid, and the receiving queue manager then verifies the access rights of the queue.

    If they are not the same, the message is discarded and a negative acknowledgment is returned to the sending application if such an acknowledgment was requested.
    If the hash values are | The receiving queue manager
    The same and the sender identifier is attached to the message | Verifies who sent the message (see next bullet).
    The same and the sender identifier is not attached to the message | Verifies the access rights of the queue (skip next bullet).
    The hash values are not the same | Discards the message, and a negative acknowledgment is returned to the sending application if such an acknowledgment was requested.

  • To verify the access rights of the queue the receiving queue manager compares the sender identifier attached to the message with the ACL of the queue. If the sender identifier was not sent with the message, the sending application did not want to validate who sent the message, the queue must allow everyone send access to the queue.

    If the sender has send access rights, the receiving queue manager authenticates the message.

    If the sending application does not have send access rights, the message is discarded and a negative acknowledgment is returned to the sending application if such an acknowledgment was requested.

  • To authenticate the message, the receiving queue manager sets the authenticated property (PROPID_M_AUTHENTICATED, PROPID_M_AUTHENTICATED_EX or MSMQMessage.IsAuthenticated, MSMQMessage.ReceivedAuthenticationLevel) of the message, inserts the message in its destination queue, and returns a positive acknowledgment to the sending application if such an acknowledgment was requested.

Note Message Queuing does not validate external certificates. The receiving application can perform any validation requirements on the certificate before using an authenticated message. Message Queuing generates the digital signature of a message when it is sent and verifies the digital signature when the message is received, but does not validate the certificate itself.

For information on | See
Security Certificates | Message Authentication
Registering a certificate programmatically or manually | Registering a Certificate


Digital Signatures

Digital signatures are used to ensure message integrity. They are created by the Message Queuing run time on the source computer, attached to the message when it is sent, and then used by the receiving queue manager to verify that the message has not been modified.

Message Queuing provides the following types of digital signatures.

  • MQMSG_AUTH_LEVEL_SIG10 signature

    Introduced in MSMQ 1.0. This signature uses a set of six message properties when creating the digital signature. (The properties used when creating this signature are listed below.)

  • MQMSG_AUTH_LEVEL_SIG20 signature

    Introduced in MSMQ 2.0. This signature uses a set of 15 message properties when creating the digital signature. These message properties include the six message properties used in MQMSG_AUTH_LEVEL_SIG10 signature plus 9 more. (The properties used when creating this signature are listed below.)

  • MQMSG_AUTH_LEVEL_SIG30 signature

    Introduced in MSMQ 3.0. This signature is only used when using distribution lists, multicast addresses or multiple-element format names to send messages.

    MQMSG_AUTH_LEVEL_SIG30 signatures use the same 15 message properties used by MQMSG_AUTH_LEVEL_SIG20 signatures with one exception. Because the message is sent to multiple destination queues, the destination queue format name property is used instead of the destination queue property. (The properties used when creating this signature are listed below.)

Applications can specify which type of digital signature Message Queuing will use by setting the authentication level property of the message (PROPID_M_AUTH_LEVEL or MSMQMessage.AuthLevel) or by setting registry keys on the source and target computer. For information on digital signature registry keys, see Digital Signature Registry Keys.

The digital signature is an encrypted hash value based on a set of message properties. The message properties for each digital signature type are listed below in the order that they are used when computing the hash. Note that Message Queuing uses the first seven properties for all digital signature types. The remaining properties are used only for certain types of digital signatures.

  • Correlation identifier property: PROPID_M_CORRELATIONID or MSMQMessage.CorrelationId
  • Application specific property: PROPID_M_APPSPECIFIC or MSMQMessage.AppSpecific
  • Message body property: PROPID_M_BODY or MSMQMessage.Body
  • Message label property: PROPID_M_LABEL or MSMQMessage.Label
  • Response queue property: PROPID_M_RESP_QUEUE or MSMQMessage.ResponseQueueInfo
  • Administration queue property: PROPID_M_ADMIN_QUEUE or MSMQMessage.AdminQueueInfo
  • Destination queue property (MQMSG_AUTH_LEVEL_SIG20 signatures only): PROPID_M_DEST_QUEUE or MSMQMessage.DestinationQueueInfo
  • Destination queue format name property (MQMSG_AUTH_LEVEL_SIG30 signatures only): PROPID_M_DEST_FORMAT_NAME or MSMQMessage.Destination.
  • Source computer identifier (MQMSG_AUTH_LEVEL_SIG20 and MQMSG_AUTH_LEVEL_SIG30 signatures only): PROPID_M_SRC_MACHINE_ID or MSMQMessage.SourceMachineGuid
  • Delivery mode property (MQMSG_AUTH_LEVEL_SIG20 and MQMSG_AUTH_LEVEL_SIG30 signatures only): PROPID_M_DELIVERY or MSMQMessage.Delivery
  • Message priority property(MQMSG_AUTH_LEVEL_SIG20 and MQMSG_AUTH_LEVEL_SIG30 signatures only): PROPID_M_PRIORITY or MSMQMessage.Priority
  • Message journaling property (MQMSG_AUTH_LEVEL_SIG20 and MQMSG_AUTH_LEVEL_SIG30 signatures only): PROPID_M_JOURNAL or MSMQMessage.Journal
  • Acknowledgment level property (MQMSG_AUTH_LEVEL_SIG20 and MQMSG_AUTH_LEVEL_SIG30 signatures only): PROPID_M_ACKNOWLEDGE or MSMQMessage.Ack
  • Message class property (MQMSG_AUTH_LEVEL_SIG20 and MQMSG_AUTH_LEVEL_SIG30 signatures only): PROPID_M_CLASS or MSMQMessage.Class
  • Body type property (MQMSG_AUTH_LEVEL_SIG20 and MQMSG_AUTH_LEVEL_SIG30 signatures only): PROPID_M_BODY_TYPE
  • Connector type property (MQMSG_AUTH_LEVEL_SIG20 and MQMSG_AUTH_LEVEL_SIG30 signatures only): PROPID_M_CONNECTOR_TYPE or MSMQMessage.ConnectorTypeGuid


Digital Signature Registry Keys

For computers running MSMQ 2.0 and MSMQ 3.0, you have the option of specifying the authentication level using message properties or registry keys. The registry keys described below can be used set to specify which type of signature will be attached to the message sent from the source computer and which type of signature will be used to authenticate the message on the target computer.

On the Source Computer

Use the following registry key to specify what type of signature will be created by the Message Queuing run time and attached to the message when the message is sent. Note that if this registry key is not available, Message Queuing run time will only create MQMSG_AUTH_LEVEL_SIG10 signatures.

hklm\software\microsoft\msmq\parameters\security\SendMsgAuthn

To specify the signature type, set this key to one of the following values.

When sending Messages to Setting Results
Target computers running any version of Message Queuing. 1 Message Queuing creates MQMSG_AUTH_LEVEL_SIG10, MQMSG_AUTH_LEVEL_SIG20, and MQMSG_AUTH_LEVEL_SIG30 signatures.

If the message is sent without using distribution lists, multicast addresses, or multiple-element format names, an MQMSG_AUTH_LEVEL_SIG10 signature and MQMSG_AUTH_LEVEL_SIG20 signature are attached to the message.

If the message is sent using distribution lists, multicast addresses, or multiple-element format names, an MQMSG_AUTH_LEVEL_SIG10 signature and MQMSG_AUTH_LEVEL_SIG30 signature are attached to the message.

This setting should be used when the sending application does not know what version of Message Queuing is running on the target computer.
Target computers running MSMQ 1.0 (default setting). 2 Message Queuing creates only MQMSG_AUTH_LEVEL_SIG10 signatures.

This setting should be used only when the sending application is sure that the target computer is running MSMQ 1.0.
Target computers running MSMQ 2.0 or MSMQ 3.0. 4 Message Queuing creates only MQMSG_AUTH_LEVEL_SIG20 signatures.

This setting should be used only when the sending application is sure that the target computer is running MSMQ 2.0 or MSMQ 3.0, and that distribution lists, multicast addresses, and multiple-element format names are not used to send messages.
Target computers running MSMQ 2.0 or MSMQ 3.0. 8 Message Queuing creates MQMSG_AUTH_LEVEL_SIG20 and MQMSG_AUTH_LEVEL_SIG30 signatures.

This setting should be used only when the sending application is sure that the target computer is running MSMQ 2.0 or MSMQ 3.0, and that distribution lists, multicast addresses, and multiple-element format names may be used when sending messages.

When setting this registry key, note that the sending application can override the registry key setting by setting the authentication level property (PROPID_M_AUTH_LEVEL, MSMQMessage.AuthLevel) of each message it sends. The authentication level property can be set to use the registry key setting, or ignore the registry key setting and use a specific signature.

If the sender registry key is set to 1 and the authentication property of the message is set to MQMSG_AUTH_ALWAYS, the Message Queuing run time will compute multiple signature types and attach them to the message. Although creating multiple signatures reduces performance slightly on the source computer, it allows you to send messages to target computers that are running MSMQ 1.0, MSMQ 2.0, or MSMQ 3.0.

On the Target Computer

On the target computer, you can set a registry key to specify what type of signature will be used to authenticate the message. (Receiving applications can also use message properties to find out if authentication was requested and, if the target computer is running MSMQ 2.0 or later, what type of signature was attached to the message.

The following registry key specifies what type of signature is used by the receiving computer.

hklm\software\microsoft\msmq\parameters\security\RcvOnlyEnhMsgAuthn

To specify the type of signature, set this key to one of the following values.

To authenticate using | Set registry key to
MQMSG_AUTH_LEVEL_SIG10, MQMSG_AUTH_LEVEL_SIG20 or MQMSG_AUTH_LEVEL_SIG30 signatures (default setting). | 0
MQMSG_AUTH_LEVEL_SIG20 and MQMSG_AUTH_LEVEL_SIG30 signatures. | 1


Access Control

Operations on queues can be restricted to a specific user or group of users. When a queue is created, a security descriptor is included in the call to specify who has access rights to the queue's operations.

Queue operations that can be set include creating, deleting, and opening a queue (for sending messages to and reading messages from the queue). Operations also include getting and setting a queue's properties and security descriptor.

For applications using functions, the security descriptor is specified by the lpSecurityDescriptor parameter of MQCreateQueue. For applications using COM components, the default security descriptor is automatically attached to the queue when it is created and can only be changed using functions.

Before Message Queuing performs any operation on a queue, it checks the queue's security descriptor to determine if the user has sufficient access rights to perform the requested operation. To do this, Message Queuing checks whether the operation is restricted. If the operation is restricted, Message Queuing then checks the identity of the user to see if the restriction applies to that user. If it does, the operation is not allowed to continue.

With the exception of putting a new message in a queue, Message Queuing can verify the identity of the user by the access token attached to the process. Access tokens are produced by the system. When a user logs on, the system verifies the user's password by comparing it with information stored in the system's security database. If the password is valid, the system produces an access token and attaches it to each process started by the user.

However, Message Queuing cannot use this access to put a new message in the queue. Instead, it uses a security identifier (SID) that Message Queuing attached to the message when it was sent. Similar to the access token, the user's SID is created by the application. For more information, see access tokens and SIDs in the Security section in the Microsoft Platform SDK.

Applications can retrieve or modify the security descriptor of a queue if they have sufficient access rights. See MQGetQueueSecurity and MQSetQueueSecurity.


Message Encryption

Message Queuing provides a secured channel for sending private, 40-bit or 128-bit encrypted messages throughout your enterprise. When private messages are sent, Message Queuing ensures that the body of the messages are kept encrypted from the moment they leave the source queue manager to the moment they reach their receiving queue manager.

Note The privacy level (PROPID_Q_PRIV_LEVEL or MSMQQueueInfo.PrivLevel) of a queue can also be set so that the queue will only accepts private messages. If the privacy level of the sent message does not correspond to the privacy level of the queue, the message is rejected by the queue, and, if the sending application requested a negative acknowledgment messages when it sent the message, an MQMSG_CLASS_BAD_ENCRYPTION class acknowledgment message is returned to the administration queue specified by sending application.

When the private message arrives at the receiving queue manager, its body is decrypted and the message is sent on to its destination queue. The receiving application never sees the encrypted body of the message.

Message Queuing provides two ways to send private messages. You can let the source queue manager encrypt the message body for you, or your application can encrypt the message body itself .

Message Queuing can encrypt the message body for you when your application is sending messages within a Windows 2000 enterprise where there is access to the directory service.

Your application must encrypt the message body when it is sending messages where there is no access to the directory service (for example, when sending message using a direct format name, when operating in foreign enterprises, or when operating in a Windows 2000 workgroup environment).

Note MSMQ 1.0 and 2.0 Differences: MSMQ 1.0 does not provide the COM components needed to encrypt messages manually. When using the COM components provided by MSMQ 1.0, you must always allow Message Queuing to encrypt the message body for you. On the other hand, MSMQ 2.0 provides full encryption support. You can tell Message Queuing to encrypt the message body, or your application can encrypt the message body.

Regardless of how the message is encrypted when it is sent, the receiving queue manager always decrypts the message body and then passes the message on to the queue.

For information on | See
Sending Message Queuing–encrypted messages | Message Queuing–Encrypted Messages
Sending manually encrypting messages when there is no access to the directory service. | Application-Encrypted Messages
Reading private messages from the destination queue | Reading Private Messages


Message Queuing-Encrypted Messages

Platform SDK: Message Queuing

MSMQ-Encrypted Messages

To let the source queue manager encrypt your messages, the sending application must set the privacy level and encryption algorithm (optional) properties of the message when the message is sent.

The privacy level property (PROPID_M_PRIV_LEVEL or MSMQMessage.PrivLevel) of the message must be set to one of the following.

Set to | For
MQMSG_PRIV_LEVEL_BODY | 40-bit encryption.
MQMSG_PRIV_LEVEL_BODY_BASE | 40-bit encryption (MSMQ 2.0 only)
MQMSG_PRIV_LEVEL_BODY_ENHANCED | 128-bit encryption (MSMQ 2.0 only)

The encryption algorithm property (PROPID_M_ENCRYPTION_ALG or MSMQMessage.EncryptAlgorithm) of the message can be set to MQMSG_RC2 or MQMSG_RC4. If this property is not set, the default RC2 encryption algorithm is used to encrypt the message. Message encryption is based on public-key encryption using the Microsoft® Cryptographic API with an underlying Microsoft Base cryptogrphic provider for 40 bits encryption or Microsoft Enhanced Cryptographic provider for 128 bits encryption.

For information on | See
Manually encrypting messages when there is no access to the directory service. | Application-Encrypted Messages
Reading private messages from the destination queue | Reading Private Messages


Application-Encrypted Messages

To encrypt a message body, the sending application must have an RC2 or RC4 symmetric key to encrypt the message body, as well as the public key of the receiving computer to encrypt the symmetric key.

Note MSMQ 1.0 and 2.0 Differences: MSMQ 1.0 does not provide the COM components needed to encrypt messages manually. When using the COM components provided by MSMQ 1.0, you must always allow Message Queuing to encrypt the message body for you. On the other hand, MSMQ 2.0 provides full encryption support. You can tell Message Queuing to encrypt the message body, or your application can encrypt the message body.

The following illustration shows the process needed to encrypt a message body.

When your application is encrypting messages, the following message properties must be set accordingly:

  • PROPID_M_BODY or MSMQMessage.Body

    This property contains encrypted message body while the message is sent.

  • PROPID_M_CONNECTOR_TYPE or MSMQMessage.ConnectorTypeGuid

    In this case, this property tells Message Queuing on the sending computer that the destination symmetric key property was not set by Message Queuing.

  • PROPID_M_DEST_SYMM_KEY or MSMQMessage.DestinationSymmetricKey

    This property contains the symmetric key needed to decrypt the message body.

  • PROPID_M_ENCRYPTION_ALG or MSMQMessage.EncryptAlgorithm

    Message Queuing supports RC2 and RC4 encryption algorithms. The encryption algorithm must be specified when the symmetric key is created, used to encrypt the body of the message, then sent on to the receiving application.

  • PROPID_M_PRIV_LEVEL or MSMQMessage.PrivLevel

    If your application is encrypting its messages with a 40-bit key, the privacy level property should be ignored. If your application is encrypting its messages with a 128-bit key, the privacy level property must be set to MQMSG_PRIV_LEVEL_BODY_ENHANCED.

For information on | See
Sending Message Queuing–encrypted messages | Message Queuing–Encrypted Messages
Reading private messages from the destination queue | Reading Private Messages


Reading Private Messages

The receiving application retrieves a private message in the same way it would retrieve any clear text message. It can, however, look at the privacy level property of the message to determine whether the message was sent encrypted and look at the encryption algorithm property to see how the message was encrypted.

For information on | See
Sending Message Queuing–encrypted messages | Message Queuing–Encrypted Messages
Sending manually encrypting messages when there is no access to the directory service. | Application-Encrypted Messages


Auditing

Message Queuing allows you to audit access operations for the queues in your Message Queuing enterprise. The operations that you can audit include creating a queue, opening a queue, setting or retrieving queue properties, and deleting a queue. Note that message operations such as sending or retrieving a message are not audited.

You can enable and disable auditing by calling MQSetQueueSecurity (there is no equivalent COM method or property). This function allows you to add queue operations to the system access control list (SACL) of the queue's security descriptor (thus enabling auditing) or remove them (disabling auditing). Any operation specified by the SACL of a queue is audited by the operating system.

Auditing is set up and maintained by the operating system installed on the computer. The operating system is notified by the directory service or Message Queuing, depending on whether the queue is public or private, whenever an audited operation is performed on a queue. For public queues, the directory service performs this notification. For private queues, Message Queuing peforms the notification.

(For a complete description of auditing, see Microsoft® Windows NT® or Windows® 2000 Help).

The following constants specify which queue operations can be audited:

  • MQSEC_DELETE_MESSAGE and MQSEC_PEEK_MESSAGE: The operating system is notified whenever the queue is opened with receive access. Note this does not imply when a message is removed from the queue.
  • MQSEC_DELETE_JOURNAL_MESSAGE and MQSEC_PEEK_MESSAGE: The operating system is notified whenever the queue's journal is opened with receive access. Note this does not imply only when a message is removed from the queue journal.
  • MQSEC_PEEK_MESSAGE: The operating system is notified whenever the queue is opened for peek access. Note this does not imply when a message is peeked at in the queue.
  • MQSEC_GET_QUEUE_PROPERTIES. The operating system is notified whenever the queue's properties are retrieved.
  • MQSEC_SET_QUEUE_PROPERTIES. The operating system is notified whenever the queue's properties are set.
  • MQSEC_DELETE_QUEUE. The operating system is notified when the queue is deleted.(equivalent to DELETE: as defined in the Win32 header files).
  • MQSEC_GET_QUEUE_PERMISSIONS. The operating system is notified whenever the queue's security descriptor is retrieved.(equivalent to READ_CONTROL: as defined by the Win32 header files).
  • MQSEC_CHANGE_QUEUE_PERMISSIONS. The operating system is notified whenever the discretionary access control list (DACL) of the queue's security descriptor is changed (equivalent to WRITE_DAC: as defined by the Win32 header files).
  • MQSEC_TAKE_QUEUE_OWNERSHIP: The operating system is notified whenever the owner of the queue is changed.(equivalent to WRITE_OWNER: as defined by the Win32 header files).

Audit log messages are written in the security event log on the server that performs the actual operation, not necessarily the server that owns the object. For example, audits for opening a queue are logged on the computer where the queue resides. However, other operations (such as setting queue properties) are logged on the machine that performed the operation. As a result, the audit messages for a queue can be logged on servers throughout your Message Queuing enterprise.


Message Queuing Transactions

The following illustration shows how transactions are used by the sending and receiving applications. In this model, Message Queuing uses two transactions: one to send messages to the queue and the other to retrieve messages from the queue.

In this model, the sending transaction can commit to sending the messages to the queue, and the receiving application can commit to retrieving the messages

Note When receiving an error from a call to commit the transaction, the transaction is in doubt, it may or may not have been committed.

Message Queuing provides its own confirmation process to notify the sending application either that the messages were retrieved from the queue or why the receiving application failed to retrieve them. Note that this confirmation process is completely independent from committing to the transaction.

Note A single transaction may contain both transactional send and receive calls.

For information on | See
The confirmation process used by Message Queuing | Transaction Confirmation Process
Requirements for sending and receiving messages within a transaction | Sending and Retrieving Messages within a Transaction
An application used to retrieve messages from remote queues when transaction are needed | Transactional Read-response Applications
A summary of the different transaction types provided by Message Queuing | Transaction Types


Transaction Confirmation Process

Message Queuing uses the transactional dead-letter queue of the source computer to indicate that the messages were retrieved from the queue or why the receiving application failed to retrieve them. This confirmation of whether a message was retrieved is completely independent of the application's committing to the transaction.

The confirmation process uses the time-to-be-received property, time-to-reach-queue property (for MSMQ 2.0), and the class property of the message, plus the source computer's transactional dead letter queue. Non-confirmed transactional messages are placed in the transactional dead letter queue if the source queue manager does not receive a positive confirmation from the remote queue manager.

Note For MSMQ 2.0 applications, the journal property of the message must be set to MQMSG_DEADLETTER to enable the confirmation process. By default, MSMQ 2.0 sets the journal property of transactional messages to MQMSG_JOURNAL_NONE.

For MSMQ 1.0 applications, the confirmation process (placing non-confirmed messages into the transactional dead letter queue of the sending computer) is applied regardless of the what the journal property is set to. In addition, if you are running MSMQ 1.0 applications on an MSMQ 2.0 computer, you can force the computer to always set the journaling property to MQMSG_DEADLETTER by setting the XactDeadLetterAlways registry entry to 1.

From an application point of view, it is important to understand exactly when the non-confirmed message is placed in the transactional dead-letter queue. Applications must check for the message after the proper time interval. Checking to see if the non-confirmed message is in the dead letter queue is the only way the sending application can be certain of the outcome of the remote receiving transaction.

For MSMQ 1.0 applications, the time interval for placing the non-confirmed message in the transactional dead-letter queue is the time-to-be-received setting of the message. The source queue manager places a copy of the message in the dead letter queue if it does not receive a positive confirmation before the time-to-be-received time of the message expires.

For MSMQ 2.0 applications, the time interval is the time-to-be-received setting plus some extended amount, allowing more time for a confirmation to be returned. This additional time can be defined by setting the XactDelayReceiveNack registry setting (there is no default for this setting). If, however, XactDelayReceiveNack does not exist, the additional time is the value of either the time-to-be-received setting or the time-to-reach-queue setting, whichever is smaller.

The following table summarizes how the time-to-be-received timer (TTBR), the time-to-reach-queue timer (TTRQ), and XactDelayReceiveNack are used to compute the extended time interval. Note that if you do not set the time-to-be-received timer (TTBR), the timer's default value of INFINITE is used. In that case, any additional time is irrelevant.

TTBR | TTRQ | XactDelay ReceiveNack | Extended time interval
Not set. (INFINITE) | NA | NA | INFINITE +
Set | NA | Set | TTBR + XactDelayReceiveNack
Set | Not Set | Not set | TTBR + TTBR
Set | Set | Not set | TTBR + min(TTBR, TTRQ)

XactDelayReceiveNack is found under

HKEY_LOCAL_MACHINE

SOFTWARE

MICROSOFT

MSMQ

Parameters

XactDelayReceiveNack = (time in seconds)

Consequently, the sending application can determine whether the message was confirmed by waiting for the proper interval and then checking whether a copy of the message is in the dead letter queue.

If the message is not there, the message has been successfully delivered to the destination queue and the receiving application has successfully retrieved it. Message Queuing guarantees this because the source queue manager has received the explicit positive confirmation from the receiving queue manager.

If the message is in the dead letter queue, the sending application can look at the class property of the messages to determine the status of the message. The class property of the message is updated by Message Queuing when it is placed in the dead letter queue.

For information on | See
Requirements for sending and receiving messages within a transaction | Sending and Retrieving Messages within a Transaction
An application used to retrieve messages from remote queues when transaction are neededAn application used to retrieve messages when transaction are needed | Transactional Read-response Applications
A summary of the different transaction types provided by Message Queuing | Transaction Types


Sending and Retrieving Messages within a Transaction

The requirements for sending and retrieving messages are based on the type of queue used (transactional or non-transactional) and the queues location (local or remote).

When using transactions to send messages, the messages can be sent to any transactional queue regardless of where the queue is located. In this case, non-transactional queues cannot be used.

The table below compares transactional and non-transactional send operations with local transactional and non-transactional queues and remote transactional and non-transactional queues.

When using a transaction to retrieve messages, the queue must be a local transactional queue. You cannot retrieve a message from a remote transactional queue, or from a local non-transactional queue within a transaction.

Note Message Queuing does not provide support for remote transactional-read operations. However, this same functionality can be achieved by using a transactional read-response application. For a description of this type of application, see Transactional Read-response Applications.

The table below compares transactional and non-transactional receive operations with local transactional and non-transactional queues and remote transactional and non-transactional queues.

Not that non-transactional receives are allowed from any queue (transactional or non-transactional, local or remote). In particular, a non-transactional receive from a transactional queue is essentially a transaction consisting of a single receive operation.

For information on | See
The confirmation process used by Message Queuing | Transaction Confirmation Process
An application used to retrieve messages from remote queues when transaction are needed | Transactional Read-response Applications
A summary of the different transaction types provided by Message Queuing | Transaction Types


Transactional Read-Response Applications

A transactional read-response application is used when you need to transactionally retrieve messages from a remote transaction queue. It uses transactions to redirect the messages from the remote queues on the sending computer to local queues on the receiving computer.

In this scenario, the read-response application resides on a server that contains two transactional queues: an input queue for collecting messages from sending applications, and a read-request queue for collecting read-requests from the receiving applications.

The read-response application uses a single transaction to retrieve a request from the request queue, retrieve a message from the input queue, then forward the message from the input queue to the receiving application that made the request. In this way the receiving application gets its messages within a transaction without the need to perform a transactional remote-read operation.

To get its messages, the receiving application sends a request message to the server specifying the response queue to which the input message should be sent to. This request can be made within the context of its own transaction. However, it is independent of the transaction used to send the message back to the receiving application.

For information on | See
Restrictions on sending and retrieving messages within a transaction | Sending and Retrieving Messages within a Transaction
A summary of the different transaction types provided by Message Queuing | Transaction Types


Transaction Types

Message Queuing provides several types of transactions for sending and receiving messages. These transactions can be explicitly invoked by providing pointers to a transaction object or implicitly invoked by directing Message Queuing to find the appropriate transaction object.

Transactions that can be explicitly invoked include Message Queuing internal transactions and the Microsoft® Distributed Transaction Coordinator (MS DTC) external transactions.

Transactions that can be implicitly invoked include single-message transactions, current Microsoft® Transaction Server™ (MTS), and XA-compliant transactions. The current MTS or XA transaction is used only if it is available. In these cases, Message Queuing decides (with the help of MTS or MS DTC) whether the call will truly be part of a transaction.

For information on | See
Specifying a transaction when sending or retrieving messages. | Sending and Retrieving Messages within a Transaction
An application used to retrieve messages from remote queues when transaction are needed | Transactional Read-response Applications
Explicit internal transactions | Message Queuing Internal Transactions
Explicit external transactions | MS DTC External Transactions
Implicit single-message transactions | Single-message Transactions
Implicit MTS transactions | MTS Transactions
Implicit XA-compliant transactions | XA-Compliant Transactions


Single-Message Transactions

Message Queuing provides a single-message transaction that can be used to guarantee exactly-once delivery of a single message. This transaction implicitly uses the Message Queuing internal transaction to send a single message to a transactional queue.

Single-message transactions can be used only to send messages.

Note If a single-message transaction is used to retrieve a message, Message Queuing disregards the transaction request and retrieves the message using a non-transaction operation.

A single-message transaction is a special case of an Message Queuing internal transaction and for that reason cannot participate in a transaction with other resource managers. Each single-message transaction is a separate transaction over which the programmer has no explicit commit/abort control.

The single-message transaction provides the best performance of all transaction types. In addition to exactly-once delivery, a single-message transaction is faster than an external transaction, and the code used to send the message is very simple. The sending application only needs to make sure the destination queue is transactional and that the transaction parameter is set to MQ_SINGLE_MESSAGE.

For an example of | See
Sending a message as a single-message transaction | C++ Visual Basic


MS DTC External Transactions

Microsoft® Distributed Transaction Coordinator (MS DTC) external transactions are used when the transaction includes more actions than simply sending or retrieving Message Queuing messages (more than one resource manager is used). In this case, the application must ask MS DTC for a transaction object and explicitly reference that object each time it sends a message, retrieves a message, or executes an action of another resource manager.

When an application is performing an MS DTC transaction, Message Queuing is acting as part of a transaction processing system that includes a transaction manager and any number of resource managers.

The following illustration shows the basic model for the transaction processing system. This model demonstrates a typical system with MS DTC as the transaction manager and Message Queuing and SQL as resource managers. The application must work with the transaction manager and with each relevant resource manager.

For an example of | See
Sending a message using an MS DTC external transaction | C++


Message Queuing Internal Transactions

Message Queuing internal transactions provide better performance for transactions that only send or receive Message Queuing messages. Unlike MS DTC external transactions, Message Queuing internal transactions cannot be passed to another resource manager. They are less expensive than MS DTC external transactions because they avoid the cost of coordinating between several resource managers.

The SDK components used to create an Message Queuing internal transaction, include MQBeginTransaction (when using functions) and MSMQTransactionDispenser (when using COM components)

Note When sending a single message, Message Queuing provides a single-message transaction that implicitly uses the Message Queuing internal transaction. This mode of sending a message provides the best performance of all transaction types.

For an example of | See
Sending a message using an internal transaction | C++ Visual Basic


MTS Transactions

When your application is running in the Microsoft® Transaction Server (MTS) environment, Message Queuing send and receive messages within an MTS transaction by using the current MTS transaction object if it is available.

Message Queuing, Microsoft Transaction Server (MTS), and Microsoft Distributed Transaction Coordinator (MS DTC) work together for this type of transaction.

Note For Microsoft Transaction Server topics in the Microsoft® Platform SDK, see Microsoft Transaction Server 2.0 Service Pack 1.

For Microsoft® Distributed Transaction Coordinator topics in the Platform SDK, see Microsoft Distributed Transaction Coordinator .

As shown in the following illustration, Message Queuing links directly to the MTS run-time environment, and, within the run-time environment, MTS uses the services of (MS DTC) for transaction coordination.

When this type of transaction is used, the transaction object is provided by MTS. It is this transaction object that is used to commit to or abort the transaction.

When sending messages within an MTS transaction, the sending application must make sure the current MTS context is transactional. To verify that the MTS context is participating in the transaction, use the IsInTransaction method provided by MTS or COM+ (Component Services).

Note When using Microsoft® Windows NT® 4.0 or earlier, use the ObjectContext::IsInTransaction method provided by MTS.

When using Microsoft Windows® 2000 or later, use the ObjectContext::IsInTransaction method provided by COM+ (Component Services).

If the MTS context is not transactional, the send operation will fail because a non-transactional message is being sent to a transactional queue. However, in this situation the message can still be sent to a transactional queue by using an independent single-message transaction.

When retrieving messages, the receiving application can also use the IsInTransaction method to verify that the MTS context is transactional, and then use the MQ_MTS_TRANSACTION or MQ_NO_TRANSACTION constants, depending on the results of the IsInTransaction call.

For an example of | See
Sending a message using an MTS transaction | Visual Basic


XA-Compliant Transactions

Message Queuing can work in transaction systems that have an XA-compliant transaction manager. Because of this, MS DTC is used as a transaction process monitor and Message Queuing is a resource manager.

In the preceding transaction system model, MS DTC acts as a resource manager and a transaction manager. It acts as an XA-compliant resource manager with the transaction manager above it and as an MS DTC-compliant transaction manager to the Message Queuing resource manager below it.


Programming Considerations with Transactions

To perform a transaction, your application must work with Microsoft® Distributed Transaction Coordinator (MS DTC), and all resource managers needed to complete the transaction. These include all the resource managers associated with the transaction, including Message Queuing and MS DTC as the transaction manager.

From a system perspective, the process of performing a transaction starts with the transaction application asking MS DTC or Message Queuing for a new transaction object. Once a transaction object is available, the application can then make any number of transactional calls to all the resource managers needed by the application. However, transaction objects cannot be reused.

The application must check the return values of all the functions called. If all calls succeed, the application can vote to commit to the transaction. This does not mean the transaction is committed; it only means that the application is ready to commit.

MS DTC now starts a two-phase commit procedure, asking each participating resource manager to prepare and to inform MS DTC if it is ready to commit. If all the resource managers commit, MS DTC commits to the transaction. If any one resource manager does not commit, MS DTC aborts the transaction.

All this activity by MS DTC is invisible to the transaction application. The application only sees the return value of the Commit function it calls. When a successful Commit is returned to the application, the transaction is completed.

Note When a transaction is completed, it does not mean the work is completed. When the transaction manager commits to the transaction, it only means that each resource manager guarantees that it will do its part of the transaction at some later time.

Dead-letter queues can be used for both transactional and non-transactional messages (Message Queuing provides a separate dead letter queue for transactional and non-transactional message). If there is a transactional type mismatch between messages and their destination queues, the messages are returned to their appropriate dead-letter queue under the following conditions.

  • If the destination queue can be accessed at send time, the send operation is rejected by the sending queue manager, due to queue type and message type mismatch, and the messages are not sent to the dead-letter queue.
  • If the queue cannot be accessed at send time, such as when you are sending messages directly to a remote location, the send operation is rejected by the receiving queue manager and the messages is sent back to the dead-letter queue.
For information on | See
A summary of functions, methods, and message properties that are used in transactions. | Transaction Functions, Methods, and Properties
Sending messages within a transaction | Sending Messages to a Transactional Queue
Retrieving messages within a transaction | Retrieving Messages from a Transactional Queue
How messages are placed in the queue | Ordering of Messages in a Transactional Queue
Checking transaction boundaries on a queue basis | Checking for Transaction Boundaries when Receiving Messages
Aborting transactions | Aborting the Transaction


Transaction Functions, Methods, and Properties

Here is a summary of the functions and methods that are typically called by transaction applications, followed by a list of those message properties set by Message Queueing when transactions are used to send messages.

The following summary includes the functions and methods are typically used when sending or read messages within transactions.

  • Function and method used to create transaction queues.

    MQCreateQueue
    MSMQQueueInfo.Create

  • Function and method use to send messages in transactions.

    MQSendMessage
    MSMQMessage.Send

  • Functions and methods used to read messages in transactions.

    MQReceiveMessage
    MQReceiveMessageByLookupId (introduced in MSMQ 3.0)
    MSMQQueue.Receive
    MSMQQueue.ReceiveCurrent
    MSMQQueue.Peek
    MSMQQueue.PeekCurrent
    MSMQQueue.PeekNext
    MSMQQueue.PeekFirstByLookupId (introduced in MSMQ 3.0)
    MSMQQueue.PeekPreviousByLookupId (introduced in MSMQ 3.0)
    MSMQQueue.PeekByLookupId (introduced in MSMQ 3.0)
    MSMQQueue.PeekNextByLookupId (introduced in MSMQ 3.0)
    MSMQQueue.PeekLastByLookupId (introduced in MSMQ 3.0)
    MSMQQueue.ReceiveFirstByLookupId (introduced in MSMQ 3.0)
    MSMQQueue.ReceivePreviousByLookupId (introduced in MSMQ 3.0)
    MSMQQueue.ReceiveByLookupId (introduced in MSMQ 3.0)
    MSMQQueue.ReceiveNextByLookupId (introduced in MSMQ 3.0)
    MSMQQueue.ReceiveLastByLookupId (introduced in MSMQ 3.0)

The following message properties are set by Message Queuing when messages are sent within a transaction.

  • PROPID_M_PRIORITY and MSMQMessage.Priority

    When sending messages, Message Queuing sets the priority level of the message to "0" regardless of what the sending application may specify.

  • PROPID_M_TIME_TO_BE_RECEIVED and MSMQMessage.MaxTimeToReceive

    When sending multiple messages, Message Queuing sets the time-to-be-received property of all transactional messages to the value specified by the first transactional message sent within the transaction. Every transactional message sent in the transaction has the same time-to-be-received setting.

  • PROPID_M_TIME_TO_REACH_QUEUE and MSMQMessage.MaxTimeToReachQueue

    When sending multiple messages, Message Queuing sets the time-to-reach-queue property of all transactional messages to the value specified by the first transactional message sent within the transaction. Every transactional message sent in the transaction has the same time-to-reach-queue setting.

For information on | See
Sending messages within a transaction | Sending Messages to a Transactional Queue
Retrieving messages within a transaction | Retrieving Messages from a Transactional Queue
How messages are placed in the queue | Ordering of Messages in a Transactional Queue
Checking transaction boundaries on a queue basis | Checking for Transaction Boundaries when Receiving Messages
Aborting transactions | Aborting the Transaction


Sending Messages to a Transactional Queue

Messages can be sent to a local or remote transactional queue.

When sending messages, the application must get a successful return code from MQSendMessage and from its Commit call before it can be assured that the message will be sent. Calling MQSendMessage does not actually send the message within the transaction. The actual sending is done at some time after MS DTC commits to the transaction. When MS DTC returns a successful commit return value, the sending application is guaranteed that the message will be sent. If a transaction is aborted, all Message Queuing transaction operations are rolled back, and no messages are sent.

Note There is no limit to the number of messages sent in a single transaction. However, an application cannot send a message to a queue and then try to retrieve it during the same transaction.

A successful Commit, however, does not guarantee that all messages will reach their queues. For example, if you send three messages within a transaction they will not reach their queues at the same time. The first two messages may reach their queues, and the third message may not because its time-to-live timer expires while the message is on the wire.

Message Queuing treats each sent message separately, even if several messages were sent in the same transaction. A message is put into a queue whenever it reaches the destination queue manager. Message Queuing does not wait for all the messages sent in the same transaction to reach the queue manager and then put them all in the queue at the same time.

For information on | See
Sending messages | Sending Messages to a Transactional Queue
Retrieving message | Retrieving Messages from a Transactional Queue
How messages are placed in the queue | Ordering of Messages in a Transactional Queue
Checking for messages lost from the receiving queue | Checking for Transaction Boundaries when Receiving Messages
Aborting | Aborting the Transaction


Retrieving Messages from a Transactional Queue

Messages can be transactionally retrieved only from a local transactional queue. Messages cannot be retrieved from a remote queue when the call is part of the transaction.

Calling MQReceiveMessage, MSMQQueue.Receive, or MSMQQueue.ReceiveCurrent does not actually remove the message within the transaction. The actual removal is done at some time after MS DTC commits to the transaction. When MS DTC returns a successful commit return value, the retrieving application is guaranteed that the messages are removed from the queue. If the transaction is aborted, all retrieved messages are returned to their original place in the queue.

Note There is no limit to the number of messages retrieved from the queue in a single transaction. However, an application cannot send a message to a queue and then try to retrieve it during the same transaction.

Message in a transactional queue do not have to be retrieved within a transaction. The receiving application can retrieve messages from a transactional queue using non-transactional receive operations.

For information on | See
Sending messages | Sending Messages to a Transactional Queue
How messages are placed in the queue | Ordering of Messages in a Transactional Queue
Checking for messages lost from the receiving queue | Checking for Transaction Boundaries when Receiving Messages
Aborting | Aborting the Transaction


Ordering of Messages in a Transactional Queue

Message Queuing guarantees that all messages sent to a specific transactional queue will be delivered once, and that they will arrive in the order in which they were sent by the transaction. This means that if a single transaction A sends messages A1 and A2 to a queue, the messages will arrive exactly once, and A1 will always arrive before A2.

However, the exact ordering of messages is not guaranteed if two transactions are sending messages to the same queue. If transaction A sends messages A1 and A2 and a second transaction B sends messages B1 and B2, Message Queuing only guarantees that A1 will arrive before A2 and that B1 will arrive before B2. To guarantee that A1 and A2 will arrive before B1 and B2, the application must commit to B only after getting a successful return code from A.

When transactional messages are sent from the same machine, all of the messages associated with a given transaction are grouped together. Within each group, the messages are in the order in which they were sent; however, the group of messages is not actually sent to the destination queue until the sending application commits to the transaction. As a result, the order of the transactional message groups in the destination queue depends on when the sending application committed to the transactions.

When transactional messages are sent from different machines, the messages sent within a specific transaction are still delivered in the order in which they were sent. However there is no single group of transactional messages (as shown above) for each transaction. In this case, messages from transactions A and B could be interleaved in the queue. The diagram below shows one possible ordering of messages from transactions A and B.

For information on | See
Sending messages | Sending Messages to a Transactional Queue
Retrieving message | Retrieving Messages from a Transactional Queue
Checking for messages lost from the receiving queue | Checking for Transaction Boundaries when Receiving Messages
Aborting | Aborting the Transaction


Checking for Transaction Boundaries when Receiving Messages

Message Queuing provides three message properties that can be used by the receiving application to check the transaction boundaries of the messages in a queue. This includes a property that identifies which transaction sent the message, and two properties that indicate if the message was the first or last message sent in the transaction. Together, these three properties can be used to check the transaction boundaries of a transaction issued by a single computer to a single transaction queue.

The receiving application can use these properties to detect if any messages have been lost while they are in the receiving queue. (Note that Message Queuing guarantees that all messages sent to a specific transactional queue will be delivered once and that they will arrive in the order in which they were sent by the transaction. However, Message Queuing cannot guarantee that messages will not be lost after the sending application commits to the transaction.) Messages can be lost because of wrong encryption, failed authentication, insufficient permissions, and timeout occurrences.

For example, the following illustration shows a destination queue with messages from two transactions: transaction A and transaction B (note that the sequence of the messages indicates that the sending application committed to transaction A then committed to transaction B ).

If the receiving application finds the first message from transaction B before it finds the last message from transaction A, it knows that at least one message, the last message from transaction A, has been lost. Note that you can only check to see if the first or last message from the transaction was lost.

For information on | See
Sending messages | Sending Messages to a Transactional Queue
Retrieving message | Retrieving Messages from a Transactional Queue
How messages are placed in the queue | Ordering of Messages in a Transactional Queue

For an example of | See
Checking transaction boundaries | C/C++


Aborting the Transaction

If some operations in a transaction fail, it is the application's responsibility to decide whether to terminate the entire transaction (by calling the transaction object's abort member function) or commit to the transaction anyway (if the failures are such that the transaction is still viable). If the application does commit to a transaction where some operations have failed, the failed operations will not be part of the transaction.

Transaction objects cannot be reused after you commit to or abort the transaction. If you release the transaction object without calling Commit or Abort, the transaction is aborted for you.

For information on | See
Sending messages | Sending Messages to a Transactional Queue
Retrieving message | Retrieving Messages from a Transactional Queue
How messages are placed in the queue | Ordering of Messages in a Transactional Queue
Checking for messages lost from the receiving queue | Checking for Transaction Boundaries when Receiving Messages


MTS Programming Design Considerations

The following is a summary of the design issues that you must consider when sending or receiving message with an MTS transaction.

Queues used to receive transaction messages must be transactional. The property used to make a queue transactional can be set only when the queue is created.

When calling | Set
MQCreateQueue | The PROPID_Q_TRANSACTION property to MQ_TRANSACTIONAL.
MSMQQueueInfo.Create | The IsTransactional parameter to TRUE.

Message Queuing can detect and become part of the current MTS transaction. When using Message Queuing functions you must explicitly specify the MTS transaction. When using the Message Queuing COM components, Message Queuing joins the current MTS transaction by default.

When calling | Set
MQSendMessage or MQReceiveMessage | The pTransaction parameter to MQ_MTS_TRANSACTION.

You can call the IsInTransaction method to see if the current MTS context is transactional. This is needed to make sure only transactional messages are sent to transactional queues.

If using | Use
Microsoft Windows NT 4.0 or earlier | The ObjectContext::IsInTransaction method provided by MTS.
Microsoft Windows 2000 or later | The ObjectContext::IsInTransaction method provided by COM+ (Component Services).

When sending message, you can make sure that only transactional messages are sent to transactional queues by changing the pTransaction parameter based on the state of the current MTS context.

If the current MTS context is | Set pTransaction to
Transactional | MTS_TRANSACTION
Non-Transactional | MQ_SINGLE_MESSAGE

It is possible to perform other types of transactions while running under MTS. To do this, set the pTransaction parameter of the sending or receiving call to a value other than MQ_MTS_TRANSACTION, such as MQ_SINGLE_MESSAGE and MQ_XA_TRANSACTION.

For information on | See
Sending Transactional Messages | Sending Messages to a Transactional Queue
Retrieving Transactional Messages | Retrieving Messages from a Transactional Queue
How messages are placed in the queue | Ordering of Messages in a Transactional Queue


Application Models

Message Queuing applications can run in many different network scenarios. The following topics highlight the issues you should keep in mind when designing an application that will operate in a Windows® 2000 workgroup environment, operate while offline, send and receive messages between enterprises, as well as send and receive message Windows 2000 and foreign sites.

For information on | See
Applications operating in a workgroup environment | Workgroup Support
Applications operating offline | Message Queuing Offline Support
Applications that must send and receive messages between enterprises | Cross-enterprise Support


Workgroup Support

Message Queuing provides support for client applications that are operating in a Windows® 2000 workgroup environment, where there is no the directory service.

This support allows creating private queues on the local computer, setting and retrieving the properties and the security descriptor of local private queues, as well as using direct format names to send message to or read messages in local and remote private queues.

The following illustrations shows the possible connections between the client computer operating in the workgroup environment and other Message Queuing computers operating in a Windows 2000 domain.

From an application architecture perspective, your workgroup application must take into account the following limitations.

  • Only private queues are supported. Your application can create local private queues, send to and read messages from local private queues, and send to and (when using MSMQ 2.0) read messages from remote private queues.
  • Queues can only be referenced using direct format names. For example, when opening a queue you must specify the queue using a direct format name.
  • You cannot make any function or method call that requires access to the directory service. the directory service is not available to workgroup applications.
For information on | See
All functions and methods that are restricted when operating in a workgroup environment | Workgroup Quick Reference
Sending encrypted messages in a workgroup environment | Sending Private (Encrypted) Messages
Moving from a workgroup to a Windows 2000 domain | Joining a Domain


Workgroup Quick Reference

The following table shows the functions, methods, and properties that are affected when operating in a Windows 2000 workgroup environment.

Functions, Methods, and Properties | How they work
MQCreateQueue MSMQQueueInfo.Create | Can only create private queues. Returns a direct format name.
MQGetMachineProperties MSMQApplication.MachineIdofMachineName | Returns error. Requires access to the directory service.
MQGetQueueProperties | Must use direct format name when specifying queue. This function works only with local queues.
MQGetQueueSecurity | Must use direct format name when specifying queue. This function works only with local queues.
MQHandleToFormatName | Returns a direct format name.
MQLocateBegin MSMQQueueInfos.Reset | Returns error. Requires access to the directory service.
MQLocateNext MSMQQueueInfos.Next | Returns error. Requires access to the directory service.
MQLocateEnd | Returns error. Requires access to the directory service.
MQOpenQueue MSMQQueueInfo.Open | Must open queues using direct format name.
MQPathNameToFormatName | Returns a direct format name.
MQRegisterCertificate MSMQApplication.RegisterCertificate | Returns error. Requires access to the directory service.
MQSetQueueProperties | Must use direct format name when specifying queue. This function works only with local queues.
MQSetQueueSecurity | Must use direct format name when specifying queue. This function works only with local queues.
PROPID_M_PRIV_LEVEL MSMQMessage.PrivLevel | Cannot be set. Encryption must be done by the sending application.
PROPID_M_SENDERID MSMQMessage.SenderId | Cannot be set. Requires access to the directory service.


Sending Private (Encrypted) Messages

Private (encrypted) messages can be sent when operating in a workgroup environment, however, you cannot set the privacy level of a message and have the source queue manager encrypt the message body for you.

Note MSMQ 1.0 and 2.0 Differences: MSMQ 1.0 does not provide the COM components needed to encrypt messages manually. When using the COM components provided by MSMQ 1.0, you must always allow Message Queuing to encrypt the message body for you. On the other hand, MSMQ 2.0 provides full encryption support. You can tell Message Queuing to encrypt the message body, or your application can encrypt the message body.

To send an encrypted message, the client application must encrypt the body of the message itself. To do this the sending application must have an RC2 or RC4 symmetric key to encrypt the message body, as well as the public key of the receiving computer to encrypt the symmetric key.

Note Message Queuing supports RC2 and RC4 encryption algorithms. The encryption algorithm is specified when the symmetric key is created, used to encrypt the body of the message, then sent on to the receiving application in the encryption algorithm property (PROPID_M_ENCRYPTION_ALG or MSMQMessage.EncryptAlgorithm) of the message

The following illustration shows the process needed to encrypt a message body.


Joining a Domain

Your client application gains access to the directory service when the client computer is added to a Windows 2000 domain. This means that you can use public queues, as well as call any function or method that access the directory service.

To join a domain

  1. Open Control Panel
  2. Select System
  3. Select Network Identification tab
  4. Click Change to start Network Access Wizard.
  5. Run wizard and select My computer uses a Windows 2000 network.
  6. Enter name of domain.


Message Queuing Offline Support

Message Queuing provides offline support for applications that are not always connected to the network. When operating offline, these applications have no access to the directory service.

This support allows an application to send messages to remote queues while it is operating offline and then later connect to the network. Once the application computer is connected to the network, the messages sent to remote queues are sent on to their destination.

Note Dependent client computers cannot be used for offline operations.

The following illustrations show the possible connections between the application computer when operating online and offline. Note that when the application is operating offline, it uses a local internal queue called an outgoing queue to store messages sent to remote queues. Message Queuing sends those messages once the computer is back online.

Note To view outgoing queues and read their messages, use the MSMQ Local Administration Tool. This tool is available with Message Queuing on Windows® 2000, it is not available with previous versions of Message Queuing.

From an application architecture perspective, your offline application must take into account the following limitations:

  • To open remote queues (with send access) while offline, your application must either obtain and cache the public or private format name of the remote queues while online, or have the information needed to construct a direct format name for these queues.
  • When operating offline, your application can send messages to remote queues, but they are stored locally until the application computer is back online.
  • Send messages in recoverable mode if the offline computer is going to be stopping the Message Queuing queue manager while offline. Messages sent in express mode are held in RAM and will be lost when the computer is turned off.
  • When operating offline, your application cannot read messages from remote queues.
  • When operating offline, do not make any function or method calls that require access to the directory service. the directory service is not available while offline.
  • When you send a message, its message timers (time-to-reach-queue and time-to-be-received) start ticking as soon as the send operation succeeds, even if the application computer is offline.
For information on | See
All functions and methods that are restricted when operating offline | Offline Quick Reference
Opening remote queues when operating offline | Opening Queues Offline
Sending messages while operating offline | Sending Messages Offline
Public, private, and direct format names | Format Names


Offline Quick Reference

The following table shows the functions, methods, and properties that are affected when operating offline in a Windows 2000 environment.

When operating offline, your application must avoid using any call that requires access to the directory service. Any call to the directory service will cause an error or time-out to occur.

Functions, Methods, and Properties | How they work
MQCreateQueue MSMQQueueInfo.Create | You can create only private queues while operating offline. You cannot create public queues because there is no access to the directory service.
MQDeleteQueue MSMQQueueInfo.Delete | You can delete only private queues while operating offline. You cannot delete public queues because there is no access to the directory service.
MQGetMachineProperties MSMQApplication.MachineIdofMachineName | Cannot be used offline. Getting the properties of a machine requires access to the directory service (including the properties of the local offline application computer).
MQGetQueueProperties | You can retrieve only properties of private queues while operating offline. You cannot retrieve the properties of public queues because there is no access to the directory service.
MQGetQueueSecurity | You can retrieve only security descriptors of private queues while operating offline. You cannot retrieve the security descriptors of public queues because there is no access to the directory service.
MQLocateBegin MSMQQueueInfos.Reset | You cannot locate public queues while operating offline. Queries can be made only while online.
MQLocateNext MSMQQueueInfos.Next | You cannot locate public queues while operating offline. Queries can be made only while online.
MQLocateEnd | You cannot locate public queues while operating offline. Queries can be made only while online.
MQOpenQueue MSMQQueueInfo.Open | You must cache format names for remote queues while online. You can then use these cached format names to open the queue while you are operating offline.
MQPathNameToFormatName | Format names for public queues cannot be retrieved while operating offline. Requires access to the directory service.
MQRegisterCertificate MSMQApplication.RegisterCertificate | Cannot be used offline.
MQSetQueueProperties | You can set only properties of private queues while operating offline. You cannot set the properties of public queues because there is no access to the directory service.
MQSetQueueSecurity | You can set only security descriptors of private queues while operating offline. You cannot set the security descriptors of public queues because there is no access to the directory service.

For information on | See
Opening queues when operating offline | Opening Queues Offline
Sending messages while operating offline | Sending Messages Offline


Opening Queues Offline

The call to open a queue is the same regardless of the offline or online status of the application computer. In both cases, a call to MQOpenQueue or MSMQQueueInfo.Open is used to open local and remote queues.

Only local queues can be opened with receive access. An application cannot read messages from remote queues while offline.

By contrast, both local and remote queues can be opened with send access. However, to open remote queues while operating offline, the application must first obtain and cache the format names of the queues while online.

Note When an application operating offline opens a remote queue with send access, all messages it sends to the queue while offline are stored locally in an outgoing queue. Once the application computer is back online, the messages are passed on to their respective destination queues.

While online, the application can retrieve the format names of public queues from the directory service by calling the MQPathNameToFormatName function or the MSMQQuery.LookupQueue method.

The format names of private queues, however, must have been sent from the receiving application while online. The receiving application can use the response queue property (PROPID_M_RESP_QUEUE or MSMQMessage.ResponseQueueInfo) to send the format name of a private queue.

The application must then cache the format names of the remote queues so that it can use them to open the queues later while offline. These format names can be cached in a local private queue, the local registry, or any other application-specific database mechanism.

Queues can be opened using public, private, or direct format names. If the application needs to construct the format name of the queues while offline, the following syntax shows what information is needed to open queues using public, private, and direct format names.

"PUBLIC=QueueGUID"
"PRIVATE=MachineGUID\QueueNumber"
DIRECT=AddressSpecification\QueueName            (For public queues.)
DIRECT=AddressSpecification\PRIVATE$\QueueName   (For private queues.)

Note Specifying a TCP/IP address when you are also using DHCP may generate errors. In this case the target computer may have changed its network address since the last time the application stored the address.

When using a direct format name, the messages are sent directly to the target computer as soon as the application computer is brought back online.

For information on | See
All functions and methods that are restricted when operating offline | Offline Quick Reference
Public, private, and direct format names | Format Names
Sending messages to remote queues while offline | Sending Messages Offline


Sending Messages Offline

While the application computer is offline, the sending application can send messages to local or remote queues. Messages sent to local queues are delivered to the local queue. On the other hand, Messages sent to remote queues are stored locally and sent to their final destination when the application computer is reconnected to the network.

Messages must be sent in recoverable mode if the application computer is going to be stopping the Message Queuing queue manager while offline. Messages sent in express mode are held in RAM and will be lost when the computer is turned off. To send recoverable messages, set the delivery property (PROPID_M_DELIVERY or MSMQMessage.Delivery) of the message to MQMSG_DELIVERY_RECOVERABLE.

Note When a message is sent, its message timers (time-to-reach-queue and time-to-be-received) start ticking as soon as the send operation succeeds, even if the application computer is offline.

For information on | See
All functions and methods that are restricted when operating offline | Offline Quick Reference
Opening queues | Opening Queues Offline


Directory Service Access Error Timeout

You can set the time interval between when a request is made to access the directory service and when Message Queuing returns MSMQ_ERROR_NO_DS by using the RpcCancelTimeout registry setting on the application computer.

The formula for computing this time interval is shown below.

ErrorTimeout = (directory_service_servers)*2*(supported protocols)*(RpcCancelTimeout)

where directory_service_servers is the number of the directory service servers in the local site, supported_protocols is the number of protocols supported by both the application computer and the directory service servers, and RPCCancelTimeout is the number of minutes set in the registry of the local computer (default is 5 minutes).

For example, the network shown below has three directory service servers. it supports 1 protocol (TCP/IP), and the RpcCancelTimeout setting is 5. The ErrorTimeout of the system below would be:

ErrorTimeout = 3*2*1*5


Cross-enterprise Support

Message Queuing provides support for applications that must communicate across two Microsoft Windows 2000 enterprises. In this situation, your application must be able to send and retrieve messages without using the directory service.

The following illustrations shows the possible connections between a computer operating in the enterprise A and the other computers operating in environment B.

From an application architecture perspective, your cross enterprise application must take into account the following limitations:

  • Queues in the other enterprise can be referenced only by using direct format names. For example, when opening a queue you must specify the queue using a direct format name.
  • You cannot make any function or method call that requires access to the directory service on the other enterprise. You can access the directory service only on your own enterprise.
  • When requesting message authentication, you must provide an external certificate. Internal certificates cannot be used.
  • To send encrypted messages, your application must obtain the public key of the receiving computer and encrypt the message itself. (The receiving queue manager will still decrypt the message for you.)
  • When you send messages within a transaction, the IP address of the sending computer must remain constant. Message Queuing uses the IP address to return a confirmation notice when the message has been retrieved from the target queue.


MSMQ Connector Servers

The MSMQ connector server is not available with the Windows NT® 4.0 Option Pack.

An MSMQ connector server provides a mechanism for Message Queuing applications to send and receive message from computers using other messaging systems. To do this, MSMQ connector servers use internal connector queues to receive the messages from Message Queuing and a connector application to translate messages between Message Queuing and the other message system.

By using an MSMQ connector server, Message Queuing applications can perform the same operations on foreign queues that they would typically perform on the queues within their enterprise.

Note Foreign queues, foreign computers, foreign sites, and foreign Connected-Networks are all created and used the same way their Message Queuing counterparts are. For information on creating, see the Message Queuing Administrator's Guide.

The MSMQ connector server uses a pair of internal connector queues for each foreign site attached to the connector. One is used for transactional messages and the other for non-transactional messages. Connector queues are implicitly created by Message Queuing. They are not registered in the directory service, and they are transparent to the Message Queuing application sending messages to the foreign queue. For applications, sending a message to a foreign queue is identical to sending a message to an Message Queuing queue.

The following illustration shows a single Message Queuing server connected to two foreign sites. In this case, there are two pairs of connector queues, one pair for each foreign site.


Connector Applications

MSMQ connector servers are not available with the Windows NT® 4.0 Option Pack.

The connector application must be able to translate between Message Queuing and the message queue system used by the foreign computer. It must be able to read the message properties in one system, translate their values into the format of the other system, and send the message on (with its new properties) to the appropriate destination.

When an Message Queuing application sends a message to a foreign queue, the message is routed to the connector queue that represents the foreign site where the queue's computer resides. The connector application must read the messages in the connector queue, translate them, and forward the message on to the foreign queue.

When a foreign application sends a message to Message Queuing, it must be routed to the connector application, translated into an Message Queuing message, and forwarded on to the appropriate Message Queuing queue. When a message is sent to Message Queuing, its PROPID_M_CONNECTOR_TYPE property must be set so that Message Queuing knows which connector sent the message.


Connector Application Responsibilities

An MSMQ connector server should be transparent to the applications running on Message Queuing computers. The connector application running on the server must be able to:

  • Handle the time-to-be-received timer. The time-to-reach-queue timer stops when the message reaches the connector queues.
  • Handle the acknowledgment level of messages. The connector must return the appropriate acknowledgment messages to the appropriate administration queue according to the message properties.
  • When the connector application creates an acknowledgment message, it must set the PROPID_M_CLASS and PROPID_M_CONNECTOR_TYPE properties when it sends the acknowledgment back to the sending application.
  • Complete any pending transaction status for transacted messages. For information on transactions with foreign queues, see Using the MSMQ Connector in a Transaction.
  • Handle security issues appropriately. See Connector Application Security for information on handling encrypted messages and authenticating messages.


Moving Messages from Message Queuing to Another Message Queue System

To move messages to another message queue system, the connector application must read all the messages that arrive in the connector queues. All transactional messages sent to foreign queues are stored in the transactional connector queue. All non-transactional messages are stored in the non-transactional connector queue. Non-transactional and transactional messages must be read from the appropriate connector queue.

Note For foreign message properties not supported by Message Queuing, use PROPID_M_EXTENSION and PROPID_M_EXTENSION_LEN.

To open these queues, the connector application must use a specific format name.

The following example shows two MQOpenQueue calls: the first one opens the connector's non-transactional queue, and the second opens the transactional queue.

MQOpenQueue("CONNECTOR=ForeignCNGUID",     // Special format name.
    MQ_RECEIVE_ACCESS,                     // Receive access.
    MQ_DENY_RECEIVE_SHARE,                 // Read Exclusive.
    qh                                     // Returned queue handle.
    )

MQOpenQueue("CONNECTOR=ForeignCNGUID;XACTONLY",  // Format name.
    MQ_RECEIVE_ACCESS,                           // Receive access.
    MQ_DENY_RECEIVE_SHARE,                       // Read Exclusive.
    qh                                           // Returned handle.
    )

An application can find the GUID of a foreign CN or site by calling MQGetMachineProperties and retrieve PROPID_QM_CONNECTION.


Moving Messages from Another Message Queue System to Message Queuing

To move messages from another message queue system to Message Queuing, the connector application must use the standard Message Queuing functions. In addition, each message sent to Message Queuing (including acknowlegment messages created by the connector application) must have its PROPID_M_CONNECTOR_TYPE property set so that Message Queuing knows which connector sent the message.

Note For foreign message properties not supported by Message Queuing, use PROPID_M_EXTENSION and PROPID_M_EXTENSION_LEN.


Connector Application Security

MSMQ connector servers are not available with the Windows NT® 4.0 Option Pack.

Security operations can be performed by the connector application, or they can be passed on to the foreign computer where the destination queue is located.

Connector applications that pass security operations to the foreign queue are referred to as transparent applications. As a transparent application, the connector application translates the message properties so they can be understood by the foreign computer, and then passes the translated message properties on to their destination. In this case, the foreign computer must interpret the message properties and perform any required actions.

Connector applications that perform security operations themselves are referred to as non-transparent applications. As a non-transparent application, the connector application receives messages from either Message Queuing or the other message queue system, interprets the message's properties, and performs any required actions. Then the application sends the message on with the appropriate message properties. In this case, the foreign queue must be able to trust the connector application to perform the correct actions.

Note Tasks for non-transparent applications are also relevant to message systems that use transparent connector applications. Even though the transparent application does not perform tasks at the server, these security tasks still must be done when the message reaches the foreign queue.

Several properties are used when creating the signature of the sender. When a transparent connector application translates these properties (in particular the administration and response queue properties) to their new values, it must include both the translated and original values when it passes the message on to its destination. The foreign application needs the original values to authenticate the signature when the message arrives.

Providing the necessary information is much more difficult for messages being sent to an Message Queuing queue than messages sent to a foreign queue. In this case, the foreign application must retrieve an Message Queuing–representation of the signature properties before it creates the signature.


Passing Authenticated Messages

To pass authenticated messages between Message Queuing and another message queue system, the connector application (both transparent and non-transparent applications) must retrieve all the properties needed for authentication. This includes the property that contains the MSMQ 1.0 signature of the sender, the sender's public key, the cryptographic provider needed to verify the signature, the hash algorithm used to create the signature, and all the message properties used in the MSMQ 1.0 signature. Note that you cannot use MSMQ 2.0 signatures when passing authenticated messages between Message Queuing and other message queue systems.

The properties are used to authenticate messages.

Property | Description
PROPID_M_SIGNATURE | Contains signature.
PROPID_M_SENDER_CERT | Contains public key of sender.
PROPID_M_PROV_NAME | Name of cryptographic provider needed to verify signature.
PROPID_M_PROV_TYPE | Type of cryptographic provider needed to verify signature.
PROPID_M_HASH_ALG | Hash algorithm used to create signature.

The properties used in the MSMQ 1.0 signature include:

PROPID_M_CORRELATIONID
PROPID_M_APPSPECIFIC
PROPID_M_BODY
PROPID_M_LABEL
PROPID_M_RESP_QUEUE
PROPID_M_ADMIN_QUEUE

Transparent connector applications must perform different operations depending on the direction of the messages. If the message is going from the foreign application to Message Queuing, the connector application needs to translate new property values and pass the new values on to Message Queuing. If the messages are being sent from Message Queuing to the other message queue system, the connector application must translate new property values and pass both these and the original values on to the foreign application. The original values are needed to generate the hash value used to authenticate the signature.

Non-transparent applications perform the security operations (verify signature) so there is no need to pass on security properties. However, the applications do need to indicate that the message was verified when it passes on the message.

The code needed to perform security operations varies for each application. However, the pseudo-code provided in the following sample shows the basic elements needed to authenticate a message.

When messages are being sent from another message queue system to Message Queuing, non-transparent applications must have access to the private signing keys of all the users on the foreign side. The application must compute the message's hash value, encrypt the hash value by applying the user's private signing key, and pass the message on to Message Queuing.

Note For foreign message properties not supported by Message Queuing, use PROPID_M_EXTENSION and PROPID_M_EXTENSION_LEN.

Signature Verification Pseudo-code

The following pseudo-code describes the basic elements needed to authenticate a message:

  1. Retrieve cryptographic provider information needed to perform the cryptographic operation required for signature verification.
    CryptProvName = GetMessageProperty(Message, PROPID_M_PROV_NAME)
CryptProvType = GetMessageProperty(Message, PROPID_M_PROV_TYPE)
  2. Initialize the crpytographic provider.
    CryptProvider = AcquireCrpytoraphicConext(
                               CryptProvName,
                               CryptProvType)
  3. Get the hash algorithm identifier and initialize a hash object. This object is used to perform the hashing and signature-verification operations.
    HashAlogorithm = GetMessageProperty(Message, PROPID_M_HASH_ALG)
HashObject = GetHashObject(CryptProvider, HashAlogorithm)
  4. Get the six message properties that are required for calculating the hash value for the message.
    CorrelationId = GetMessageProperty(Message, PROPID_M_CORRELATIONID)
AppSpecific = GetMessageProperty(Message, PROPID_M_APPSPECIFIC)
MessageBody = GetMessageProperty(Message, PROPID_M_BODY)
MessageLabel = GetMessageProperty(Message,  PROPID_M_LABEL)
RespQueueFormat = GetMessageProperty(Message, PROPID_M_RESP_QUEUE)
AdminQueueFormat = GetMessageProperty(Message,  PROPID_M_ADMIN_QUEUE)
  5. Compute the hash value for the message by adding (in order) each message property to the hash value. The order in which the properties are added is important. Changing the calculation order of the message properties causes signature verification to fail.
    HashData(HashObject, CorrelationId)
HashData(HashObject, AppSpecific)
if NotEmpty(MessageBody)
        HashData(HashObject, MessageBody)
if NotEmpty(MessageLabel)
        HashData(HashObject, MessageLabel)
if NotEmpty(RespQueueFormat)
        HashData(HashObject, RespQueueFormat)
if NotEmpty(AdminQueueFormat)
        HashData(HashObject, AdminQueueFormat)
  6. Get the message signature. Note this property can only contain MSMQ 1.0 signatures.
    MessageSignature = GetMessageProperty(Message, PROPID_M_SIGNATURE)
  7. Get the sender's certificate.
    SenderCert = GetMessageProperty(Message, PROPID_M_SENDER_CERT)
  8. Get the sender's public key out from the sender's certificate.
    SenderPublicKey = GetPublicKeyFromCertificate(CryptProvider,
                  SenderCert)
  9. Verify the signature of the message according to the message hash value and the sender's public key.
    VerifySignature(HashObject, SenderPublicKey, MessageSignature)

The result of the verify signature function indicates whether the signature is valid.


Passing Private Messages

Passing private, encrypted messages between Message Queuing and another message queue system is very similar to passing private messages between Message Queuing applications. The only difference is that a symmetric key must be exposed when sending a private message.

The message properties used to send private messages include:

Property | Description
PROPID_M_BODY | Contains encrypted message body.
PROPID_M_DEST_SYMM_KEY | Used to decrypt messages.
PROPID_M_DEST_SYMM_KEY_LEN | Specifies the length of the symmetric key.
PROPID_M_ENCRYPTION_ALG | Algorithm used to encrypt the message.
PROPID_QM_ENCRYPTION_PK PROPID_QM_ENCRYPTION_PK_BASE PROPID_QM_ENCRYPTION_PK_ENHANCED | One of these properties must contain the public key of the destination queue (used when sending messages to an Message Queuing queue.) For MSMQ 1.0 applications, use PROPID_QM_ENCRYPTION_PK. For MSMQ 2.0 applications, the base and enhanced public key properties should contain the 40-bit or 128-bit encryption key respectively. (MSMQ 2.0) Identifies the 40-bit public encryption key of the computer. (MSMQ 2.0) Identifies the 128-bit public encryption key of the computer.

The implementation of the connector application determines how private messages are passed to their destinations. Transparent connector applications pass the symmetric key, encryption algorithm, and the encrypted message body on to the queue manager of the destination queue. This is the same regardless of the direction the message is going. When using a transparent connector application, the public keys of all destination queue managers must be registered in the directory service.

Non-transparent connector applications decrypt the message at the server and can pass on a clear-text message body or encrypt the message again (using the receiving systems encryption operations) and pass on a newly encrypted message body. When using a non-transparent connector application, all destination queues must use the public key of the connector application.

In addition to the type of connector application, there are two design considerations that should be taken into account:

  • When multiple servers are used (two or more servers are connected to the same foreign connector networks), only transparent connector applications can be used.
  • When sending messages from one message queue system to another, the source application must get the public key of the destination queue before it can encrypt the message body. The source application must tell the connector application to call MQGetMachineProperties and pass back the public key found in one of the three encryption key properties mentioned above.

    This means that there must be a level of trust between the connector application and the foreign queue manager. There is no way for the foreign queue manager to independently verify that the key it receives is the public key it requested.

Note For foreign message properties not supported by Message Queuing, use PROPID_M_EXTENSION and PROPID_M_EXTENSION_LEN.

Caching the Symmetric Key

Non-transparent connector applications can cache the symmetric key to save time when decrypting private messages. If several messages arrive from the same source, there is no need to decrypt a symmetric key for each message.

To do this, the application must cache the identifier of the source computer and the decrypted and encrypted values of the symmetric key. The connector application can call PROPID_M_SRC_MACHINE_ID to retrieve the identifier of an Message Queuing source machine.

When the next message arrives, the connector application can first check if a message has already arrived from that source machine. If the machine identifier is not found, the connector application will add it to the cached values.

If a previous message has arrived, the application can next test to see if the new encrypted key matches the cached encrypted key. If they match, the cached decrypted value can be used immediately. If they do not match, it will decrypt the new key (storing both the encrypted and decrypted values in the cache), using the new value to decrypt the message body.


Using the MSMQ Connector in a Transaction

The MSMQ connector server is not available with the Windows NT® 4.0 Option Pack.

When an Message Queuing application sends messages in a transaction, Message Queuing routes the message to the transactional connector queue.

To know where to return the read receipt or negative acknowledgment, the connector application must retrieve the format name of the queue by looking at the message's PROPID_M_XACT_STATUS_QUEUE property. The read receipt must be returned even if the sending application did not request acknowledgments (PROPID_M_ACKNOWLEDGE is set to MQMSG_ACKNOWLEDGMENT_NONE).


Message Queuing COM Support

Message Queuing provides a set of COM objects for developing Message Queuing applications using COM development tools. These tools include, but are not limited to, Microsoft® Visual Basic® (version 4.0 or later), Microsoft Visual C++ ®, or C++.

The Message Queuing COM objects provide the most common Message Queuing API functionality needed for developing Message Queuing applications. This includes queue lookup, queue management, message management, and queue administration.

Message Queuing COM applications can be created using any development tool that supports COM objects, including Microsoft® Visual Basic® version 4.0 (32 bit), Microsoft® Visual Basic® version 5.0, Microsoft® Office (95 and 97), Delphi, Microsoft® Internet Explorer, Microsoft® Active Server Pages, as well as others.

For information on | See
COM objects used to perform specific tasks | Message Queuing COM Object Model


Message Queuing COM Object Model

The object model described in the following illustrations provides functionality for sending messages to queues, reading messages in queues, and several more queue management features. The guiding principle in designing the Message Queuing COM objects is object model simplicity.

The following illustration shows two sets of objects that can be used to send messages to queues. The first set uses the MSMQDestination object (introduced in MSMQ 3.0) and can be used to send messages to one or more destination queues. Messages can be sent to multiple destination queues using distribution lists, multicast addresses, or multiple-element format names.

The second set uses an MSMQQueueInfo object and should be used only when writing sending applications using the MSDMQ 1.0 or MSMQ 2.0 object libraries. The MSMQQueueInfo object can only reference a single destination queue.

The following illustration shows the objects used to read messages from a destination queue. (Note that the MSMQDestination object used to send messages cannot be used when reading messages from a queue.)

The following objects can be used to locate an existing public queue for sending messages or reading messages. These object can be used to obtain one or more MSMQQueueInfo object that can then be used to open the queue for sending or reading message.

Message Queuing provides the following objects for obtaining a transaction object for internal and external transactions. These objects must be defined with the other objects needed for sending and reading messages.

Message Queuing provides a single COM application object that can be used to monitor Message Queuing on a computer, retrieve the machine name and machine identifier of a computer, and register internal and external certificates used to authenticate messages.


Message Queuing Object Libraries

Message Queuing provides the following object libraries:

  • Microsoft Message Queue 3.0 Object Library: Provided by Whistler.
  • Microsoft Message Queue 2.0 Object Library: Provided by Windows 2000.
  • Microsoft Message Queue 1.0 Object Library: Provided by Windows NT.

Each object library provides a new set of objects that provide new and past Message Queueing functionality (with the exception of the Message Queuing Mail objects that are not available with MSMQ 3.0)). The programmatic names used in past functionality remains the same, allowing you to use the same names you are familiar with when writing sending and receiving applications. However, each new object library provides a new interface (with a new GUID) for each object that becomes the default interface for the object.

As a result of the new interfaces, sending and receiving applications that use early binding and that are recompiled on newer operating systems will work only on computers running the newer operating systems. This is because the new default interface identifiers that are compiled into the program are not available on computers running the older operating systems.

Dim qinfo As MSMQQueueInfo

In contrast, sending and receiving applications that use late binding (as in the code below) will work on all operating systems because interface identifiers are not used.

Dim qinfo As Object
set qinfo=CreateObject("MSMQ.MSMQQueueInfo")

The following table lists the object libraries

Object Library | Files Provided
Microsoft Message Queue 3.0 Object Library (Whistler) | mqoa.dll mqoa20.tlb mqoa10.tlb
Microsoft Message Queue 2.0 Object Library (Windows 2000) | mqoa.dll mqoa10.tlb
Microsoft Message Queue 1.0 Object Library (Windows NT) | mqoa.dll

Each object library provides an mqoa.dll file that contains new definitions and implementations of the Message Queuing objects, plus tlb files that contain older definitions of the Message Queuing objects. This means that existing applications can be compiled using the new object definitions provided in mqoa.dll or the older definitions provided in the tlb files.

The tradeoff between using newer or older definitions is as follows. If you use the newer definitions (provided by the new mqoa.dll), your applications can take advantage of the new functionality provided by that version of Message Queuing, but they can run only on the operating system noted in the table above. However, if you use the old definitions provided by the tlb file, your applications can run on multiple platforms, but you cannot take advantage of the new functionality.


Message Queuing Mail Services

[The Message Queuing Mail Service is available only on Windows NT4 and Windows 2000.]

Message Queuing mail services provide a way to send Message Queuing mail messages to applications that use e-mail based messaging. These applications include Microsoft® Exchange as well as individual MAPI client applications. Application developers can use these mail services to combine the ease of development and use of e-mail-based forms with the computing power and interoperability of Message Queuing.

Message Queuing provides two mail services: the MSMQ MAPI Transport Provider and the MSMQ Exchange Connector. The differences between the two services are listed below.

MSMQ Exchange Connector | MSMQ MAPI Transport Provider
Runs on a single computer serving all Microsoft Exchange users. | Runs on each MAPI client application computer serving only one MAPI client.
Requires Message Queuing installed on one computer. | Requires Message Queuing installed on each MAPI client computer.
Uses a single input queue for all Microsoft Exchange users. | Uses a different user input queue for each MAPI user.
Stores the addresses of the Message Queuing applications in the Microsoft Exchange address book, which is common to all Microsoft Exchange users. | Stores addresses in personal address books, which cannot be shared among MAPI clients.
Requires a connection to a Microsoft Exchange server. | Does not require Microsoft Exchange.
When sending mail messages, the Message Queuing application must specify the address of the Microsoft Exchange user. | When sending mail messages, only the label of the MAPI client's queue is needed.

The Message Queuing mail services currently support sending/receiving of the following:

  • Text messages without attachments of any kind.
  • EFD (Exchange Form Designer) forms without attachments of any kind.
  • MAPI TNEF messages.
  • Delivery and non-delivery reports.

The Message Queuing mail services support only MAPI TNEF messages when sending/receiving e-mail with:

  • Any type of attachment
  • Microsoft Outlook™ custom forms


Message Queuing Mail API

[The Message Queuing Mail Service is available only on Windows NT4 and Windows 2000.]

The Message Queuing mail API provides the functions and COM components needed to compose and parse mail messages.

The Message Queuing mail API functions include:

  • MQMailComposeBody
  • MQMailFreeMemory
  • MQMailParseBody

The Message Queuing mail COM objects include:

  • MSMQMailEMail
  • MSMQMailFormData
  • MSMQMailFormField
  • MSMQMailFormFieldList
  • MSMQMailRecipient
  • MSMQMailRecipientList
  • MSMQMailTextMessageData
  • MSMQMailTnefData
  • MSMQMailDeliveryReportData
  • MSMQMailNonDeliveryReportData


MSMQ Exchange Connector

[The Message Queuing Mail Service is available only on Windows NT4 and Windows 2000.]

The MSMQ Exchange Connector provides a way for Microsoft® Exchange users to communicate with Message Queuing applications. Using the Exchange Connector, e-mail can be sent to Message Queuing applications and Message Queuing mail messages can be sent to Microsoft Exchange users.

The Exchange Connector is the recommended solution for connecting Microsoft Exchange users to Message Queuing applications.

Additional Exchange Connector information can be found in the following:

  • To install and use the Exchange Connector, see Microsoft® Windows NT® Help.
  • To see how mail is sent between Microsoft Exchange users and Message Queuing applications, see Sending Exchange E-mail to an Message Queuing Application or Sending Message Queuing Mail Messages to an Exchange User.
  • To use the functions and COM components provided by the Message Queuing mail API, see the reference page for each item. You can locate these functions and COM components by their names or under Message Queuing Mail Functions and Message Queuing Mail COM Components.
  • For an example of an Message Queuing mail sample application, see MSMQ Exchange Connector: Book Server Application.


Sending Exchange E-mail to an Message Queuing Application

[The Message Queuing Mail Service is available only on Windows NT4 and Windows 2000.]

E-mail sent by Microsoft Exchange users is routed through their Exchange server to the MSMQ Exchange Connector and then sent on to the input queue of the Message Queuing application (see illustration below). The Message Queuing application can then read, process, and return a mail message to the Exchange user who sent the mail or forward the mail message (or another mail message) on to the next processing destination.

To send e-mail to an Message Queuing application, the Exchange Connector performs the following functions:

  • Converts the e-mail to a mail message whose body is in Message Queuing mail format.
  • Sends the converted mail message to the application input queue of the Message Queuing application.

The Message Queuing application creates the application input queue that will receive the mail message. The application must specify a queue type when it creates a queue for the Exchange Connector to find the queue.

Additional information can be found in the following:

  • To see how Message Queuing messages are sent to Exchange users, see Sending Message Queuing Mail Messages to an Exchange User.
  • To set up the Exchange Connector, see Microsoft® Windows NT® Help.
  • To use the functions and COM components provided by the Message Queuing mail API, see the individual reference pages for each item. You can locate these functions and COM components by name or by looking in Message Queuing Mail Functions and Message Queuing Mail COM Components.


Sending Message Queuing Mail Messages to an Exchange User

[The Message Queuing Mail Service is available only on Windows NT4 and Windows 2000.]

Message Queuing mail messages sent to Exchange users are sent to the server input queue of the Exchange Connector. Message Queuing mail messages are then routed through the Exchange Connector where they are translated and sent on to the Exchange Server where they are distributed to the appropriate Exchange user (see illustration below).

The MSMQ Exchange Connector creates a server input queue when it starts for the first time. This queue is created only once by the Exchange Connector. The Exchange Server input queue is used only when Message Queuing mail messages are sent to Exchange users. It is not used when an Exchange user sends e-mail to an Message Queuing application.

When an Message Queuing mail message is sent to an Exchange user, the sending application sends the message to this server input queue, and the Exchange Connector then performs the following functions:

  • Reads the Message Queuing mail message from the server input queue.
  • Translates the mail message into e-mail.
  • Sends the e-mail on to the Exchange Server.

The Message Queuing application must know the address of the Exchange user it is sending messages to.

Additional information can be found in the following:

  • To see how mail is sent to Message Queuing applications, see Sending E-mail to an Message Queuing Application.
  • To set up the Exchange Connector, see the Microsoft® Windows NT® Help.
  • To use the functions and COM components provided by the Message Queuing mail API, see the reference page for the item. You can locate these functions and COM components by name or by looking in Message Queuing Mail Functions and Message Queuing Mail COM Components.


MSMQ Exchange Connector: Book Server Application

[The Message Queuing Mail Service is available only on Windows NT4 and Windows 2000.]

The Book Server sample application uses the MSMQ Exchange Connector to pass messages between a Microsoft® Exchange user and an Message Queuing application. In this application, the Exchange user requests a query, the Message Queuing application performs the query, and the results of the query are sent back to the Exchange user.

The following is a step-by-step description of the process that Book Server uses to perform its query.

  1. Using Microsoft Exchange, the Microsoft Exchange user enters the search criteria and submits the query mail, which is preaddressed to a recipient called Book Server. The mail's Message Queuing-typed address is set to the label of the application input queue of the sample Message Queuing application booksrvr.
  2. The Exchange Connector receives the form from Exchange (because the recipient is an Message Queuing-typed recipient), translates it into an Message Queuing mail message, and sends it to the application input queue of the sample Message Queuing application.
  3. The sample Message Queuing application (booksrvr) retrieves the message from the application input queue, calls MQMailParseBody to parse the body of the message into a mail structure, and finds the values of the query fields from the structure and performs the query.
  4. Once the query is complete, a reply form is sent to the Exchange Connector. The reply form is created by including the results of the query, who is sending the results (in this case the booksrvr application), and who will receive the results (the sender of the original mail) in a new mail structure. After the structure is filled in, a call to MQMailComposeBody creates a message body that is then sent to the Exchange Connector's server input queue.
  5. The Exchange Connector retrieves the message from the queue, translates it into mail, and submits it to the Exchange user who requested the query.
  6. The Exchange user can then retrieve the mail from the Inbox and view the results of the query.

To Run Book Server

  1. Build the sample Message Queuing application.
    • Make sure that the environment (PATH, INCLUDE, and LIB variables) is set correctly to compile Windows-based applications.
    • Edit the file mk.bat that is in the booksrvr directory. Make the following changes to point to the correct locations of the Message Queuing SDK directory and the Message Queuing Mail SDK directory.
      set PLATFORM_SDK = c:\mssdk
    • Run mk.bat. This should build booksrvr.exe in the booksrvr directory.
  2. Ask your Microsoft Exchange administrator to install the MSMQ Exchange Connector.
  3. From the booksrvr directory, the administrator must install the forms bookfrm.efp and bookres.efp into your Exchange system.
  4. Your Exchange administrator must add a custom recipient named "Book Server" with the address-type Message Queuing and whose address is "booksrvrq." It must not be a rich-text recipient.
  5. Run booksrvr.exe (make sure Message Queuing is running). Type "booksrvr booksrvrq" in the command line. The argument booksrvrq is the label of the queue that the booksrvr application will use as its input queue. This label should be identical to the address of the "Book Server" custom recipient that your Exchange administrator entered.
  6. Send the query. In your mail client, open the form named "Book Search". Fill in the appropriate fields and submit the form.
  7. Verify the query results. After a short time, you should receive a result form sent by the sample booksrvr application with the results of the query.


MSMQ MAPI Transport Provider

[The Message Queuing Mail Service is available only on Windows NT4 and Windows 2000.]

The Message Queuing (MSMQ) MAPI Transport Provider allows you to connect MAPI client applications (such as Microsoft® Exchange clients) to Message Queuing applications. As a transport provider, the MSMQ MAPI Transport Provider translates between e-mail and Message Queuing mail messages.

Additional MAPI Transport Provider information is outlined in the following:

  • To set up the MAPI Transport Provider, see Setting up the MSMQ MAPI Transport Provider.
  • To see how e-mail is sent to Message Queuing applications, see Sending E-mail to an Message Queuing Application.
  • To see how mail messages are sent to MAPI applications, see Sending Message Queuing Mail Message to a MAPI Client.
  • To use the functions and COM components provided by the Message Queuing mail API, see the reference page for each item. You can locate these functions and COM components by name or by looking in Message Queuing Mail Functions and Message Queuing Mail COM Components.


Setting Up the MSMQ MAPI Transport Provider

[The Message Queuing Mail Service is available only on Windows NT4 and Windows 2000.]

Setting up the MSMQ MAPI Transport Provider is a two-part process that includes:

  • Installing the MAPI Transport Provider.
  • Creating a MAPI address for your Message Queuing application.

The MSMQ MAPI Transport Provider is installed with Message Queuing. The installation adds Message Queuing to the list of MAPI Transport Providers available to your MAPI applications.

After Message Queuing is installed, add "Microsoft Message Queue" to your MAPI profiles. (For more information on how to add services to your profiles, see the documentation for your MAPI client). After Adding "Microsoft Message Queue," restart your MAPI applications to make sure your profile changes have taken effect.

Each Message Queuing application that sends mail messages or receives translated e-mail messages must have a MAPI address. The MSMQ MAPI Transport Provider uses this information to locate the application's input queue.

The addresses for your Message Queuing applications should be created and saved in the personal address book used by your MAPI applications. To create an address, open the personal address book and add a new address of the type Other Address. The following table describes the necessary content for each field.

Field | Description
Display name | Specify a name for the Message Queuing application. This name is an alias and is only used for display purposes.
E-mail address | Specify the label of the Message Queuing application's input queue (case sensitive). The MAPI transport provider uses this information to locate the input queue.
E-mail type | Set to MSMQ. This instructs the MAPI Transport Provider to handle this type of form.

Clear the Always send to this recipient in Microsoft Exchange rich text check box. Rich text information should never be sent to an Message Queuing application unless the application is known to understand the MAPI TNEF format.


Sending E-mail to an Message Queuing Application

[The Message Queuing Mail Service is available only on Windows NT4 and Windows 2000.]

The e-mails submitted by MAPI client applications are routed through the MSMQ MAPI Transport Provider to the Message Queuing application (see the following illustration). The Message Queuing application can then pick up, process, and return the mail to the MAPI user who sent the mail or forward it (or another mail) to the next processing destination.

To send forms to an Message Queuing application, the MSMQ MAPI Transport Provider performs the following tasks:

  • Converts the e-mail form to an Message Queuing mail message whose body is in Message Queuing mail format.
  • Sends the converted mail message to the Message Queuing application input queue used by the Message Queuing application.

The Message Queuing application must create the application input queue. When creating the queue, the application must specify the following queue type so that the MAPI Transport Provider can find the queue.

{5eadc0d0-7182-11cf-a8ff-0020afb8fb50}.

Additional information can be found in the following topics:

  • To see how Message Queuing messages are sent to MAPI clients, see Sending Message Queuing Mail Message to a MAPI Client.
  • To set up the MAPI Transport Provider, see Setting up the MSMQ MAPI Transport Provider.
  • To use the functions and COM components provided by the Message Queuing mail API, see the reference page for each item. You can locate these functions and COM components by name or by looking in Message Queuing Mail Functions and Message Queuing Mail COM Components.


Sending Message Queuing Mail Message to a MAPI Client

[The Message Queuing Mail Service is available only on Windows NT4 and Windows 2000.]

Message Queuing mail messages sent to a MAPI client are sent to the client's MAPI user input queue. From there, they are routed through the MAPI Transport Provider where they are translated and sent to the Inbox of the appropriate MAPI client. See the following illustration.

The MSMQ MAPI Transport Provider creates a MAPI user input queue for the MAPI user when it starts for the first time. This queue is created only once by the MAPI Transport Provider. The MAPI user input queue is used only when an Message Queuing mail message is sent to a MAPI client. It is not used when a MAPI client sends e-mail to an Message Queuing application.

When an Message Queuing mail message is sent to a MAPI client, the sending application sends the messat to this useer input queue, and the MAPI Transport then performs the following functions the the MAPI Transport Provider performs the following functions:

  • Reads the Message Queuing mail message from the user input queue.
  • Translates the Message Queuing mail message into an e-mail message.
  • Sends the e-mail message to the Inbox for the MAPI application.

The Message Queuing application must know the MAPI address of the client where it sends the messages.

Additional information about MAPI tasks can be found in the following:

  • To create an address for the MAPI client, see Setting Up the MSMQ MAPI Transport Provider.
  • To see how e-mail messages are sent to Message Queuing applications, see Sending E-mail to an Message Queuing Application.
  • To set up the MAPI Transport Provider, see Setting Up the MSMQ MAPI Transport Provider.
  • To use the functions and COM components provided by the Message Queuing mail API, see the reference page for each item. You can locate these functions and COM components by name or by looking in Message Queuing Mail Functions and Message Queuing Mail COM Components.


Logging Information

[The Message Queuing Mail Service is available only on Windows NT4 and Windows 2000.]

The MSMQ MAPI Transport Provider uses the Application Event Log to record informational messages and error messages. When logging messages, it inserts the name MSMQMAPI in the source column of the event viewer.

For example, when Microsoft Exchange starts the MAPI Transport Provider, it performs a basic initialization, logging the following informational messages in the event viewer.

If Initialization | Then message reads
Succeeds | "Transport provider logon succeeded"
Fails | "Transport provider logon failed"

Error entries that are logged by the MAPI Transport Provider include a details section that provides a stack trace of error descriptions. Save this information for a reference when troubleshooting problems.


Using Forms In Message Queuing Mail

[The Message Queuing Mail Service is available only on Windows NT4 and Windows 2000.]

The Message Queuing mail services (MSMQ Exchange Connector, MSMQ MAPI Transport) can exchange EFD (Exchange Form Designer) forms between mail users and Message Queuing applications.

When a mail user sends an EFD form to an Message Queuing application, the Message Queuing mail service translates the EFD form to a mail message that contains the form's data, and sends it to the Message Queuing application.

When the Message Queuing mail service receives a mail message that contains a form's data, it translates it to an EFD form and puts it in the inbox of the mail user. Note that the name of the form in the received mail message must correspond to an EFD form that is recognized by the mail user. Otherwise, the mail user would not be able to view the form.

In addition to the general e-mail data, the Message Queuing mail format of such a mail message contains the name of the form, and the name and the value of each field. This format is described in Message Queuing Mail Format.

For form processing to work correctly, the form designer and the Message Queuing application developer must agree on the field names used in the form. The Message Queuing application must know the name of the fields on the form so that it can parse received mail messages that contain that form or compose new mail messages that contain that form.

For example, when creating an EFD form that has several fields, the form designer can use the Microsoft® Exchange Form Designer to specify a name for each field (the name of each field is entered in the Reference Name field on the General page in the Field Properties dialog box). The Message Queuing application developer needs to know these names to write an application that can parse the mail messages it receives and compose its own mail messages.

Note For more information on designing forms, see the Microsoft Exchange Form Designer documentation.


Message Queuing Mail Format

[The Message Queuing Mail Service is available only on Windows NT4 and Windows 2000.]

The Message Queuing mail format is used to represent e-mail information within the body of an Message Queuing mail message. It is used by the MSMQ Exchange Connector, MSMQ MAPI Transport Provider, and the Message Queuing mail API.

Note The Message Queuing mail format is a subset of the Multipurpose Internet Mail Extensions (MIME) format.

The body of a mail message is composed of:

  • A header section (see Header Section)
  • An empty line (CR/LF pair)
  • A body section (see Body Section)

For samples of the Message Queuing mail format, see Sample Form Message and Sample Text Message.


Header Section

[The Message Queuing Mail Service is available only on Windows NT4 and Windows 2000.]

The header section is composed of several headers with each header on a separate line (each line is terminated by a CR/LF pair). Each header is composed of a header name followed by a colon and a header value (for example, Subject: message subject).

The following table describes the headers that are used.

Header Name Description
MIME-Version Describes the MIME version used. It should contain the value 1.0.

Example: MIME-Version: 1.0
Date Indicates the time the message was submitted by the sender. It is formatted as {sender-local-date} {sender-local-time} {sender-local-time-zone}.

Example: Date: 21 Jul 1996 20:12:06-0300

Month names: Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, and Dec

Time zones should be numeric and prefixed with a "–" (minus sign) or a "+" (plus sign); that is, no named time zones.
From Indicates the sender of the message.

For applications using the MSMQ Exchange Connector, this header is formatted as {sender-friendly-name<user-email-alias@server-input-queue-label>}; where the user e-mail alias is the user's alias in the Microsoft Exchange system (corresponds to the PR_ACCOUNT property of the user) and server-input-queue-label is the label of the MSMQ Exchange Connector's input queue.

Example: From: Jane Doe <janedoe@Exchangeserverinputqueue>

For applications using the MAPI Transport Provider, it is formatted as {sender-friendly-name <sender-queue-label>}. Where the sender-queue-label is the Message Queuing queue label associated with the sender.

Example: From: John Doe <johndoe>
Subject Indicates the subject of the message. The subject text is not formatted.

Example: Subject: message subject
To Lists each message recipient separated by a comma. Each recipient is formatted as {recipient-friendly-name <recipient-address>}.

For the MSMQ MAPI Transport Provider, the recipient address is the label of the MAPI user input queue associated with the recipient.

Example: To: John Doe<johndoe>

For the MSMQ Exchange Connector, the recipient name includes the user name plus the label of the MSMQ Exchange Connector's server input queue.

Example: To: Jane Doe<janedoe@ServerInputQueueLabel>
Cc Optional. Lists the copied message recipients separated by a comma. Each recipient is formatted as {recipient-friendly-name <recipient-address>}.

For the MSMQ MAPI Transport Provider, the recipient address is the label of the MAPI user input queue associated with the recipient.

Example: To: John Doe<johndoe>

For the MSMQ Exchange Connector, the recipient name includes the user name plus the label of the MSMQ Exchange Connector's server input queue.

Example: To: Jane Doe<janedoe@ServerInputQueueLabel>
Bcc Optional. Lists the hidden copied message recipients separated by a comma. Each recipient is formatted as {recipient-friendly-name <recipient-address>}.

For the MSMQ MAPI Transport Provider, the recipient address can be the Message Queuing queue label associated with the recipient.

Example: Bcc: John Doe<johndoe>

For MSMQ Exchange Connector, the recipient name includes the user name plus the Message Queuing queue label of the connector's queue.

Example: Bcc: Jane Doe<janedoe@ExchangeConnectorQueueLabel>
Content-Type Optional. Describes the content of the body section of the message. It can have one of the following values (the default is "text/plain; charset=us-ascii"):

text/plain; charset=us-ascii

This means that this is a regular message, and the body section contains the message text.

Example: Content-Type: text/plain; charset=us-ascii

application/x-ms-tnef

This means that this is a TNEF message and the body section contains the TNEF data of the message.

Example: Content-Type: application/x-ms-tnef

multipart/form-data; boundary=boundary-string

This means that the form and body section have multiple parts, and each part describes a single form field (name, value, and so on). The boundary-string separates multiple parts in the body section (see Body Section).

Example: Content-Type: multipart/form-data;
boundary=xyz12sssdeeggg
Content-Transfer-Encoding Describes the encoding of the body section (if it contains binary data). The only legal header value is binary (that is, no encoding of binary data).

Example: Content-Transfer-Encoding: binary
X-Form-Name Name of the form whose fields are described in the body section. This header is not necessary on text messages, only on form messages.

The name here corresponds to the name defined by the Exchange Form Designer (see the Item Type field in the General tab of the Form Properties dialog box) and the PR_MESSAGE_CLASS property of the form.

Example:

X-Form: IPM.ORGANIZATION.SAMPLE
X-Delivery-Report-Requested Specifies whether the receiving application should return a delivery report when the message is received. Valid values are True or False.

Example:

X-Delivery-Report-Requested: True
X-Non-Delivery-Report-Requested Specifies whether a non-delivery report should be sent back. Valid values are True or False.

Example:

X-Non-Delivery-Report-Requested: True
X-Report-Date Indicates the time the report was submitted.

This header is only set for delivery or non-delivery report messages.

It is formatted as the Date header mentioned previously.

Example:

X-Report-Date: 22 Jul 1996 21:12:06 –0300
X-Report-To Specifies the recipient of the delivery or non-delivery report.

This header is set only on delivery or non-delivery report messages.

It is formatted as the To header above but contains only one recipient.

Example:

X-Report-To: John Doe<johndoe>
X-Report-Delivered-To

X-Report-Delivered-Cc

X-Report-Delivered-Bcc

 Specifies recipients who received a previously sent mail.

These headers are only set on delivery report messages.

X-Report-Delivered-To specifies the delivered recipients from the To list of the original e-mail.

X-Report-Delivered-Cc specifies the delivered recipients from the Cc list of the original e-mail.

X-Report-Delivered-Bcc specifies the delivered recipients from the Bcc list of the original e-mail.

They are formatted as the To header above, but contain the delivery time as well. The delivery time is formatted as the Date header above and appears between round brackets after the recipient's address.

Example: X-Report-Delivered-To: John Doe<johndoe>(22 Jul 1996 21:11:06 –0300), Jane Doe<mailto:janedoe@ExchangeConnectorQueueLabel >(21 Jul 1996 20:06:06 –0300)
X-Report-Not-Delivered-To

X-Report- Not-Delivered-Cc

X-Report- Not-Delivered-Bcc

 Specifies recipients who did not receive a previously sent mail.

These headers are set only on non-delivery report messages.

X-Report-Not-Delivered-To specifies the non-delivered recipients from the To list of the original e-mail.

X-Report-Not-Delivered-Cc specifies the non-delivered recipients from the Cc list of the original e-mail.

X-Report-Not-Delivered-Bcc specifies the non-delivered recipients from the Bcc list of the original e-mail.

They are formatted as the X-Report-Delivered-To header above but contain the non-delivery reason instead of the delivery time.

The non-delivery reason is not formatted and appears between round brackets after the recipient's address.

Example: X-Report-Not-Delivered-To: John Doe<johndoe>(Communication failure), Jane Doe<mailto:janedoe@ExchangeConnectorQueueLabel >(Recipient is not known at this address)

For samples of the Message Queuing mail format, see Sample Form Message and Sample Text Message.


Body Section

[The Message Queuing Mail Service is available only on Windows NT4 and Windows 2000.]

The body section of the Message Queuing mail format begins at the line after the separating empty line and ends at the end of the file.

The body section can be formatted in several ways. If the Content-Type header value is text/plain, the body section only contains the text of the message. If the Content-Type header value is multipart/form-data, the body section contains a collection of field sections, each separated by a boundary string (the boundary string is defined in the header section). If the Content-Type header value is application/x-ms-tnef, the body section contains the Transport-Neutral Encapsulation Format (TNEF) data of the message. For information on the Content-Type header, see Header Section.

The format of a multiple, form-data body section is as follows:

--boundary string
field section 1
--boundary string
field section 2
--boundary string—-

Each field section describes one of the form's fields and is formatted very much like the message itself. Each section starts with a Content-Disposition header line, followed by an empty line, followed by a body section line. The Content-Disposition line describes the field, and the body section line specifies the value of the field. The boundary string following the last field section always ends with two minus characters (--).

The following example shows a field section that specifies the customer name John Doe (7fs9dfsdfs9sdf is the boundary string):

--7fs9dfsdfs9sdf
Content-Disposition: form-data; name=Customer

John Doe
--7fs9dfsdfs9sdf                 'If last field, add --

If the field is a Boolean field such as a text box, the Content-Disposition line should also contain the parameter x-type=boolean (prefixed by a semicolon).

For example:

blank line(cr/lf)
--hj57ujkdfg4535
Content-Disposition: form-data; name=SaveSettingsOnExit; x-type=boolean

true
--hj57ujkdfg4535                 'If last field, add --

Note When creating a multiple, form-data body section, the following apply:

  • The actual separator starts with two minus characters (--) followed by the supplied boundary string. The last boundary also ends with two minus characters (--). This is part of the MIME multipart format.
  • The blank line (CR/LF pair) before the boundary string belongs to the boundary, not to the field section before it. If you'd like the field section to end with a CR/LF, leave an empty line before the boundary.
  • Any text in the body section that comes before the first boundary string or after the last boundary string (the boundary string followed by two minus characters) is ignored.

For samples of the Message Queuing mail format, see Sample Form Message and Sample Text Message.


Sample Text Message

[The Message Queuing Mail Service is available only on Windows NT4 and Windows 2000.]

In this sample, there are eight headers in the header section and two lines in the message body. Notice that the Content-Type header (see Body Section) indicates that the body of the message contains only text.

Mime-Version: 1.0
Date: 21 Jul 1996 20:12:06 -0300
From: User name <useraddress>
Subject: Message representation
Content-Transfer-Encoding: binary
To: John Doe <johndoe>, Good Guy <ggqueue>
Cc: Another Good Guy <aggqueue>
Content-Type: text/plain; charset=us-ascii

This is the first line of the message body. Notice the previous
empty line that separates this body section from the eight headers
in the header section.

This is the second line of the message body.

For information on the header and body sections, see Header Section and Body Section.

For a sample of a form message, see Sample Form Message.


Sample Form Message

[The Message Queuing Mail Service is available only on Windows NT4 and Windows 2000.]

In this sample, there are eight headers in the header section and five section fields in the message body. Notice that the Content-Type header (see Body Section) indicates that the body of the message contains fields and that the boundary string is 7pKviP84rI4ZzGBds.

Mime-Version: 1.0
Date: 21 Jul 1996 20:12:06 -0300
From: Jane Doe (MSMQ) <janedoe>
Subject: Form representation
X-Form-Name: IPM.MSMQMAPI.SAMPLE
Content-Transfer-Encoding: binary
To: John Doe <johndoe>
Content-Type: multipart/form-data; boundary=7pKviP84rI4ZzGBds

--7pKviP84rI4ZzGBds
Content-Disposition: form-data; name=TextBox_Name

This is a text box control
--7pKviP84rI4ZzGBds
Content-Disposition: form-data; name=CheckBox_Name; x-type=boolean

true
--7pKviP84rI4ZzGBds
Content-Disposition: form-data; name=RadioButton_Name

RadioButton_choice1
--7pKviP84rI4ZzGBds
Content-Disposition: form-data; name=ComboBox_Name

This is a combo box control
--7pKviP84rI4ZzGBds
Content-Disposition: form-data; name=ListBox_Name

2222
--7pKviP84rI4ZzGBds--

For information on the header and body sections, see Header Section and Body Section.

For a sample of a text message, see Sample Text Message.


Using Message Queuing

This section provides two sets of code examples: one set that uses function calls to perform a task and another that uses COM components. Each example in these sections contains a procedure that explains the steps needed to perform the task, followed by one or more complete code examples that you can cut and paste into your application.

For | See
Examples using function calls | Using the Message Queuing Functions
Examples using COM components | Using the COM Components


Using the Message Queuing Functions

This section contains code examples of the basic tasks your application may need to perform.

Note For information on a specific Message Queuing function, property, or structure, see the specific reference page in the Message Queuing Reference.

For examples of | See
Creating queues | Creating a Queue
Locating public queues | Locating a Public Queue
Opening queues | Opening a Queue
Deleting queues | Deleting a Queue
Sending messages to a queue | Sending Messages
Reading message from a queue | Reading Messages in a Queue
Requesting authentication when sending messages and validating authentication when reading messages | Requesting and Validating Authentication
Filtering messages using message properties | Filtering Messages
Retrieving the properties of an existing queue | Retrieving Queue Properties
Setting the properties of an existing queue | Setting Queue Properties
Setting the access control of a queue | Setting Access Control Security for a Queue
Connector application tasks | Returning an Acknowledgment Message by a Connector Application
Sending and retrieving messages within transactions, and checking transaction boundaries | Using Transactions
Checking whether the computer running Message Queuing is part of a workgroup | Verifying Workgroup Installation


Creating a Queue

Queues are created by calling MQCreateQueue. These include public queues registered in the directory service, private queues registered on the local computer.

Before creating a queue, you must decide where its messages will be stored, where the queue will be registered, and what the name for the queue will be. All this information is included as part of the PROPID_Q_PATHNAME property of the queue. PROPID_Q_PATHNAME is the only required property needed to create a queue.

When creating the queue, you can also set additional queue properties, such as the label of the queue, the privacy level of the queue, and the transactional status of the queue.

Once the queue is created, the format name returned by MQCreateQueue can be used to open the queue for sending messages or reading messages.

For an example of | See
Creating a public queue | Creating a Public Queue
Creating a private queue | Creating a Private Queue
Creating a transactional queue | Creating a Transactional Queue
Creating a queue that only accepts private (encrypted) messages | Creating a Private-Message-Only Queue


Creating a Public Queue

To create a public queue, you must provide the pathname for the queue, plus any additional queue properties needed by your application.

The pathname for a public queue contains the name of the computer where the messages sent to the queue will be stored and the name of the queue.

When providing the name of computer, you can use the NetBIOS machine name or the full DNS machine name. To designate the local computer, you can also use a period (".").

When providing a name for the queue, you can use any character except "\", ";" and "$" as the last character of the name (Message Queuing reserves names ending with "$", for example, the token "PRIVATE$" is used to specify a private queue).The name of the queue is case-insensitive (for example, "MyQueue" and "myQueue" are treated as the same name)and can be up to 124 Unicode characters.

Note Queue names greater than 64 Unicode characters may cause a slight reduction in performance, plus they are not easily displayed in the directory service.

To create a public queue

  1. Define the structures needed to create the queue.
  2. Specify PROPID_Q_PATHNAME in the MQQUEUEPROPS structure. In this example, "." is used to indicate the local computer.

    Note For Message Queuing servers and independent clients, the local machine is the local computer. However, for Message Queuing–dependent clients, the local machine is the client's Message Queuing server.

  3. Optional. Add additional queue properties as needed. In this example, PROPID_Q_LABEL is set to "Test Queue".
  4. Initialize the MQQUEUEPROPS structure.
  5. Call MQCreateQueue to create the queue.
For a code example using | See
C++ | C/C++ Code Example


C/C++ Code Example: Creating a Public Queue

The following example creates a public queue on the local computer. If a queue with the same pathname already exists, an error message is displayed and no queue is created.

#include <windows.h>
#include <stdio.h>
#include <mq.h>                                       // Message Queuing header file

int main(int arg, char *argv[])

{
  ////////////////////////////////////////////////////////////
  //  Define the required structures.
  ////////////////////////////////////////////////////////////

  #define NUMBEROFPROPERTIES 2                        // Number of queue properties
  DWORD cPropId = 0;                                  // Define the property counter.

  //Define the MQQUEUPROPS structure.
  MQQUEUEPROPS QueueProps;
  MQPROPVARIANT aQueuePropVar[NUMBEROFPROPERTIES];
  QUEUEPROPID aQueuePropId[NUMBEROFPROPERTIES];
  HRESULT aQueueStatus[NUMBEROFPROPERTIES];

  HRESULT hr;                                         // Define results.
  PSECURITY_DESCRIPTOR pSecurityDescriptor=NULL;      // Security descriptor

  // Queue pathname
  LPWSTR wszPathName = L".\\TestQueue";

  // Queue label
  LPWSTR wszQueueLabel = L"Test Queue";

  // Format name buffer for queue
  DWORD dwFormatNameBufferLength = 256;               // Length of format name buffer
  WCHAR wszFormatNameBuffer[256];                     // Format name buffer

  /////////////////////////////////////////////////////////////////
  // Specify PROPID_Q_PATHNAME.
  /////////////////////////////////////////////////////////////////

  aQueuePropId[cPropId] = PROPID_Q_PATHNAME;          // Property ID
  aQueuePropVar[cPropId].vt = VT_LPWSTR;              // Type indicator
  aQueuePropVar[cPropId].pwszVal = wszPathName;       // Pathname of queue
  cPropId++;

  /////////////////////////////////////////////////////////////////
  // Add additional queue properties here. When adding properties,
  // increment NUMBEROFPROPERTIES to reflect total number of
  // properties.
  /////////////////////////////////////////////////////////////////

  aQueuePropId[cPropId] = PROPID_Q_LABEL;             // Property ID
  aQueuePropVar[cPropId].vt = VT_LPWSTR;              // Type indicator
  aQueuePropVar[cPropId].pwszVal = wszQueueLabel;     // Label of queue
  cPropId++;

  /////////////////////////////////////////////////////////////////
  // Initialize the MQQUEUEPROPS structure.
  /////////////////////////////////////////////////////////////////

  QueueProps.cProp = cPropId;                         // Number of properties
  QueueProps.aPropID = aQueuePropId;                  // Ids of properties
  QueueProps.aPropVar = aQueuePropVar;                // Values of properties
  QueueProps.aStatus = aQueueStatus;                  // Error reports

  /////////////////////////////////////////////////////////////////
  //Create Queue.
  /////////////////////////////////////////////////////////////////

  hr = MQCreateQueue(pSecurityDescriptor,             // Security descriptor
                     &QueueProps,                     // Queue properties
                     wszFormatNameBuffer,             // OUT: Format name of queue
                     &dwFormatNameBufferLength);      // OUT: Format name length
  if (FAILED(hr))
  {
    switch( hr )
    {
      case MQ_ERROR_QUEUE_EXISTS:
        fprintf(stderr, "The queue already exists!\n");
        break;
      default:
        fprintf(stderr, "Failed creating queue, error = 0x%x\n",hr);
        break;
    }
    return -1;
  }

  puts ("The queue is created!");
  return 0;

}


Creating a Private Queue

To create a private queue, you must provide the pathname for the queue, plus any additional queue properties needed by your application.

The pathname for a private queue contains the name of the local computer where the messages sent to the queue will be stored, the "PRIVATE$" keyword, and the name of the queue.

When providing the name of local computer, you can use the NetBIOS machine name, full DNS machine name, or a period (".") to designate the local computer. Private queues can only be created on the local computer.

When providing a name for the queue, you can use any character except "\", ";" and "$" as the last character of the name (Message Queuing reserves names ending with "$". For example, the token "PRIVATE$" is used to specify a private queue).The name of the queue is case-insensitive (for example, "MyQueue" and "myQueue" are treated as the same name)and can be up to 124 Unicode characters.

To create a private queue

  1. Define the structures needed to create the queue.
  2. Specify PROPID_Q_PATHNAME in the MQQUEUEPROPS structure. In this example, "." is used to indicate the local computer.

    Note For Message Queuing servers and independent clients, the local machine is the local computer. However, for Message Queuing–dependent clients, the local machine is the client's Message Queuing server.

  3. Optional. Add additional queue properties as needed. In this example, PROPID_Q_LABEL is set to "Test Queue".
  4. Initialize the MQQUEUEPROPS structure.
  5. Call MQCreateQueue to create the queue.
For a code example using | See
C++ | C/C++ Code Example


C/C++ Code Example: Creating a Private Queue

The following example creates a private queue on the local computer. If a queue with the same pathname already exists, an error message is displayed and no queue is created.

#include <windows.h>
#include <stdio.h>
#include <mq.h>                                       // Message Queuing header file

int main(int arg, char *argv[])

{
  ////////////////////////////////////////////////////////////
  //  Define the required structures.
  ////////////////////////////////////////////////////////////

  #define NUMBEROFPROPERTIES 2                        // Number of queue properties
  DWORD cPropId = 0;                                  // Define the property counter.

  //Define the MQQUEUPROPS structure.
  MQQUEUEPROPS QueueProps;
  MQPROPVARIANT aQueuePropVar[NUMBEROFPROPERTIES];
  QUEUEPROPID aQueuePropId[NUMBEROFPROPERTIES];
  HRESULT aQueueStatus[NUMBEROFPROPERTIES];

  HRESULT hr;                                         // Define results.
  PSECURITY_DESCRIPTOR pSecurityDescriptor=NULL;      // Security descriptor

  // Queue pathname
  LPWSTR wszPathName = L".\\PRIVATE$\\TestQueue";

  // Queue label
  LPWSTR wszQueueLabel = L"Test Queue";

  // Format name buffer for queue
  DWORD dwFormatNameBufferLength = 256;               // Length of format name buffer
  WCHAR wszFormatNameBuffer[256];                     // Format name buffer

  /////////////////////////////////////////////////////////////////
  // Specify PROPID_Q_PATHNAME.
  /////////////////////////////////////////////////////////////////

  aQueuePropId[cPropId] = PROPID_Q_PATHNAME;          // Property ID
  aQueuePropVar[cPropId].vt = VT_LPWSTR;              // Type indicator
  aQueuePropVar[cPropId].pwszVal = wszPathName;       // Pathname of queue
  cPropId++;

  /////////////////////////////////////////////////////////////////
  // Add additional queue properties here. When adding properties,
  // increment NUMBEROFPROPERTIES to reflect total number of
  // properties.
  /////////////////////////////////////////////////////////////////

  aQueuePropId[cPropId] = PROPID_Q_LABEL;             // Property ID
  aQueuePropVar[cPropId].vt = VT_LPWSTR;              // Type indicator
  aQueuePropVar[cPropId].pwszVal = wszQueueLabel;     // Label of queue
  cPropId++;

  /////////////////////////////////////////////////////////////////
  // Initialize the MQQUEUEPROPS structure.
  /////////////////////////////////////////////////////////////////

  QueueProps.cProp = cPropId;                         // Number of properties
  QueueProps.aPropID = aQueuePropId;                  // Ids of properties
  QueueProps.aPropVar = aQueuePropVar;                // Values of properties
  QueueProps.aStatus = aQueueStatus;                  // Error reports

  /////////////////////////////////////////////////////////////////
  // Create Queue.
  /////////////////////////////////////////////////////////////////

  hr = MQCreateQueue(pSecurityDescriptor,             // Security descriptor
                     &QueueProps,                     // Queue properties
                     wszFormatNameBuffer,             // OUT: Format name of queue
                     &dwFormatNameBufferLength);      // OUT: Format name length
  if (FAILED(hr))
  {
    switch( hr )
    {
      case MQ_ERROR_QUEUE_EXISTS:
        fprintf(stderr, "The queue already exists!\n");
        break;
      default:
        fprintf(stderr, "Failed creating queue, error = 0x%x\n",hr);
        break;
    }
    return -1;
  }

  puts ("The queue is created!");
  return 0;

}


Creating a Transactional Queue

To create a transactional queue, the PROPID_Q_TRANSACTION property must be set to MQ_TRANSACTIONAL.

Note You cannot make a queue transactional once the queue is created. PROPID_Q_TRANSACTION cannot be changed once the queue is created.

This example creates a public transactional queue. You can also use this code to create a private transactional queue by adding the PRIVATE$ keyword to the pathname of the queue (PROPID_Q_PATHNAME).

To create a transactional queue

  1. Define the structures needed to create the queue.
  2. Specify PROPID_Q_PATHNAME and PROPID_Q_TRANSACTION in the MQQUEUEPROPS structure. In this example, "." is used to indicate the local computer.

    Note For Message Queuing servers and independent clients, the local machine is the local computer. However, for Message Queuing–dependent clients, the local machine is the client's Message Queuing server.

  3. Optional. Add additional queue properties as needed. In this example, PROPID_Q_LABEL is set to "Test Queue".
  4. Initialize the MQQUEUEPROPS structure.
  5. Call MQCreateQueue to create the queue.
For a code example using | See
C++ | C/C++ Code Example


C/C++ Code Example: Creating a Transactional Queue

The following example creates a public transactional queue. If a queue with the same pathname already exists, an error message is displayed and no queue is created.

#include <windows.h>
#include <stdio.h>
#include <mq.h>                                       // Message Queuing header file

int main(int arg, char *argv[])

{
  ////////////////////////////////////////////////////////////
  //  Define the required structures.
  ////////////////////////////////////////////////////////////

  #define NUMBEROFPROPERTIES 3                        // Number of queue properties
  DWORD cPropId = 0;                                  // Define the property counter.

  //Define the MQQUEUPROPS structure.
  MQQUEUEPROPS QueueProps;
  MQPROPVARIANT aQueuePropVar[NUMBEROFPROPERTIES];
  QUEUEPROPID aQueuePropId[NUMBEROFPROPERTIES];
  HRESULT aQueueStatus[NUMBEROFPROPERTIES];

  HRESULT hr;                                         // Define results.
  PSECURITY_DESCRIPTOR pSecurityDescriptor=NULL;      // Security descriptor

  // Queue pathname
  LPWSTR wszPathName = L".\\TestQueue";

  // Queue label
  LPWSTR wszQueueLabel = L"Test Queue";

  // Transaction level
  UCHAR ucTransactionLevel = MQ_TRANSACTIONAL;

  // Format name buffer for queue
  DWORD dwFormatNameBufferLength = 256;               // Length of format name buffer
  WCHAR wszFormatNameBuffer[256];                     // Format name buffer

  /////////////////////////////////////////////////////////////////
  // Specify PROPID_Q_PATHNAME.
  /////////////////////////////////////////////////////////////////

  aQueuePropId[cPropId] = PROPID_Q_PATHNAME;          // Property ID
  aQueuePropVar[cPropId].vt = VT_LPWSTR;              // Type indicator
  aQueuePropVar[cPropId].pwszVal = wszPathName;       // Pathname of queue
  cPropId++;

  /////////////////////////////////////////////////////////////////
  // Add additional queue properties here. When adding properties,
  // increment NUMBEROFPROPERTIES to reflect total number of
  // properties.
  /////////////////////////////////////////////////////////////////

  aQueuePropId[cPropId] = PROPID_Q_TRANSACTION;       // Property ID
  aQueuePropVar[cPropId].vt = VT_UI1;                 // Type indicator
  aQueuePropVar[cPropId].bVal = ucTransactionLevel;   // Transaction level
  cPropId++;

  aQueuePropId[cPropId] = PROPID_Q_LABEL;             // Property ID
  aQueuePropVar[cPropId].vt = VT_LPWSTR;              // Type indicator
  aQueuePropVar[cPropId].pwszVal = wszQueueLabel;     // Label of queue
  cPropId++;

  /////////////////////////////////////////////////////////////////
  // Initialize the MQQUEUEPROPS structure.
  /////////////////////////////////////////////////////////////////

  QueueProps.cProp = cPropId;                         // Number of properties
  QueueProps.aPropID = aQueuePropId;                  // Ids of properties
  QueueProps.aPropVar = aQueuePropVar;                // Values of properties
  QueueProps.aStatus = aQueueStatus;                  // Error reports

  /////////////////////////////////////////////////////////////////
  // Create Queue.
  /////////////////////////////////////////////////////////////////

  hr = MQCreateQueue(pSecurityDescriptor,             // Security descriptor
                     &QueueProps,                     // Queue properties
                     wszFormatNameBuffer,             // OUT: Format name of queue
                     &dwFormatNameBufferLength);      // OUT: Format name length
  if (FAILED(hr))
  {
    switch( hr )
    {
      case MQ_ERROR_QUEUE_EXISTS:
        fprintf(stderr, "The queue already exists!\n");
        break;
      case MQ_ERROR_INSUFFICIENT_PROPERTIES:
        fprintf (stderr, "Insufficient properties. Check NUMBEROFPROPERTIES.\n");
        break;
      default:
        fprintf(stderr, "Failed creating queue, error = 0x%x\n",hr);
        break;
    }
    return -1;
  }

  puts ("The queue is created!");
  return 0;

}


Creating a Private-message Only Queue

To create a queue that only accepts private messages, the PROPID_Q_PRIV_LEVEL must be set to MQ_PRIV_LEVEL_BODY. (Both private and public queues can be created to accept only private messages.)

This example creates a public queue. You can also use this code to create a private queue by adding the PRIVATE$ keyword to the pathname of the queue (PROPID_Q_PATHNAME).

To create a private-message queue

  1. Define the structures needed to create the queue.
  2. Specify PROPID_Q_PATHNAME and PROPID_Q_PRIV_LEVEL in the MQQUEUEPROPS structure. In this example, "." is used to indicate the local computer.

    Note For Message Queuing servers and independent clients, the local machine is the local computer. However, for Message Queuing–dependent clients, the local machine is the client's Message Queuing server.

  3. Optional. Add additional queue properties as needed. In this example, PROPID_Q_LABEL is set to "Test Queue".
  4. Initialize the MQQUEUEPROPS structure.
  5. Call MQCreateQueue to create the queue.
For a code example using | See
C++ | C/C++ Code Example


C/C++ Code Example: Creating a Private-message Only Queue

The following example creates a public queue that only accepts private messages. If a queue with the same pathname already exists, an error message is displayed and no queue is created.

#include <windows.h>
#include <stdio.h>
#include <mq.h>                                       // Message Queuing header file

int main(int arg, char *argv[])

{
  ////////////////////////////////////////////////////////////
  //  Define the required structures.
  ////////////////////////////////////////////////////////////

  #define NUMBEROFPROPERTIES 3                        // Number of queue properties
  DWORD cPropId = 0;                                  // Define the property counter.

  //Define the MQQUEUPROPS structure.
  MQQUEUEPROPS QueueProps;
  MQPROPVARIANT aQueuePropVar[NUMBEROFPROPERTIES];
  QUEUEPROPID aQueuePropId[NUMBEROFPROPERTIES];
  HRESULT aQueueStatus[NUMBEROFPROPERTIES];

  HRESULT hr;                                         // Define results.
  PSECURITY_DESCRIPTOR pSecurityDescriptor=NULL;      // Security descriptor

  // Queue pathname
  LPWSTR wszPathName = L".\\TestQueue";

  // Queue label
  LPWSTR wszQueueLabel = L"Test Queue";

  // Privacy level
  DWORD dwPrivacyLevel = MQ_PRIV_LEVEL_BODY;

  // Format name buffer for queue
  DWORD dwFormatNameBufferLength = 256;               // Length of format name buffer
  WCHAR wszFormatNameBuffer[256];                     // Format name buffer

  /////////////////////////////////////////////////////////////////
  // Specify PROPID_Q_PATHNAME.
  /////////////////////////////////////////////////////////////////

  aQueuePropId[cPropId] = PROPID_Q_PATHNAME;          // Property ID
  aQueuePropVar[cPropId].vt = VT_LPWSTR;              // Type indicator
  aQueuePropVar[cPropId].pwszVal = wszPathName;       // Pathname of queue
  cPropId++;

  /////////////////////////////////////////////////////////////////
  // Add additional queue properties here. When adding properties,
  // increment NUMBEROFPROPERTIES to reflect total number of
  // properties.
  /////////////////////////////////////////////////////////////////

  aQueuePropId[cPropId] = PROPID_Q_PRIV_LEVEL;        // Property ID
  aQueuePropVar[cPropId].vt = VT_UI4;                 // Type indicator
  aQueuePropVar[cPropId].ulVal = dwPrivacyLevel;       // Privacy level
  cPropId++;

  aQueuePropId[cPropId] = PROPID_Q_LABEL;             // Property ID
  aQueuePropVar[cPropId].vt = VT_LPWSTR;              // Type indicator
  aQueuePropVar[cPropId].pwszVal = wszQueueLabel;     // Label of queue
  cPropId++;

  /////////////////////////////////////////////////////////////////
  // Initialize the MQQUEUEPROPS structure.
  /////////////////////////////////////////////////////////////////

  QueueProps.cProp = cPropId;                         // Number of properties
  QueueProps.aPropID = aQueuePropId;                  // Ids of properties
  QueueProps.aPropVar = aQueuePropVar;                // Values of properties
  QueueProps.aStatus = aQueueStatus;                  // Error reports

  /////////////////////////////////////////////////////////////////
  // Create Queue.
  /////////////////////////////////////////////////////////////////

  hr = MQCreateQueue(pSecurityDescriptor,             // Security descriptor
                     &QueueProps,                     // Queue properties
                     wszFormatNameBuffer,             // OUT: Format name of queue
                     &dwFormatNameBufferLength);      // OUT: Format name length
  if (FAILED(hr))
  {
    switch( hr )
    {
      case MQ_ERROR_QUEUE_EXISTS:
        fprintf(stderr, "The queue already exists!\n");
        break;
      case MQ_ERROR_INSUFFICIENT_PROPERTIES:
        fprintf (stderr, "Insufficient properties. Check NUMBEROFPROPERTIES.\n");
        break;
      default:
        fprintf(stderr, "Failed creating queue, error = 0x%x\n",hr);
        break;
    }
    return -1;
  }

  puts ("The queue is created!");
  return 0;

}


Locating a Public Queue

Public queues can be located by running a query on the queues registered in the directory service. A query can be based on the identifier of the queue, its label, the type of service it provides, when it was created, or the last time the properties of the queue were modified.

To run the query, the following three Locate functions are used: MQLocateBegin, MQLocateNext, and MQLocateEnd.

MQLocateBegin uses two sets of properties: One set specifies the properties used to locate the queues, and the other set specifies the properties that will be included in the query results. For example, you may want to locate all the queues with a specific service type (PROPID_Q_TYPE) and only return their labels (PROPID_Q_LABEL). MQLocateBegin returns a handle to the query results.

Note If Message Queuing finds a queue but the application does not have the access rights required to get the queue's properties, that queue is not included in the results of the query.

Once the results are available, MQLocateNext is called (as many times as needed) to navigate through the results. Finally, after the application is done using the query, MQLocateEnd is called to release the resources used for the query.

For an example of | See
Locating queues based in their service type | Type Query


Type Query

The following example locates all the public queues that have a specific type.

Note Queries can be based on the identifier of the queue, its label, the type of service it provides, when it was created, or the last time the properties of the queue were modified.

To run a query based on the Type of the queue

  1. Specify the search criteria using MQPROPERTYRESTRICTION and MQRESTRICTION.
  2. Specify the properties to retrieve using MQCOLUMNSET.
  3. Call MQLocateBegin to start the query.
  4. Call MQLocateNext to look at the query results.
  5. Call MQLocateEnd to close the query.
For a code example using | See
C++ | C/C++ Code Example


C/C++ Code Example: Type Query

Platform SDK: Message Queuing

Visual C/C++ Code Example: Type Query

The following example shows the code used to locate all the queues of a specific type as well as return their queue identifier (PROPID_Q_INSTANCE) and when they were created (PROPID_Q_CREATE_TIME).

/////////////////////////////////////
// Define the MQPROPERTYRESTRICTION
// and MQRESTRICTION structures.
/////////////////////////////////////
#define MAX_PROPERTIES 13       // 13 possible queue properties
CLSID PRINTER_SERVICE_TYPE =    // dummy GUID
      {0x1, 0x2, 0x3, {0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb}};
HRESULT hr;
MQPROPERTYRESTRICTION PropertyRestriction;
MQRESTRICTION  Restriction;

//////////////////////////////////////////
// Set search criteria according to the
// type of service provided by the queue.
/////////////////////////////////////////

// Set queue restriction to PROPID_Q_TYPE = PRINTER_SERVICE_TYPE.
PropertyRestriction.rel = PREQ;
PropertyRestriction.prop = PROPID_Q_TYPE;
PropertyRestriction.prval.vt = VT_CLSID;
PropertyRestriction.prval.puuid = &PRINTER_SERVICE_TYPE;

// Specify a one property restriction.
Restriction.cRes = 1;
Restriction.paPropRes = &PropertyRestriction;

/////////////////////////////////////////
// Set MQCOLUMNSET structure to specify
// the properties to be returned:
// PROPID_Q_INSTANCE and PROPID_Q_CREATE_TIME.
/////////////////////////////////////////

MQCOLUMNSET    Column;
ROPID    aPropId[2];     // only two properties to retrieve
DWORD           dwColumnCount = 0;

aPropId[dwColumnCount] = PROPID_Q_INSTANCE;
dwColumnCount++;

aPropId[dwColumnCount] = PROPID_Q_CREATE_TIME;
dwColumnCount++;

Column.cCol = dwColumnCount;
Column.aCol = aPropId;

/////////////////////////////////////
// Call MQLocateBegin to start query.
/////////////////////////////////////

HANDLE         hEnum;
hr = MQLocateBegin(
    NULL,           //start search at the top
    &Restriction,   //Search criteria
    &Column,        //Properties to return
    NULL,           //No sort order
    &hEnum          //Enumeration Handle
    );

    if(FAILED(hr))
    {
        //
        //  Error handling
        //
    }

/////////////////////////////////////
// Call MQLocateNext to examine results
// of query.
/////////////////////////////////////

MQPROPVARIANT aPropVar[MAX_PROPERTIES];
DWORD cProps, index;

do
  {
   cProps = MAX_PROPERTIES;
   hr = MQLocateNext(
        hEnum,      // Handle returned by MQLocateBegin
        &cProps,    // Size of aPropVar array
        aPropVar    // An array of MQPROPVARIANT for results
        );

      if (FAILED(hr))
      {
        break;
      }

      for (index = 0; index < cProps; index += dwColumnCount)

      {
         //Process properties of a queue stored in:
         //aPropVar[index], aPropVar[index+1], …,
         //aPropVar[index+dwColumnCount-1].
      }

  } while (cProps > 0);

/////////////////////////////////////
// Call MQLocateEnd to end query.
/////////////////////////////////////
hr = MQLocateEnd(hEnum);   //Handle returned by MQLocateBegin
if(FAILED(hr))
{
    //
    //Error handling
    //
}


Opening a Queue

To open a queue, the application must provide a format name for the queue, and specify the access mode and the share mode of the queue when it calls MQOpenQueue.

Once the queue is open, MQOpenQueue returns a queue handle that can be used to:

  • Send messages to the queue (MQSendMessage).
  • Retrieve and peek at messages in the queue (MQReceiveMessage).
  • Create a cursor for navigating through the queue (MQCreateCursor).
  • Close the queue (MQCloseQueue).
  • Retrieve a format name for the queue (MQHandleToFormatName).

The following examples show several ways to open queues. This includes opening application queues for sending and retrieving messages, opening system queues, such as journal and dead-letter queues, as well as ways to open a queue when the queue's format name is not known.

For an example of | See
Opening a queue to send messages | Opening a Queue to Send Messages
Opening a queue to peek at or retrieve messages | Opening a Queue to Read Messages
Opening a queue when only the queue's pathname is known | Using a Queue Pathname to Open a Queue
Opening a queue when only the queue's identifier (GUID) is known | Using a Queue Identifier to Open a Queue
Opening a private queue when only the machine identifier and queue number is known | Using a Machine Identifier and Queue Number to Open a Private Queue
Opening a queue with a direct format name | Opening a Queue with a Direct Format Name
Opening the queue journal of a public queue | Opening the Queue Journal of a Public Queue
Opening a the queue journal of a private queue | Opening the Queue Journal of a Private Queue
Opening a computer journal queue | Opening a Computer's Computer Journal queue


Opening a Queue to Send Messages

When sending messages to a queue, the queue's access mode must be set to MQ_SEND_ACCESS, and the queue's share mode must be set to MQ_DENY_NONE. Both these modes are set using parameters of the MQOpenQueue function.

Note Message Queuing checks the access rights of local and remote queues at different times. When opening local queues, Message Queuing checks the queue's access rights when the queue is opened. When opening remote queues, the queues access rights are checked when messages are sent to the queue. In either case, the access mode of the opened queue must match the access rights of the queue.

For a discussion of queue access rights, see Access Control.

To open a queue to send messages

  1. Define the required structures. These include the access mode and share mode of the queue.
  2. Obtain a format name for the queue. The example code below uses MQPathNameToFormatName to generate a format name for the queue.
  3. Call MQOpenQueue to open the queue.
  4. Optional. Add code to send message.
  5. Call MQCloseQueue to close.
For a code example using | See
C++ | C/C++ Code Example


C/C++ Code Example: Opening a Queue to Send Messages

This example opens a queue using its known pathname. The queue is opened with send access and then closed.

#include <windows.h>
#include <stdio.h>
#include <mq.h>                                       // Message Queuing header file

int main(int arg, char *argv[])

{
  ////////////////////////////////////////////////////////////
  //  Define the required structures.
  ////////////////////////////////////////////////////////////

  HRESULT hr;                                         // Define results
  QUEUEHANDLE hQueue;                                 // Handle of created queue
  DWORD dwAccess = MQ_SEND_ACCESS;                    // Access mode of queue
  DWORD dwShareMode = MQ_DENY_NONE;                   // Share Mode of queue

  DWORD dwFormatNameBufferLength = 256;               // Length of format name buffer
  WCHAR wszFormatNameBuffer[256];                     // Format name buffer

  /////////////////////////////////////////////////////////////////
  // Call MQPathNameToFormatName to obtain a format name for
  // the queue.
  /////////////////////////////////////////////////////////////////

  hr = MQPathNameToFormatName(L".\\TestQueue",
                              wszFormatNameBuffer,
                              &dwFormatNameBufferLength);
  if (FAILED(hr))
  {
     fprintf(stderr, "Failed in MQPathNameToFormatName, error = 0x%x\n",hr);
     return -1;
  }

  /////////////////////////////////////////////////////////////////
  // Open queue to send message.
  /////////////////////////////////////////////////////////////////

  hr = MQOpenQueue(wszFormatNameBuffer,               // Format name of queue
                   dwAccess,                          // Access mode
                   dwShareMode,                       // Share mode
                   &hQueue                            // OUT: Handle to queue
                   );
  if (FAILED(hr))
  {
     fprintf(stderr, "Failed in MQOpenQueue, error = 0x%x\n",hr);
     return -1;
  }

  puts("The queue is opened to send messages.");

  /////////////////////////////////////////////////////////////////
  // Add code to send messages to the queue.
  /////////////////////////////////////////////////////////////////

  /////////////////////////////////////////////////////////////////
  // Close the queue.
  /////////////////////////////////////////////////////////////////

  hr = MQCloseQueue(hQueue);

  if (FAILED(hr))
  {
     fprintf(stderr, "Failed in MQCloseQueue, error = 0x%x\n",hr);
     return -1;
  }

  puts("The queue is closed.");
  return 0;

}


Opening a Queue to Read Messages

When reading messages from a queue, the queue's access mode and share mode are set when calling MQOpenQueue.

When reading messages, the access mode of the queue can be set to either MQ_RECEIVE_ACCESS or MQ_PEEK_ACCESS. When the access mode is set to MQ_RECEIVE_ACCESS, the application can retrieve messages and peek at the messages in the queue (whether a message is retrieved from the queue or looked at depends on the dwAction parameter of MQReceiveMessage). When the access mode is set to MQ_PEEK_ACCESS, the application can only look at the messages in the queue.

The share mode of the queue can be set to MQ_DENY_NONE or MQ_DENY_RECEIVE_SHARE. When the share mode is set to MQ_DENY_RECEIVE_SHARE, only the current process can receive messages from the queue. If the queue is already open for receiving messages from another process when the MQOpenQueue call is made, the call fails and returns MQ_ERROR_SHARING_VIOLATION.

Note Before opening a queue, Message Queuing verifies that the access mode requested by the application does not conflict with the access rights of the queue. For example, a queue may restrict those who can retrieve messages from it.

For a discussion of queue access rights, see Access Control.

To open a queue to read messages

  1. Define the required structures. This includes the access mode and share mode of the queue.
  2. Obtain a format name for the queue. The example code below uses MQPathNameToFormatName to generate a format name for the queue.
  3. Call MQOpenQueue to open the queue.
  4. Optional. Add code to read the messages in the queue.
  5. Call MQCloseQueue to close.
For a code example using | See
C++ | C/C++ Code Example


C/C++ Code Example: Opening a Queue to Read Messages

This example opens a queue using its known pathname. The queue is opened with receive access and then closed.

#include <windows.h>
#include <stdio.h>
#include <mq.h>                                       // Message Queuing header file

int main(int arg, char *argv[])

{
  ////////////////////////////////////////////////////////////
  //  Define the required structures.
  ////////////////////////////////////////////////////////////

  HRESULT hr;                                         // Define results
  QUEUEHANDLE hQueue;                                 // Handle of created queue
  DWORD dwAccess = MQ_RECEIVE_ACCESS;                 // Access mode of queue
  DWORD dwShareMode = MQ_DENY_RECEIVE_SHARE;          // Share Mode of queue

  DWORD dwFormatNameBufferLength = 256;               // Length of format name buffer
  WCHAR wszFormatNameBuffer[256];                     // Format name buffer

  /////////////////////////////////////////////////////////////////
  // Call MQPathNameToFormatName to obtain a format name for
  // the queue.
  /////////////////////////////////////////////////////////////////

  hr = MQPathNameToFormatName(L".\\TestQueue",
                              wszFormatNameBuffer,
                              &dwFormatNameBufferLength);
  if (FAILED(hr))
  {
     fprintf(stderr, "Failed in MQPathNameToFormatName, error = 0x%x\n",hr);
     return -1;
  }

  /////////////////////////////////////////////////////////////////
  // Open queue to send message.
  /////////////////////////////////////////////////////////////////

  hr = MQOpenQueue(wszFormatNameBuffer,               // Format name of queue
                   dwAccess,                          // Access mode
                   dwShareMode,                       // Share mode
                   &hQueue                            // OUT: Handle to queue
                   );
  if (FAILED(hr))
  {
     fprintf(stderr, "Failed in MQOpenQueue, error = 0x%x\n",hr);
     return -1;
  }

  puts("The queue is opened to read messages.");

  /////////////////////////////////////////////////////////////////
  // Add code to read messages in the queue.
  /////////////////////////////////////////////////////////////////

  /////////////////////////////////////////////////////////////////
  // Close the queue.
  /////////////////////////////////////////////////////////////////

  hr = MQCloseQueue(hQueue);

  if (FAILED(hr))
  {
     fprintf(stderr, "Failed in MQCloseQueue, error = 0x%x\n",hr);
     return -1;
  }

  puts("The queue is closed.");
  return 0;

}


Using a Queue Pathname to Open a Queue

To open a queue when only the pathname of the queue is known, MQPathNameToFormatName can be used to generate the format name required by MQOpenQueue.

As is the case when opening all queues, the queue's access mode and share mode are set when calling MQOpenQueue.

Note Before opening a queue, Message Queuing verifies that the access mode requested by the application does not conflict with the access rights of the queue. For example, a queue may restrict those who can retrieve messages from it.

For a discussion of queue access rights, see Access Control.

To open a queue using a known pathname

  1. Define the required structures. This includes the access mode and share mode of the queue.
  2. Call MQPathNameToFormatName to convert the known pathname to a format name for the queue.
  3. Call MQOpenQueue to open the queue. This example opens the queue with send access.
  4. Optional. Add code to send messages.
  5. Call MQCloseQueue to close the queue.
For a code example using | See
C++ | C/C++ Code Example


C/C++ Code Example: Using a Pathname to Open a Queue

This example generates a format name for the queue based on the queue's pathname, opens the queue with send access, waits for three seconds, and then closes the queue.

#include <windows.h>
#include <stdio.h>
#include <mq.h>                                       // Message Queuing header file

int main(int arg, char *argv[])

{
  ////////////////////////////////////////////////////////////
  //  Define structures for function calls.
  ////////////////////////////////////////////////////////////

  HRESULT hr;                                         // Define results
  QUEUEHANDLE hQueue;                                 // Handle of created queue
  DWORD dwAccess = MQ_SEND_ACCESS;                    // Access mode of queue
  DWORD dwShareMode = MQ_DENY_NONE;                   // Share Mode of queue
  DWORD dwFormatNameBufferLength = 256;               // Length of format name
  WCHAR wszFormatNameBuffer[256];                     // Format name buffer

  /////////////////////////////////////////////////////////////////
  // Convert Pathname to Format Name.
  /////////////////////////////////////////////////////////////////

  hr = MQPathNameToFormatName(L".\\TestQueue",
                              wszFormatNameBuffer,
                              &dwFormatNameBufferLength);
  if (FAILED(hr))
  {
    fprintf(stderr, "Failed in MQPathNameToFormatName, error = 0x%x\n",hr);
    return -1;
  }

  /////////////////////////////////////////////////////////////////
  // Open queue to send message.
  /////////////////////////////////////////////////////////////////

  hr = MQOpenQueue(wszFormatNameBuffer,     // Format name of queue
                   dwAccess,               // Access mode
                   dwShareMode,            // Share mode
                   &hQueue                 // OUT: Handle to queue
                   );
  if (FAILED(hr))
  {
     fprintf(stderr, "Failed in MQOpenQueue, error = 0x%x\n",hr);
     return -1;
  }

  puts("The queue is opened to send messages.");

  /////////////////////////////////////////////////////////////////
  // Add code to send messages to the queue.
  /////////////////////////////////////////////////////////////////

  /////////////////////////////////////////////////////////////////
  // Close the queue.
  /////////////////////////////////////////////////////////////////

  hr = MQCloseQueue(hQueue);

  if (FAILED(hr))
  {
     fprintf(stderr, "Failed in MQCloseQueue, error = 0x%x\n",hr);
     return -1;
  }

  puts("The queue is closed.");
  return 0;

}


Using a Queue Identifier to Open a Queue

To open a queue when only the identifier (GUID) of the queue is known, MQInstanceToFormatName can be used to generate the format name required by MQOpenQueue.

Note Message Queuing generates the queue identifier when the queue is created. It can be retrieved from a previous call to MQCreateQueue , or from a query when locating a public queue.

As is the case when opening all queues, the queue's access mode and share mode are set when calling MQOpenQueue.

Note Before opening a queue, Message Queuing verifies that the access mode requested by the application does not conflict with the access rights of the queue. For example, a queue may restrict those who can retrieve messages from it.

For a discussion of queue access rights, see Access Control.

To open a queue using a queue identifier

  1. Define the required structures. This includes a GUID structure for the queue identifier (GUID), the queue handle returned when the queue is opened, plus the access mode, share mode, and format name buffer used to open the queue.
  2. Call MQInstanceToFormatName to convert the queue identifier to a format name for the queue.
  3. Call MQOpenQueue to open the queue. This example opens the queue with send access.
  4. Optional. Add code to send messages.
  5. Call MQCloseQueue to close the queue.
For a code example using | See
C++ | C/C++ Code Example


C/C++ Code Example: Using a Queue Identifier to Open a Queue

This example generates a format name for the queue based on the queue's identifier, opens the queue with send access and then closes the queue.

#include <windows.h>
#include <stdio.h>
#include <mq.h>                                       // Message Queuing header file

int main(int arg, char *argv[])

{
  ////////////////////////////////////////////////////////////
  //  Define structures for function calls.
  ////////////////////////////////////////////////////////////

  HRESULT hr;                                         // Define results
  QUEUEHANDLE hQueue;                                 // Handle of queue
  DWORD dwAccess = MQ_SEND_ACCESS;                    // Access mode of queue
  DWORD dwShareMode = MQ_DENY_NONE;                   // Share Mode of queue
  DWORD dwFormatNameBufferLength = 256;               // Length of format name
  WCHAR wszFormatNameBuffer[256];                     // Format name buffer

  // Create GUID structure using known queue GUID
  static GUID qInstance =
  { 0x317c2229, 0xbcf0, 0x11d1, { 0xb1, 0x3b, 0x0, 0xaa, 0x0, 0x4a, 0xa1, 0x62 } };

  /////////////////////////////////////////////////////////////////
  // Convert GUID to Format Name.
  /////////////////////////////////////////////////////////////////

  hr = MQInstanceToFormatName(&qInstance,
                              wszFormatNameBuffer,
                              &dwFormatNameBufferLength);
  if (FAILED(hr))
  {
    fprintf(stderr, "Failed in MQInstanceToFormatName, error = 0x%x\n",hr);
    return -1;
  }
  /////////////////////////////////////////////////////////////////
  // Open queue to send message.
  /////////////////////////////////////////////////////////////////

  hr = MQOpenQueue(wszFormatNameBuffer,               // Format name of queue
                   dwAccess,                          // Access mode
                   dwShareMode,                       // Share mode
                   &hQueue                            // OUT: Handle to queue
                   );
  if (FAILED(hr))
  {
     fprintf(stderr, "Failed in MQOpenQueue, error = 0x%x\n",hr);
     return -1;
  }

  puts("The queue is opened to send messages.");

  /////////////////////////////////////////////////////////////////
  // Add code to send messages to the queue.
  /////////////////////////////////////////////////////////////////

  /////////////////////////////////////////////////////////////////
  // Close the queue.
  /////////////////////////////////////////////////////////////////

  hr = MQCloseQueue(hQueue);

  if (FAILED(hr))
  {
     fprintf(stderr, "Failed in MQCloseQueue, error = 0x%x\n",hr);
     return -1;
  }

  puts("The queue is closed.");
  return 0;

}


Using a Machine Identifier and Queue Number to Open a Private Queue

A private queue can be opened using the machine identifier (of the computer where the private queue is registered) and the queue number of the queue.

The machine identifier can be obtained by calling MQGetMachineProperties.

The queue number can be obtained from the names of the files stored in the Lqs folder (the Lqs folder is created when Message Queuing is installed).

To open a queue using a direct format name

  1. Obtain the queue number of the queue from the …/MSMQ/storage/Lqs folder. For example, the following file name includes the queue number 00000033.
    00000033.3559f71d
  2. Define the required structures needed to open the queue.
  3. Specify PROPID_QM_MACHINE_ID to obtain the computers machine identifier.
  4. Initialize the MQQMPROPS structure.
  5. Call MQGetMachineProperties to retrieve the machine identifier of the computer. The following example code retrieves the machine identifier of the local computer.
  6. Construct the format name of the private queue. The syntax of the format name used to open a private queue is shown below:
    "PRIVATE=MachineGUID\QueueNumber"
  7. Call MQOpenQueue to open the queue with send access.
  8. Optional. Add code to send messages to the queue.
  9. Call MQCloseQueue to close the queue.
For a code example using | See
C++ | C/C++ Code Example


C/C++ Code Example: Using a Queue Identifier to Open a Private Queue

Platform SDK: Message Queuing

C/C++ Code Example: Using a Machine Identifier and Queue Number to Open a Private Queue

The following example opens a private queue using the machine identifier and queue number. This example uses the RPC function UuidToString to construct the format of the private queue. The library and header files for this function are rpcrt4.lib and rpc.h respectively.

#include <windows.h>
#include <stdio.h>
#include <mq.h>                                       // Message Queuing header file
#include <rpc.h>                                      // Defines UuidToString

int main(int arg, char *argv[])

{
  ////////////////////////////////////////////////////////////
  //  Define the required structures.
  ////////////////////////////////////////////////////////////

  #define NUMBEROFPROPERTIES 1                        // Number of machine properties
  DWORD cPropId=0;                                    // Property counter

  MQQMPROPS qmprops;                                  // QM property structure
  QMPROPID aQMPropId[NUMBEROFPROPERTIES];             // Property Id array
  MQPROPVARIANT aQMPropVar[NUMBEROFPROPERTIES];        // Property value array
  HRESULT aQMStatus[NUMBEROFPROPERTIES];              // property status array

  HRESULT hr;                                         // Define results.
  QUEUEHANDLE hQueue;                                 // Handle of created queue.
  DWORD dwAccess = MQ_SEND_ACCESS;                    // Access mode of queue
  DWORD dwShareMode = MQ_DENY_NONE;                   // Share Mode of queue

  CLSID guidMachineId;                                // Machine ID buffer
  UCHAR *pszUuid = 0;                                 // Machine GUID string
  CHAR szFormatNameBuffer[256];                       // Format name buffer
  CHAR szQueueNumber [] = "\\00000033";               // Known queue number

  WCHAR wszFormatNameBuffer[256];                     // Wide format name buffer

  /////////////////////////////////////////////////////////////////
  // Specify PROPID_QM_MACHINE_ID.
  /////////////////////////////////////////////////////////////////

  aQMPropId[cPropId] = PROPID_QM_MACHINE_ID;          // Property identifier
  aQMPropVar[cPropId].vt = VT_CLSID;                  // type indicator
  aQMPropVar[cPropId].puuid = &guidMachineId;         // Machine ID buffer
  cPropId++;

  /////////////////////////////////////////////////////////////////
  // Initialize MQQMPROPS structure.
  /////////////////////////////////////////////////////////////////

  qmprops.cProp = cPropId;                            // Number of properties
  qmprops.aPropID = aQMPropId;                        // IDs of properties
  qmprops.aPropVar = aQMPropVar;                      // Value of properties
  qmprops.aStatus = aQMStatus;                        // Error reports

  /////////////////////////////////////////////////////////////////
  // Call MQGetMachineProperties to retrieve the machine
  // identifier of the computer where the queue is registered.
  /////////////////////////////////////////////////////////////////

  hr = MQGetMachineProperties(NULL,
                              NULL,
                              &qmprops);
  if (FAILED(hr))
  {
     fprintf(stderr, "Failed in MQGetMachineProperties, error = 0x%x\n",hr);
     return -1;
  }

  /////////////////////////////////////////////////////////////////
  // Construct format name of the private queue. The returned
  // machine GUID is translated into a string, and then combined
  // with the queue number.
  /////////////////////////////////////////////////////////////////

  if (UuidToString(&guidMachineId, &pszUuid) !=RPC_S_OK)
  {
     fprintf(stderr, "Failed in UuidToString.\n");
     return -1;
  }
  else
  {
    // Combine machine ID and queue number
    sprintf(szFormatNameBuffer,
            "PRIVATE=%s%s",
            pszUuid,
            szQueueNumber);

   // Convert format name to wide string
     mbstowcs(wszFormatNameBuffer,
             szFormatNameBuffer,
             sizeof(szFormatNameBuffer));
  RpcStringFree(&pszUuid);
  }

  /////////////////////////////////////////////////////////////////
  // Open the queue to send messages.
  /////////////////////////////////////////////////////////////////

  hr = MQOpenQueue(wszFormatNameBuffer,               // Format name of queue
                   dwAccess,                          // Access mode
                   dwShareMode,                       // Share mode
                   &hQueue                            // OUT: Handle to queue
                   );
  if (FAILED(hr))
  {
     fprintf(stderr, "Failed in MQOpenQueue, error = 0x%x\n",hr);
     return -1;
  }

  puts("The queue is opened to send messages.");

  /////////////////////////////////////////////////////////////////
  // Add code to send messages to the queue.
  /////////////////////////////////////////////////////////////////

  /////////////////////////////////////////////////////////////////
  // Close the queue.
  /////////////////////////////////////////////////////////////////

  hr = MQCloseQueue(hQueue);

  if (FAILED(hr))
  {
     fprintf(stderr, "Failed in MQCloseQueue, error = 0x%x\n",hr);
     return -1;
  }

  puts("The queue is closed.");
  return 0;

}


Opening a Queue with a Direct Format Name

To send or retrieve messages directly from a queue, the format name used to open the queue must be a direct format name. Direct format names use one of the following syntax:

DIRECT=AddressSpecification\QueueName           // For public queues.
DIRECT=AddressSpecification\PRIVATE$\QueueName  // For private queues.

Note Before opening a queue, Message Queuing verifies that the access mode requested by the application does not conflict with the access rights of the queue. For example, a queue may restrict those who can send messages to it.

For a discussion of queue access rights, see Access Control.

To open a queue using a direct format name

  1. Define the required structures, including specifying a direct format name for the queue.
  2. Call MQOpenQueue to open queue with send access.
  3. Optional. Add code to send message.
  4. Call MQCloseQueue to close the queue.
For a code example using | See
C++ | C/C++ Code Example


C/C++ Code Example: Opening a Queue Using a Direct Format Name

This example opens a known public queue using a direct format name. It opens the queue with send access, and then closes the queue.

#include <windows.h>
#include <stdio.h>
#include <mq.h>                              // Message Queuing header file

int main(int arg, char *argv[])

{
  ////////////////////////////////////////////////////////////
  //  Define the required structures.
  ////////////////////////////////////////////////////////////

  HRESULT hr;                                 // Define results
  QUEUEHANDLE hQueue;                         // Handle of queue
  DWORD dwAccess = MQ_SEND_ACCESS;            // Access mode of queue
  DWORD dwShareMode = MQ_DENY_NONE;           // Share Mode of queue

  //Direct format name for queue
  LPWSTR FormatName=L"DIRECT=OS:stevenel1\\testqueue";

  /////////////////////////////////////////////////////////////////
  // Open queue to send message.
  /////////////////////////////////////////////////////////////////

  hr = MQOpenQueue(FormatName,             // Format name of queue
                   dwAccess,               // Access mode
                   dwShareMode,            // Share mode
                   &hQueue                 // OUT: Handle to queue
                   );
  if (FAILED(hr))
  {
     fprintf(stderr, "Failed in MQOpenQueue, error = 0x%x\n",hr);
     return -1;
  }

  puts("The queue is opened to send messages.");

  /////////////////////////////////////////////////////////////////
  // Add code to send messages to the queue.
  /////////////////////////////////////////////////////////////////

  /////////////////////////////////////////////////////////////////
  // Close the queue.
  /////////////////////////////////////////////////////////////////

  hr = MQCloseQueue(hQueue);

  if (FAILED(hr))
  {
     fprintf(stderr, "Failed in MQCloseQueue, error = 0x%x\n",hr);
     return -1;
  }

  puts("The queue is closed.");
  return 0;

}


Opening the Queue Journal of a Public Queue

A queue journal can only be opened with receive or peek access. (You cannot send messages to a queue journal.)

To open the queue journal of a public queue, the format name supplied to MQOpenQueue must be in the following syntax:

PUBLIC=QueueGUID;JOURNAL

Note MSMQ 1.0 does not allow you to open a queue journal using a direct format name.

To open the queue journal of a public queue

  1. Define the required structures.
  2. Call MQPathNameToFormatName to generate a format name for the public queue. The returned format name is used to construct the format name for the queue journal.
  3. Construct the format name for the queue journal by adding ";JOURNAL" to the end of the format name returned by MQPathNameToFormatName.
  4. Call MQOpenQueue to open queue with receive access.
  5. Optional. Add code to read the messages in the queue.
  6. Call MQCloseQueue to close the queue.
For a code example using | See
C++ | C/C++ Code Example


C/C++ Code Example: Opening the Queue Journal of a Public Queue

This example opens the queue journal of a known public queue. It opens the queue journal with receive access and then closes the queue.

#include <windows.h>
#include <stdio.h>
#include <mq.h>                // Message Queuing header file
#include <string.h>            // Defines wcscat

int main(int arg, char *argv[])

{
  ////////////////////////////////////////////////////////////
  //  Define the required structures.
  ////////////////////////////////////////////////////////////

  HRESULT hr;                                 // Define results
  QUEUEHANDLE hQueue;                         // Handle of queue
  DWORD dwAccess = MQ_RECEIVE_ACCESS;         // Access mode of queue
  DWORD dwShareMode = MQ_DENY_RECEIVE_SHARE;  // Share Mode of queue
  DWORD dwFormatNameBufferLength = 256;       // Length of format name
  WCHAR wszFormatNameBuffer[256];             // Format name buffer

  /////////////////////////////////////////////////////////////////
  // Generate the destination queue's format name using
  // MQPathNameToFormatName.
  /////////////////////////////////////////////////////////////////

  hr = MQPathNameToFormatName(L".\\TestQueue",
                              wszFormatNameBuffer,
                              &dwFormatNameBufferLength);
  if (FAILED(hr))
  {
    fprintf(stderr, "Failed in MQPathNameToFormatName, error = 0x%x\n",hr);
    return -1;
  }

  /////////////////////////////////////////////////////////////////
  // Generate the queue journal's format name by appending
  // ";JOURNAL" to the destination queue's format name.
  /////////////////////////////////////////////////////////////////

  wcscat(wszFormatNameBuffer, L";JOURNAL");

  /////////////////////////////////////////////////////////////////
  // Open queue journal to retrieve message.
  /////////////////////////////////////////////////////////////////

  hr = MQOpenQueue(wszFormatNameBuffer,     // Format name of queue
                   dwAccess,               // Access mode
                   dwShareMode,            // Share mode
                   &hQueue                 // Handle to queue
                   );
  if (FAILED(hr))
  {
     fprintf(stderr, "Failed in MQOpenQueue, error = 0x%x\n",hr);
     return -1;
  }

  puts("The queue is opened to read messages.");

  /////////////////////////////////////////////////////////////////
  // Close the queue.
  /////////////////////////////////////////////////////////////////

  hr = MQCloseQueue(hQueue);

  if (FAILED(hr))
  {
     fprintf(stderr, "Failed in MQCloseQueue, error = 0x%x\n",hr);
     return -1;
  }

  puts("The queue is closed.");
  return 0;

}


Opening the Queue Journal of a Private Queue

A queue journal can only be opened with receive or peek access. (You cannot send messages to a queue journal.)

To open this queue, the format name supplied to MQOpenQueue must be in the following syntax:

PRIVATE=MachineGUID\QueueNumber;JOURNAL

Note MSMQ 1.0 does not allow you to open a queue journal using a direct format name.

This example uses MQPathNameToFormatName to retrieve a format name for the private queue. The returned format name includes the machine identifier where the queue is located (machine GUID) and the number of the queue (queue number).

To open the queue journal of a private queue

  1. Define the required structures.
  2. Call MQPathNameToFormatName to generate a format name for the private queue. The returned format name of the queue is used to construct the format name for the queue journal.
  3. Construct the format name for the queue journal by adding ";JOURNAL" to the end of the format name returned by MQPathNameToFormatName.
  4. Call MQOpenQueue to open queue with receive or peek access.
  5. Optional. Add code to read the messages in the queue.
  6. Call MQCloseQueue to close the queue.
For a code example using | See
C++ | C/C++ Code Example


C/C++ Code Example: Opening the Queue Journal of a Private Queue

This example opens the queue journal of a known private queue. It opens the queue journal with receive access and then closes the queue.

#include <windows.h>
#include <stdio.h>
#include <mq.h>                // Message Queuing header file
#include <string.h>            // Defines wcscat

int main(int arg, char *argv[])

{
  ////////////////////////////////////////////////////////////
  //  Define the required structures.
  ////////////////////////////////////////////////////////////

  HRESULT hr;                                 // Define results
  QUEUEHANDLE hQueue;                         // Handle of queue
  DWORD dwAccess = MQ_RECEIVE_ACCESS;         // Access mode of queue
  DWORD dwShareMode = MQ_DENY_RECEIVE_SHARE ; // Share Mode of queue
  DWORD dwFormatNameBufferLength = 256;       // Length of format name
  WCHAR wszFormatNameBuffer[256];             // Format name buffer

  /////////////////////////////////////////////////////////////////
  // Generate the destination queue's format name using
  // MQPathNameToFormatName.
  /////////////////////////////////////////////////////////////////

  hr = MQPathNameToFormatName(L".\\PRIVATE$\\TestQueue",
                              wszFormatNameBuffer,
                              &dwFormatNameBufferLength);
  if (FAILED(hr))
  {
    fprintf(stderr, "Failed in MQPathNameToFormatName, error = 0x%x\n",hr);
    return -1;
  }

  /////////////////////////////////////////////////////////////////
  // Generate the queue journal's format name by appending
  // ";JOURNAL" to the destination queue's format name.
  /////////////////////////////////////////////////////////////////

  wcscat(wszFormatNameBuffer, L";JOURNAL");

  /////////////////////////////////////////////////////////////////
  // Open queue journal to retrieve message.
  /////////////////////////////////////////////////////////////////

  hr = MQOpenQueue(wszFormatNameBuffer,    // Format name of queue
                   dwAccess,               // Access mode
                   dwShareMode,            // Share mode
                   &hQueue                 // Handle to queue
                   );
  if (FAILED(hr))
  {
     fprintf(stderr, "Failed in MQOpenQueue, error = 0x%x\n",hr);
     return -1;
  }

  puts("The queue is opened to read messages.");

  /////////////////////////////////////////////////////////////////
  // Close the queue.
  /////////////////////////////////////////////////////////////////

  hr = MQCloseQueue(hQueue);

  if (FAILED(hr))
  {
     fprintf(stderr, "Failed in MQCloseQueue, error = 0x%x\n",hr);
     return -1;
  }

  puts("The queue is closed.");
  return 0;

}


Opening a Computer's Computer Journal Queue

A computer's computer journal queue can only be opened with receive or peek access. (You cannot send messages to a computer journal queue.)

To open this queue, the format name supplied to MQOpenQueue must be in the following syntax:

MACHINE=MachineGUID;JOURNAL

This example uses MQGetMachineProperties to retrieve the identifier used in machine GUID.

To open the computer journal queue

  1. Define the required structures.
  2. Specify PROPID_QM_MACHINE_ID to retrieve the machine identifier (GUID) of the local computer.
  3. Initialize the MQQMPROPS structure.
  4. Call MQGetMachineProperties to retrieve the identifier (GUID) of the machine.
  5. Construct the format name for the computer journal. The returned machine GUID is translated into a string, combined with "MACHINE=" and ";JOURNAL", then translated into a wide string.
  6. Call MQOpenQueue to open the computer journal queue.
  7. Call MQCloseQueue to close the queue.
For a code example using | See
C++ | C/C++ Code Example


C/C++ Code Example: Opening the Computer Journal of a Computer

This example opens the computer journal of the local computer. The computer journal is opened with receive access and then closed. This example uses the RPC function UuidToString to construct the format of the computer journal. The library and header files for this function are rpcrt4.lib and rpc.h respectively.

#include <windows.h>
#include <stdio.h>
#include <mq.h>                // Message Queuing header file
#include <rpc.h>               // Defines UuidToString and RpcStringFree

int main(int arg, char *argv[])

{
  ////////////////////////////////////////////////////////////
  //  Define the required structures.
  ////////////////////////////////////////////////////////////

  #define NUMBEROFPROPERTIES 1                   // Number of QM properties
  DWORD cPropId=0;                               // Property counter

  MQQMPROPS qmprops;
  QMPROPID aQMPropId[NUMBEROFPROPERTIES];        // Property ID array
  MQPROPVARIANT aQMPropVar[NUMBEROFPROPERTIES];  // Property value array
  HRESULT aQMStatus[NUMBEROFPROPERTIES];         // Property status array

  HRESULT hr;                                 // Define results
  QUEUEHANDLE hQueue;                         // Handle of queue
  DWORD dwAccess = MQ_RECEIVE_ACCESS;         // Access mode of queue
  DWORD dwShareMode = MQ_DENY_RECEIVE_SHARE ; // Share Mode of queue
  WCHAR wszFormatNameBuffer[256];             // Format name buffer

  //Buffers and string for translating Machine GUID
  CLSID guidMachineId;                      // Buffer for Machine GUID
  CHAR  szFormatNameBuffer[256];            // Format name buffer
  UCHAR *pszUuid = 0;                       // String GUID

  /////////////////////////////////////////////////////////////////
  // Specify Machine ID property
  /////////////////////////////////////////////////////////////////

  aQMPropId[cPropId] = PROPID_QM_MACHINE_ID;     // Property ID
  aQMPropVar[cPropId].vt = VT_CLSID;             // Type indicator
  aQMPropVar[cPropId].puuid = &guidMachineId;    // GUID buffer
  cPropId++;

  /////////////////////////////////////////////////////////////////
  // Initialize MQQMPROPS structure.
  /////////////////////////////////////////////////////////////////

  qmprops.cProp = cPropId;                     // Number of properties
  qmprops.aPropID = aQMPropId;                 // IDs of properties
  qmprops.aPropVar = aQMPropVar;               // Values of properties
  qmprops.aStatus = aQMStatus;                 // Error reports

  /////////////////////////////////////////////////////////////////
  // Retrieve the machine's GUID.
  /////////////////////////////////////////////////////////////////

  hr = MQGetMachineProperties(NULL,
                              NULL,
                              &qmprops);
  if (FAILED(hr))
  {
     fprintf(stderr, "Failed in MQGetMachineProperties, error = 0x%x\n",hr);
     return -1;
  }

  /////////////////////////////////////////////////////////////////
  // Construct the format name for the computer journal. The returned
  // machine GUID is translated into a string, and then combined
  // with ";JOURNAL".
  /////////////////////////////////////////////////////////////////

  if(UuidToString(&guidMachineId, &pszUuid) != RPC_S_OK)
  {
     fprintf(stderr, "Failed in UuidToString.\n");
     return -1;
  }
  else
  {
     //Combine parts of format name
     sprintf( szFormatNameBuffer,
              "MACHINE=%s%s",
              pszUuid,
              ";JOURNAL" );

     //translate to wide string.
     mbstowcs(wszFormatNameBuffer,
              szFormatNameBuffer,
              sizeof(szFormatNameBuffer));
     RpcStringFree(&pszUuid);
  }

  /////////////////////////////////////////////////////////////////
  // Open computer journal to retrieve message.
  /////////////////////////////////////////////////////////////////

  hr = MQOpenQueue(wszFormatNameBuffer,    // Format name of queue
                   dwAccess,               // Access mode
                   dwShareMode,            // Share mode
                   &hQueue                 // OUT: Handle to queue
                   );
  if (FAILED(hr))
  {
     fprintf(stderr, "Failed in MQOpenQueue, error = 0x%x\n",hr);
     return -1;
  }

  puts("The queue is opened to read messages.");

  /////////////////////////////////////////////////////////////////
  // Close the queue.
  /////////////////////////////////////////////////////////////////

  hr = MQCloseQueue(hQueue);

  if (FAILED(hr))
  {
     fprintf(stderr, "Failed in MQCloseQueue, error = 0x%x\n",hr);
     return -1;
  }

  puts("The queue is closed.");
  return 0;
}


Deleting a Queue

A queue is deleted with a single call to MQDeleteQueue.

To delete a public queue, the application must have a connection to the directory service.

To delete a private queue, the queue must be registered on the local computer. Only local private queues can be deleted.

To delete a queue

  1. Obtain the format name of the queue. It is returned by MQCreateQueue when the queue is created. If you do not know the format name of the queue, you can obtain a format name by using one of the following format name translation functions:

    MQHandleToFormatName

    MQInstanceToFormatName

    MQPathNameToFormatName

  2. Call MQDeleteQueue to delete the queue.
For a code example using | See
C++ | C/C++ Code Example


C/C++ Code Example: Deleting a Queue

The following example deletes the queue.

/////////////////
// Delete queue.
/////////////////
hr = MQDeleteQueue(szwFormatName);

if (FAILED(hr))
{
   // MQDeleteQueue error handler.
}


Sending Messages to a Queue

Sending messages is typically a three-function operation: a single call to MQOpenQueue to open the queue, one or more calls to MQSendMessage, and a single call to MQCloseQueue to close the queue. While the queue is open, the application can send any number of messages to the queue.

Messages are defined by the properties specified in the MQMSGPROPS structure associated with the message. This structure provides the number of properties that will be sent with the message, identifiers for each property, and the value of each property. Message Queuing uses default values for any properties not specified in this structure.

For an example of | See
Send a message to a queue | Sending a Typical Message
Sending a message that requests an acknowledgment from Message Queuing | Requesting Acknowledgment Messages
Sending a message the requests a response message from the receiving application. | Requesting Response Messages
Sending a response message to a response queue | Sending Response Messages
Sending messages within an explicit internal transaction | Sending Messages Using an Internal Transaction
Sending a single message within an implicit internal transaction | Sending a Single-message Transaction
Sending messages with different delivery modes | Sending Express and Recoverable Messages


Sending a Typical Message

Sending messages includes specifying the properties of the message in an MQMSGPROPS structure, opening the destination queue with send access, sending one or more messages to the queue, and then closing the queue. The following example sends a single message to a known destination queue.

Note Each Message Queuing message can have no more than 4 MB of data.

To send a message

  1. Define the structures needed to send the message.
  2. Specify the properties of the message. This example only sets the body of the message. Add additional message properties as needed.
  3. Initialize the MQMSGPROPS structure.
  4. Generate a format name for the queue. This example calls MQPathNameToFormatName to convert a known pathname to a format name.
  5. Call MQOpenQueue to open the destination queue with send access.
  6. Call MQSendMessage to send the message to the destination queue.
  7. Call MQCloseQueue to close the destination queue.
For a code example using | See
C++ | C/C++ Code Example


C/C++ Code Example: Sending Messages to a Queue

This example sends a message to a known public queue. It uses a known pathname for the queue to generate a format name, then opens the queue, sends the message, and closes the queue.

#include <windows.h>
#include <stdio.h>
#include <mq.h>                              // Message Queuing header file

int main(int arg, char *argv[])

{
  ////////////////////////////////////////////////////////////
  //  Define the required structures.
  ////////////////////////////////////////////////////////////

  #define NUMBEROFPROPERTIES 1                // Number of properties
  DWORD cPropId = 0;             // Property counter

  MQMSGPROPS msgprops;
  MSGPROPID aMsgPropId[NUMBEROFPROPERTIES];
  MQPROPVARIANT aMsgPropVar[NUMBEROFPROPERTIES];
  HRESULT aMsgStatus[NUMBEROFPROPERTIES];

  HANDLE hQueue;                             // Queue handle
  HRESULT hr;                                // Define results
  DWORD dwAccessMode = MQ_SEND_ACCESS;       // Access mode of queue
  DWORD dwShareMode = MQ_DENY_NONE;          // Share Mode of queue

  DWORD dwDestFormatNameBufferLength = 256;
  WCHAR wszDestFormatNameBuffer[256];

  //Body of message
  WCHAR wszMessageBody[] = L"Test Message.";

  /////////////////////////////////////////////////////////////////
  // Specify PROPID_M_BODY.
  /////////////////////////////////////////////////////////////////

  aMsgPropId[cPropId] = PROPID_M_BODY;
  aMsgPropVar[cPropId].vt = VT_VECTOR | VT_UI1;
  aMsgPropVar[cPropId].caub.pElems = (LPBYTE)wszMessageBody;
  aMsgPropVar[cPropId].caub.cElems = sizeof(wszMessageBody);
  cPropId++;

  /////////////////////////////////////////////////////////////////
  // Add additional message properties here. When adding
  // properties, increment cProp to reflect total
  // number of message properties specified.
  /////////////////////////////////////////////////////////////////

  /////////////////////////////////////////////////////////////////
  // Initialize the MQMSGPROPS structure.
  /////////////////////////////////////////////////////////////////

  msgprops.cProp = cPropId;             // Number of properties
  msgprops.aPropID = aMsgPropId;        // Ids of properties
  msgprops.aPropVar = aMsgPropVar;      // Values of properties
  msgprops.aStatus  = aMsgStatus;       // Error reports

  /////////////////////////////////////////////////////////////////
  // Convert destination queue pathname to a format name.
  /////////////////////////////////////////////////////////////////

  hr = MQPathNameToFormatName(L".\\TestQueue",
                              wszDestFormatNameBuffer,
                              &dwDestFormatNameBufferLength);
  if (FAILED(hr))
  {
     fprintf(stderr, "Failed in MQPathNameToFormatName for destination queue, error = 0x%x\n",hr);
     return -1;
  }

  /////////////////////////////////////////////////////////////////
  // Open the destination queue to send message.
  /////////////////////////////////////////////////////////////////

  hr = MQOpenQueue(wszDestFormatNameBuffer, // Format name of queue
                   dwAccessMode,           // Access mode
                   dwShareMode,            // Share mode
                   &hQueue                 // OUT: Handle to queue
                   );
  if (FAILED(hr))
  {
     fprintf(stderr, "Failed opening destination queue, error = 0x%x\n",hr);
     return -1;
  }

  /////////////////////////////////////////////////////////////////
  // Send message to the destination queue.
  /////////////////////////////////////////////////////////////////

  hr = MQSendMessage(hQueue,              // Handle of open queue
                     &msgprops,           // Properties of message
                     NULL);               // No transaction

  if (FAILED(hr))
  {
     fprintf(stderr, "Failed sending message, error = 0x%x\n",hr);
     return -1;
  }

  /////////////////////////////////////////////////////////////////
  // Close the queue.
  /////////////////////////////////////////////////////////////////

  hr = MQCloseQueue(hQueue);

  if (FAILED(hr))
  {
     fprintf(stderr, "Failed closing destination queue, error = 0x%x\n",hr);
     return -1;
  }

  puts("The message is sent and the queue is closed.");
  return 0;

}


Requesting Acknowledgment Messages

To request acknowledgment messages, the sending application must indicate the acknowledgment level of the message and the administration queue where the acknowledgment message will be placed.

Acknowledgment messages are returned to the administration queue specified by PROPID_M_ADMIN_QUEUE.

Note Each Message Queuing message can have no more than 4 MB of data.

To request an acknowledgment message

  1. Define the structures needed to send the message.
  2. Set PROPID_M_ADMIN_QUEUE and PROPID_M_ACKNOWLEDGE. PROPID_M_ADMIN_QUEUE specifies the administration queue and PROPID_M_ACKNOWLEDGE specifies the acknowledgment level needed. The example below calls MQPathNameToFormatName to generate a format name for the administration queue.
  3. Optional. Specify additional message properties. The example below specifies a message body and the time-to-be-received timer. If the message is not removed from the destination queue before the timer expires, Message Queuing sends a negative acknowledgment message to the administration queue and the original message is removed from the destination queue.
  4. Initialize the MQMSGPROPS structure.
  5. Generate a format name for the destination queue. the example below calls MQPathNameToFormatName to convert the known pathname to a format name.
  6. Call MQOpenQueue to open the queue with send access.
  7. Call MQSendMessage to send the message. In the example below, if the message is removed from the queue within 3 minutes a positive acknowledgment is returned to the administration queue. If the message is not removed within 3 minutes, a negative acknowledgment is returned.
  8. Call MQCloseQueue to close the destination queue.
For a code example using | See
C++ | C/C++ Code Example


C/C++ Code Example: Requesting Acknowledgment Messages

This example uses a known destination queue and administration queue. A single message is sent to the destination queue requesting an acknowledgment message from Message Queuing. The acknowledge message indicates if the message was retrieved from the queue within three minutes. It is returned to the administration queue specified in the original message.

#include <windows.h>
#include <stdio.h>
#include <mq.h>                              // Message Queuing header file

int main(int arg, char *argv[])

{
  ////////////////////////////////////////////////////////////
  //  Define the required structures.
  ////////////////////////////////////////////////////////////

  #define NUMBEROFPROPERTIES  4               // Number of properties
  DWORD cPropId = 0;             // Property counter

  //Define MQMSGPROPS structure.
  MQMSGPROPS msgprops;
  MSGPROPID aMsgPropId[NUMBEROFPROPERTIES];
  MQPROPVARIANT aMsgPropVar[NUMBEROFPROPERTIES];
  HRESULT aMsgStatus[NUMBEROFPROPERTIES];

  // Queue handle and results
  HANDLE hQueue;                     // Queue handle
  HRESULT hr;                        // Define results

  // Access and share mode of destination queue
  DWORD dwAccessMode = MQ_SEND_ACCESS;       // Access mode of queue
  DWORD dwShareMode = MQ_DENY_NONE;          // Share Mode of queue

  // Format name buffer of destination queue
  DWORD dwDestFormatNameBufferLength = 256;
  WCHAR wszDestFormatNameBuffer[256];

  // Format name buffer of administration queue
  DWORD dwAdminFormatNameBufferLength = 256;
  WCHAR wszAdminFormatNameBuffer[256];

  //Body of message
  WCHAR wszMessageBody[] = L"Requesting acknowledgment please.";

  /////////////////////////////////////////////////////////////////
  // Set administration queue property of message and
  // acknowledgment level. Convert administration queue
  // pathname to a format name and set PROPID_M_ADMIN_QUEUE.
  // Set PROPID_M_ACKNOWLEDGE to the acknowledgment level needed.
  /////////////////////////////////////////////////////////////////

  hr = MQPathNameToFormatName(L".\\AdminQueue",
                              wszAdminFormatNameBuffer,
                              &dwAdminFormatNameBufferLength);
  if (FAILED(hr))
  {
     fprintf(stderr, "Failed in MQPathNameToFormatName for administration queue, error = 0x%x\n",hr);
     return -1;
  }

  aMsgPropId[cPropId] = PROPID_M_ADMIN_QUEUE;   // Property ID
  aMsgPropVar[cPropId].vt = VT_LPWSTR;          // Type indicator
  aMsgPropVar[cPropId].pwszVal = wszAdminFormatNameBuffer;
  cPropId++;

  aMsgPropId[cPropId] = PROPID_M_ACKNOWLEDGE;   // Property ID
  aMsgPropVar[cPropId].vt = VT_UI1;             // Type indicator
  aMsgPropVar[cPropId].bVal = MQMSG_ACKNOWLEDGMENT_FULL_RECEIVE;
  cPropId++;

  /////////////////////////////////////////////////////////////////
  // Add additional message properties here. This example includes
  // the body of the message (PROPID_M_BODY) and the
  // time-to-receive timer (PROPID_M_TIME_TO_BE_RECEIVED).
  // When adding properties, increment cProp to
  // reflect the total number of message properties specified.
  /////////////////////////////////////////////////////////////////

  aMsgPropId[cPropId] = PROPID_M_BODY;
  aMsgPropVar[cPropId].vt = VT_VECTOR | VT_UI1;
  aMsgPropVar[cPropId].caub.pElems = (LPBYTE)wszMessageBody;
  aMsgPropVar[cPropId].caub.cElems = sizeof(wszMessageBody);
  cPropId++;

  aMsgPropId[cPropId] = PROPID_M_TIME_TO_BE_RECEIVED;
  aMsgPropVar[cPropId].vt = VT_UI4;
  aMsgPropVar[cPropId].ulVal = 60*3;
  cPropId++;

  /////////////////////////////////////////////////////////////////
  // Initialize the MQMSGPROPS structure.
  /////////////////////////////////////////////////////////////////

  msgprops.cProp = cPropId;            //Number of message properties
  msgprops.aPropID = aMsgPropId;       //Ids of message properties
  msgprops.aPropVar = aMsgPropVar;     //Values of message properties
  msgprops.aStatus  = aMsgStatus;      //Error reports

  /////////////////////////////////////////////////////////////////
  // Convert destination queue pathname to a format name.
  /////////////////////////////////////////////////////////////////

  hr = MQPathNameToFormatName(L".\\TestQueue",
                              wszDestFormatNameBuffer,
                              &dwDestFormatNameBufferLength);
  if (FAILED(hr))
  {
     fprintf(stderr, "Failed in MQPathNameToFormatName for destination queue, error = 0x%x\n",hr);
     return -1;
  }

  /////////////////////////////////////////////////////////////////
  // Open the destination queue to send message.
  /////////////////////////////////////////////////////////////////

  hr = MQOpenQueue(wszDestFormatNameBuffer,  // Format name of queue
                   dwAccessMode,             // Access mode
                   dwShareMode,              // Share mode
                   &hQueue                   // OUT: Handle to queue
                   );
  if (FAILED(hr))
  {
     fprintf(stderr, "Failed opening destination queue, error = 0x%x\n",hr);
     return -1;
  }

  /////////////////////////////////////////////////////////////////
  // Send message to the destination queue.
  /////////////////////////////////////////////////////////////////

  hr = MQSendMessage(hQueue,
                     &msgprops,
                     NULL);
  if (FAILED(hr))
  {
     fprintf(stderr, "Failed sending message, error = 0x%x\n",hr);
     return -1;
  }

  /////////////////////////////////////////////////////////////////
  // Close the queue.
  /////////////////////////////////////////////////////////////////

  hr = MQCloseQueue(hQueue);

  if (FAILED(hr))
  {
     fprintf(stderr, "Failed closing destination queue, error = 0x%x\n",hr);
     return -1;
  }

  puts("The message is sent and the queue is closed.");
  return 0;

}


Requesting Response Messages

To request a response message, the sending application must include a format name for the response queue when it sends the original message. Response messages are application-defined and generated by the application reading the original message.

Note Each Message Queuing message can have no more than 4 MB of data.

To request a response message

  1. Define the structures needed to send the message. These include a format name buffer for the destination queue and response queue.
  2. Generate a format name for the response queue and set PROPID_M_RESP_QUEUE.
  3. Optional. Set other message properties as needed. The following example sets the body of the message.
  4. Initialize the MQMSGPROPS structure.
  5. Generate a format name for the destination queue. The following example calls MQPathNameToFormatName to convert a know pathname to a format name.
  6. Call MQOpenQueue to open the queue with send access.
  7. Call MQSendMessage to send the message to the queue.
  8. Call MQCloseQueue to close the queue.
For a code example using | See
C++ | C/C++ Code Example


C/C++ Code Example: Requesting Response Messages

The following example sends a message to a known destination queue. The PROPID_M_RESP_QUEUE property of the message is set to the format name of a response queue.

#include <windows.h>
#include <stdio.h>
#include <mq.h>                              // Message Queuing header file

int main(int arg, char *argv[])

{
  ////////////////////////////////////////////////////////////
  //  Define the required structures.
  ////////////////////////////////////////////////////////////

  #define NUMBEROFPROPERTIES 2                // Number of properties
  DWORD cPropId = 0;                          // Property counter

  MQMSGPROPS msgprops;
  MSGPROPID aMsgPropId[NUMBEROFPROPERTIES];
  MQPROPVARIANT aMsgPropVar[NUMBEROFPROPERTIES];
  HRESULT aMsgStatus[NUMBEROFPROPERTIES];

  HANDLE hQueue;                              // Queue handle
  HRESULT hr;                                 // Define results
  DWORD dwAccess = MQ_SEND_ACCESS;            // Access mode of queue
  DWORD dwShareMode = MQ_DENY_NONE;           // Share Mode of queue

  DWORD dwDestFormatNameBufferLength = 256;
  WCHAR wszDestFormatNameBuffer[256];

  DWORD dwRespFormatNameBufferLength = 256;
  WCHAR szRespFormatNameBuffer[256];

  WCHAR wszMessageBody[] = L"Requesting response please.";

  /////////////////////////////////////////////////////////////////
  // Set response queue property of message. Convert response
  // queue pathname to a format name and then set
  // PROPID_M_RESP_QUEUE.
  /////////////////////////////////////////////////////////////////

  hr = MQPathNameToFormatName(L".\\ResponseQueue",
                              szRespFormatNameBuffer,
                              &dwRespFormatNameBufferLength);
  if (FAILED(hr))
  {
     fprintf(stderr, "Failed in MQPathNameToFormatName for response queue, error = 0x%x\n",hr);
     return -1;
  }

  aMsgPropId[cPropId] = PROPID_M_RESP_QUEUE;     // Property ID
  aMsgPropVar[cPropId].vt = VT_LPWSTR;           // Type indicator
  aMsgPropVar[cPropId].pwszVal = szRespFormatNameBuffer;
  cPropId++;

  /////////////////////////////////////////////////////////////////
  // Add additional message properties here. This example sets
  // the body of the message (PROPID_M_BODY).
  /////////////////////////////////////////////////////////////////

  aMsgPropId[cPropId] = PROPID_M_BODY;
  aMsgPropVar[cPropId].vt = VT_VECTOR | VT_UI1;
  aMsgPropVar[cPropId].caub.pElems = (LPBYTE)wszMessageBody;
  aMsgPropVar[cPropId].caub.cElems = sizeof(wszMessageBody);
  cPropId++;

  /////////////////////////////////////////////////////////////////
  // Initialize the MQMSGPROPS structure.
  /////////////////////////////////////////////////////////////////

  msgprops.cProp = cPropId;           // Number of message properties
  msgprops.aPropID = aMsgPropId;      // Ids of message properties
  msgprops.aPropVar = aMsgPropVar;    // Values of message properties
  msgprops.aStatus  = aMsgStatus;     // Error reports

  /////////////////////////////////////////////////////////////////
  // Convert destination queue pathname to a format name.
  /////////////////////////////////////////////////////////////////

  hr = MQPathNameToFormatName(L".\\TestQueue",
                              wszDestFormatNameBuffer,
                              &dwDestFormatNameBufferLength);
  if (FAILED(hr))
  {
     fprintf(stderr, "Failed in MQPathNameToFormatName for destination queue, error = 0x%x\n",hr);
     return -1;
  }

  /////////////////////////////////////////////////////////////////
  // Open the destination queue to send message.
  /////////////////////////////////////////////////////////////////

  hr = MQOpenQueue(wszDestFormatNameBuffer, // Format name of queue
                   dwAccess,               // Access mode
                   dwShareMode,            // Share mode
                   &hQueue                 // OUT: Handle to queue
                   );
  if (FAILED(hr))
  {
     fprintf(stderr, "Failed in MQOpenQueue, error = 0x%x\n",hr);
     return -1;
  }

  /////////////////////////////////////////////////////////////////
  // Send message to the destination queue.
  /////////////////////////////////////////////////////////////////

  hr = MQSendMessage(hQueue,
                     &msgprops,
                     NULL);

  if (FAILED(hr))
  {
      fprintf(stderr, "Failed in MQSendMessage, error = 0x%x\n",hr);
      return -1;
  }

  /////////////////////////////////////////////////////////////////
  // Close the queue.
  /////////////////////////////////////////////////////////////////

  hr = MQCloseQueue(hQueue);

  if (FAILED(hr))
  {
      fprintf(stderr, "Failed in MQCloseQueue, error = 0x%x\n",hr);
      return -1;
   }

   puts("The message is sent and the queue is closed.");
   return 0;

}


Requesting Report Messages

To request report messages, the requesting application must specify a report queue and enable tracing. Once a message has been sent with tracing enabled, you can use Active Directory Manager to view the report messages Message Queuing sent to the report queue.

Report queues are typically specified by the Message Queuing Administrator by means of Active Directory Manager. You can select a known report queue, or specify a new queue. If you specify a new queue, Active Directory Manager creates the queue for you.

Note Report queues are typically created by means of Active Directory Manager. If you want to create a report queue using MQCreateQueue, be sure to specify the following queue type (GUID) when you create the queue.

{55EE8F32-CCE9-11CF-B108-0020AFD61CE9}

To enable tracing

  1. Using Active Directory Manager, make sure a report queue has been specified.
  2. In your application, define the structures needed to send the message.
  3. Specify PROPID_M_TRACE, setting it to MQMSG_SEND_ROUTE_TO_REPORT_QUEUE.
  4. Optional. Specify other message properties as needed.
  5. Initialize the MQMSGPROPS structure for the message.
  6. Generate a format name for the destination queue. The following example calls MQPathNameToFormatName to convert a known pathname to a format name.
  7. Call MQOpenQueue to open the destination queue with send access.
  8. Call MQSendMessage to send the message.
  9. Call MQCloseQueue to close the destination queue.
For a code example using | See
C++ | C/C++ Code Example


C/C++ Code Example: Requesting Report Messages

The following example sends a single message with tracing enabled.

#include <windows.h>
#include <stdio.h>
#include <mq.h>                              // Message Queuing header file

int main(int arg, char *argv[])

{
  ////////////////////////////////////////////////////////////
  //  Define the required structures.
  ////////////////////////////////////////////////////////////

  #define NUMBEROFPROPERTIES 3       // Number of properties
  DWORD cPropId = 0;                 // Property counter

  //Define MQMSGPROPS structure.
  MQMSGPROPS msgprops;
  MSGPROPID aMsgPropId[NUMBEROFPROPERTIES];
  MQPROPVARIANT aMsgPropVar[NUMBEROFPROPERTIES];
  HRESULT aMsgStatus[NUMBEROFPROPERTIES];

  HANDLE hQueue;                                      // Queue handle
  HRESULT hr;                                         // Define results.
  DWORD dwAccess = MQ_SEND_ACCESS;                    // Access mode of queue
  DWORD dwShareMode = MQ_DENY_NONE;                   // Share mode of queue

  //Destination queue format name buffer
  DWORD dwDestFormatNameBufferLength = 256;
  WCHAR szDestFormatNameBuffer[256];

  //Body of message
  WCHAR wszMessageBody[] = L"Test Message.";

  /////////////////////////////////////////////////////////////////
  // Specify PROPID_M_TRACE to enable tracing.
  /////////////////////////////////////////////////////////////////

  aMsgPropId[cPropId] = PROPID_M_TRACE;
  aMsgPropVar[cPropId].vt = VT_UI1;
  aMsgPropVar[cPropId].bVal = MQMSG_SEND_ROUTE_TO_REPORT_QUEUE;
  cPropId++;

  /////////////////////////////////////////////////////////////////
  // Add additional message properties here. When adding
  // properties, increment NumberOfProperties to reflect the
  // total number of message properties specified.
  /////////////////////////////////////////////////////////////////

  aMsgPropId[cPropId] = PROPID_M_BODY;
  aMsgPropVar[cPropId].vt = VT_VECTOR | VT_UI1;
  aMsgPropVar[cPropId].caub.pElems = (LPBYTE)wszMessageBody;
  aMsgPropVar[cPropId].caub.cElems = sizeof(wszMessageBody);
  cPropId++;

  aMsgPropId[cPropId] = PROPID_M_LABEL;
  aMsgPropVar[cPropId].vt = VT_LPWSTR;
  aMsgPropVar[cPropId].pwszVal = L"Message Label";
  cPropId++;

  /////////////////////////////////////////////////////////////////
  // Initialize the MQMSGPROPS structure.
  /////////////////////////////////////////////////////////////////

  msgprops.cProp = cPropId;                           // Number of message properties
  msgprops.aPropID = aMsgPropId;                      // Ids of message properties
  msgprops.aPropVar = aMsgPropVar;                    // Values of message properties
  msgprops.aStatus  = aMsgStatus;                     // Error reports

  /////////////////////////////////////////////////////////////////
  // Convert destination queue pathname to a format name.
  /////////////////////////////////////////////////////////////////

  hr = MQPathNameToFormatName(L"boothby-srv4\\TestQueue",
                              szDestFormatNameBuffer,
                              &dwDestFormatNameBufferLength);
  if (FAILED(hr))
  {
     fprintf(stderr, "Failed in MQPathNameToFormatName for destination queue, error = 0x%x\n",hr);
     return -1;
  }

  /////////////////////////////////////////////////////////////////
  // Open the destination queue to send the message.
  /////////////////////////////////////////////////////////////////

  hr = MQOpenQueue(szDestFormatNameBuffer,            // Format name of queue
                   dwAccess,                          // Access mode
                   dwShareMode,                       // Share mode
                   &hQueue                            // OUT: Handle to queue

                   );
  if (FAILED(hr))
  {
     fprintf(stderr, "Failed opening destination queue, error = 0x%x\n",hr);
     return -1;
  }

  /////////////////////////////////////////////////////////////////
  // Send the message to the destination queue.
  /////////////////////////////////////////////////////////////////

  hr = MQSendMessage(hQueue,
                     &MsgProps,
                     NULL);

  if (FAILED(hr))
  {
     fprintf(stderr, "Failed sending message, error = 0x%x\n",hr);
     return -1;
  }

  /////////////////////////////////////////////////////////////////
  // Close the queue.
  /////////////////////////////////////////////////////////////////

  hr = MQCloseQueue(hQueue);
  if (FAILED(hr))
  {
     fprintf(stderr, "Failed closing destination queue, error = 0x%x\n",hr);
     return -1;
  }

  puts("The message is sent. Check the report queue for new report messages.");
  return 0;

}


Sending Response Messages

The receiving application can return response messages to the response queue provided by the sending application.

When the receiving application sees that a response queue format name was sent in the PROPID_M_RESP_QUEUE property of the original message (if this value is NULL, no response is expected), it should return a response message to the sending application.

Note Each Message Queuing message can have no more than 4 MB of data.

To send a response message

  1. Determine what type of response message is needed. Response messages are application-defined, consequently both the sending and receiving application must be able to understand the message. In this example the response message includes the message identifier and destination of the original message.
  2. Define the structures needed to send the message.
  3. Specify the properties to retrieve from the original message. The following example retrieves PROPID_M_RESP_QUEUE, PROPID_M_RESP_QUEUE_LEN, PROPID_M_DEST_QUEUE, PROPID_M_DEST_QUEUE_LEN, and PROPID_M_MSGID.
  4. Specify the properties of the response message. The following example only sets the PROPID_M_BODY, PROPID_M_RESP_QUEUE and PROPID_M_CORRELATIONID.
  5. Initialize the MQMSGPROPS structures for the original message and response message.
  6. Generate a format name for the destination queue. The following example calls MQPathNameToFormatName to convert a known pathname to a format name.
  7. Call MQOpenQueue to open the destination queue with receive access.
  8. Call MQReceiveMessage to retrieve the format name needed to open the response queue.
  9. Call MQOpenQueue to open the response queue, using the format name retrieved from PROPID_M_RESP_QUEUE.
  10. Call MQSendMessage to send the response message.
  11. Call MQCloseQueue to close the destination queue and response queue.
For a code example using | See
C++ | C/C++ Code Example


C/C++ Code Example: Sending Response Messages

The following example retrieves the first message from a known destination queue, tests to see if a response message is needed, and then sends a response message if the test indicates a response message is expected.

#include <windows.h>
#include <stdio.h>
#include <mq.h>                                       // Message Queuing header file

int main(int arg, char *argv[])

{
  ////////////////////////////////////////////////////////////
  //  Define the required structures.
  ////////////////////////////////////////////////////////////

  #define ORIGNUMBEROFPROPERTIES 5                    // Number of properties
  #define RESPNUMBEROFPROPERTIES 3                    // Number of properties
  DWORD cOrigPropId = 0;                              // Original message counter
  DWORD cRespPropId = 0;                          // Response message counter

  // Define MQMSGPROPS structures.
  MQMSGPROPS origmsgprops;
  MSGPROPID aOrigMsgPropId[ORIGNUMBEROFPROPERTIES];
  MQPROPVARIANT aOrigMsgPropVar[ORIGNUMBEROFPROPERTIES];
  HRESULT aOrigMsgStatus[ORIGNUMBEROFPROPERTIES];

  MQMSGPROPS respmsgprops;
  MSGPROPID arespmsgpropId[RESPNUMBEROFPROPERTIES];
  MQPROPVARIANT arespmsgpropVar[RESPNUMBEROFPROPERTIES];
  HRESULT aRespMsgStatus[RESPNUMBEROFPROPERTIES];

  HANDLE hDestQueue, hRespQueue;                      // Queue handles
  HRESULT hr;                                         // Define results

  // Access and share mode for receiving original message
  DWORD dwDestAccess = MQ_RECEIVE_ACCESS;             // Access mode of queue
  DWORD dwDestShareMode = MQ_DENY_RECEIVE_SHARE;      // Share Mode of queue
  DWORD dwRecAction = MQ_ACTION_RECEIVE;              // Receive mode

  // Access and share mode for sending response message
  DWORD dwRespAccess = MQ_SEND_ACCESS;                // Access mode of queue
  DWORD dwRespShareMode = MQ_DENY_NONE;               // Share Mode of queue

  // Destination queue format name buffer
  DWORD dwDestFormatNameBufferLength = 256;
  WCHAR szDestFormatNameBuffer[256];

  // Response queue format name buffer
  DWORD dwRespFormatNameBufferLength = 256;
  WCHAR szRespFormatNameBuffer[256];

  // Message identifier of original message
  UCHAR szMessageID[20];

  // Body of response message
  WCHAR wszRespMessageBody[] = L"Response message.";

  /////////////////////////////////////////////////////////////////
  // Specify the message properties of the original message.
  // PROPID_M_RESP_QUEUE and PROPID_M_RESP_QUEUE_LEN are
  // needed to retrieve the format name of the response queue.
  /////////////////////////////////////////////////////////////////

  aOrigMsgPropId[cOrigPropId] = PROPID_M_RESP_QUEUE;
  aOrigMsgPropVar[cOrigPropId].vt = VT_LPWSTR;
  aOrigMsgPropVar[cOrigPropId].pwszVal = szRespFormatNameBuffer;
  cOrigPropId++;

  aOrigMsgPropId[cOrigPropId] = PROPID_M_RESP_QUEUE_LEN;
  aOrigMsgPropVar[cOrigPropId].vt = VT_UI4;
  aOrigMsgPropVar[cOrigPropId].ulVal = dwRespFormatNameBufferLength;
  cOrigPropId++;

  aOrigMsgPropId[cOrigPropId] = PROPID_M_DEST_QUEUE;
  aOrigMsgPropVar[cOrigPropId].vt = VT_LPWSTR;
  aOrigMsgPropVar[cOrigPropId].pwszVal = szDestFormatNameBuffer;
  cOrigPropId++;

  aOrigMsgPropId[cOrigPropId] = PROPID_M_DEST_QUEUE_LEN;
  aOrigMsgPropVar[cOrigPropId].vt = VT_UI4;
  aOrigMsgPropVar[cOrigPropId].ulVal = dwDestFormatNameBufferLength;
  cOrigPropId++;

  aOrigMsgPropId[cOrigPropId] = PROPID_M_MSGID;
  aOrigMsgPropVar[cOrigPropId].vt = VT_VECTOR | VT_UI1;
  aOrigMsgPropVar[cOrigPropId].caub.pElems = szMessageID;
  aOrigMsgPropVar[cOrigPropId].caub.cElems = sizeof(szMessageID);  cOrigPropId++;

  /////////////////////////////////////////////////////////////////
  // Specify the message properties of the response message.
  // This example only sets the body, correlation identifier, and
  // response queue properties of the message.
  /////////////////////////////////////////////////////////////////

  arespmsgpropId[cRespPropId] = PROPID_M_BODY;
  arespmsgpropVar[cRespPropId].vt = VT_VECTOR | VT_UI1;
  arespmsgpropVar[cRespPropId].caub.pElems = (LPBYTE)wszRespMessageBody;
  arespmsgpropVar[cRespPropId].caub.cElems = sizeof(wszRespMessageBody);
  cRespPropId++;

  arespmsgpropId[cRespPropId] = PROPID_M_RESP_QUEUE;
  arespmsgpropVar[cRespPropId].vt = VT_LPWSTR;
  arespmsgpropVar[cRespPropId].pwszVal = szRespFormatNameBuffer;
  cRespPropId++;

  arespmsgpropId[cRespPropId] = PROPID_M_CORRELATIONID;
  arespmsgpropVar[cRespPropId].vt = VT_VECTOR | VT_UI1;
  arespmsgpropVar[cRespPropId].caub.pElems = szMessageID;
  arespmsgpropVar[cRespPropId].caub.cElems = sizeof(szMessageID);
  cRespPropId++;

  /////////////////////////////////////////////////////////////////
  // Initialize the MQMSGPROPS structures for original and
  // response messages.
  /////////////////////////////////////////////////////////////////

  origmsgprops.cProp = cOrigPropId;               // Number of message properties.
  origmsgprops.aPropID = aOrigMsgPropId;              // Ids of message properties.
  origmsgprops.aPropVar = aOrigMsgPropVar;            // Values of message properties.
  origmsgprops.aStatus  = aOrigMsgStatus;             // Error reports.

  respmsgprops.cProp = cRespPropId;               // Number of message properties.
  respmsgprops.aPropID = arespmsgpropId;              // Ids of message properties.
  respmsgprops.aPropVar = arespmsgpropVar;            // Values of message properties.
  respmsgprops.aStatus  = aRespMsgStatus;             // Error reports.

  /////////////////////////////////////////////////////////////////
  // Convert destination queue pathname to a format name.
  /////////////////////////////////////////////////////////////////

  hr = MQPathNameToFormatName(L".\\TestQueue",
                             szDestFormatNameBuffer,
                              &dwDestFormatNameBufferLength);
  if (FAILED(hr))
  {
     fprintf(stderr, "Failed in MQPathNameToFormatName for destination queue, error = 0x%x\n",hr);
     return -1;
  }

  /////////////////////////////////////////////////////////////////
  // Open the destination queue to retrieve original message.
  /////////////////////////////////////////////////////////////////

  hr = MQOpenQueue(szDestFormatNameBuffer, // Format name of queue
                   dwDestAccess,           // Access mode
                   dwDestShareMode,        // Share mode
                   &hDestQueue             // OUT: Handle to queue
                   );
  if (FAILED(hr))
  {
     fprintf(stderr, "Failed opening destination queue, error = 0x%x\n",hr);
     return -1;
  }

  ////////////////////////////////////////////////////////////////
  // Retrieve original message to obtain format name of response
  // queue.
  /////////////////////////////////////////////////////////////////

  hr = MQReceiveMessage(
                        hDestQueue,        // Handle of queue
                        5*60*1000,         // Timeout = 5 minutes
                        dwRecAction,       // How message is retrieved
                        &origmsgprops,     // Properties to retrieve
                        NULL,              // NULL for sync read
                        NULL,              // NULL for sync read
                        NULL,              // No cursor
                        MQ_NO_TRANSACTION  // No transaction
                        );

  if (FAILED(hr))
  {
     fprintf(stderr, "Failed reading original message, error = 0x%x\n",hr);
     return -1;
  }

  puts("The original message was read from the destination queue.");

  if (origmsgprops.aPropVar[1].ulVal == NULL)
  {
     puts("No response message was requested.");
     return -1;
  }

  /////////////////////////////////////////////////////////////////
  // Open the response queue to send message.
  /////////////////////////////////////////////////////////////////

  hr = MQOpenQueue(szRespFormatNameBuffer, // Format name of queue
                   dwRespAccess,           // Access mode
                   dwRespShareMode,        // Share mode
                   &hRespQueue             // OUT: Handle to queue
                   );
  if (FAILED(hr))
  {
     fprintf(stderr, "Failed opening response queue, error = 0x%x\n",hr);
     return -1;
  }

  /////////////////////////////////////////////////////////////////
  // Send message to the destination queue.
  /////////////////////////////////////////////////////////////////

  hr = MQSendMessage(hRespQueue,
                     &respmsgprops,
                     NULL
                     );
  if (FAILED(hr))
  {
     fprintf(stderr, "Failed sending response message, error = 0x%x\n",hr);
     return -1;
  }

  /////////////////////////////////////////////////////////////////
  // Close destination and response queue.
  /////////////////////////////////////////////////////////////////

  hr = MQCloseQueue(hDestQueue);

  if (FAILED(hr))
  {
     fprintf(stderr, "Failed closing destination queue, error = 0x%x\n",hr);
     return -1;
  }
  hr = MQCloseQueue(hRespQueue);

  if (FAILED(hr))
  {
     fprintf(stderr, "Failed closing response queue, error = 0x%x\n",hr);
     return -1;
  }
  puts("The response message was sent to the response queue.");
  return 0;

}


Sending Private Messages

To send a private message, the sending application must set the privacy level (PROPID_M_PRIV_LEVEL) of the message, and, optionally, specify the encryption algorithm (PROPID_M_ENCRYPTION_ALG) to be used to encrypt the body of the message.

The functions used to send a private message are no different from those used to send other messages.

When sending (and receiving) private messages, the application has no part in encrypting (or decrypting) the message. (For information on how Message Queuing encrypts and decrypts messages, see Message Encryption.)

Note Each Message Queuing message can have no more than 4 MB of data.

To send a private message

  1. Define the MQMSGPROPS structure.
  2. Specify the properties of the message. The example below specifies the label, body, privacy level, and encryption algorithm for the message. The value of PROPID_M_PRIV_LEVEL indicates that the message is private.
  3. Initialize the MQMSGPROPS structure.
  4. Obtain the format name of the destination queue. The example below calls MQPathNameToFormatName to obtain a format name from a known pathname.
  5. Call MQOpenQueue to open the destination queue with send access.
  6. Call MQSendMessage to send the message.
  7. Call MQCloseQueue to close the destination queue.
For a code example using | See
C++ | C/C++ Code Example


C/C++ Code Example: Sending Private Messages

This example sends a private message to a known public queue. Note that the privacy level and the optional encryption algorithm property are set for the message.

#include <windows.h>
#include <wincrypt.h>                                 // CrpytoAPI header file.
#include <stdio.h>
#include <mq.h>                                       // Message Queuing header file

int main(int arg, char *argv[])

{
  ////////////////////////////////////////////////////////////////
  //  Define the required structures.
  ////////////////////////////////////////////////////////////////

  #define NUMBEROFPROPERTIES 4                       //Number of message properties.
  DWORD cPropId = 0;

  MQMSGPROPS msgprops;
  MSGPROPID aMsgPropId[NUMBEROFPROPERTIES];
  MQPROPVARIANT aMsgPropVar[NUMBEROFPROPERTIES];
  HRESULT aMsgStatus[NUMBEROFPROPERTIES];

  HANDLE hQueue;                                      // Queue handle
  HRESULT hr;                                         // Define results
  DWORD dwAccessMode = MQ_SEND_ACCESS;                // Access mode of queue
  DWORD dwShareMode = MQ_DENY_NONE;                   // Share mode of queue

  // Define format name buffer
  DWORD dwDestFormatNameBufferLength = 256;
  WCHAR wszDestFormatNameBuffer[256];

  // Define message body
  WCHAR wszMessageBody[] = L"Private massage.";

  //////////////////////////////////////////////////////////////////
  // Specify message properties.
  //////////////////////////////////////////////////////////////////

  //Set the PROPID_M_LABEL property.
  aMsgPropId[cPropId] = PROPID_M_LABEL;               // PROPVARIENT Field
  aMsgPropVar[cPropId].vt = VT_LPWSTR;                // Type Indicator
  aMsgPropVar[cPropId].pwszVal = L"Private Message";  // Message label
  cPropId++;

  //Set the PROPID_M_BODY property.
  aMsgPropId[cPropId] = PROPID_M_BODY;                       // PROPVARIENT Field
  aMsgPropVar[cPropId].vt = VT_VECTOR | VT_UI1;              // Type Indicator
  aMsgPropVar[cPropId].caub.pElems = (LPBYTE)wszMessageBody; // Message body
  aMsgPropVar[cPropId].caub.cElems = sizeof(wszMessageBody);
  cPropId++;

  //Set the PROPID_M_PRIV_LEVEL property.
  aMsgPropId[cPropId] = PROPID_M_PRIV_LEVEL;          // PROPVARIENT Field
  aMsgPropVar[cPropId].vt = VT_UI4;                   // Type Indicator
  aMsgPropVar[cPropId].ulVal = MQMSG_PRIV_LEVEL_BODY; // Privacy level
  cPropId++;

  //Set the PROPID_M_ENCRYPTION_ALG property.
  aMsgPropId[cPropId] = PROPID_M_ENCRYPTION_ALG;      // PROPVARIENT Field
  aMsgPropVar[cPropId].vt = VT_UI4;                   // Type Indicator
  aMsgPropVar[cPropId].ulVal = CALG_RC4;              // Encryption algorithm
  cPropId++;

  //////////////////////////////////////////////////////////////////
  // Initialize the MQMSGPROPS structure.
  //////////////////////////////////////////////////////////////////
  msgprops.cProp = cPropId;                           // Number of properties
  msgprops.aPropID = aMsgPropId;                      // Ids of properties
  msgprops.aPropVar = aMsgPropVar;                    // Values of properties
  msgprops.aStatus = aMsgStatus;                      // Error reports

  //////////////////////////////////////////////////////////////////
  // Obtain format name of queue.
  //////////////////////////////////////////////////////////////////

  hr = MQPathNameToFormatName(L".\\privatemessagetestqueue",
                              wszDestFormatNameBuffer,
                              &dwDestFormatNameBufferLength
                              );
  if (FAILED(hr))
  {
     fprintf(stderr, "Failed in MQPathNameToFormatName, error = 0x%x\n",hr);
     return -1;
  }

  //////////////////////////////////////////////////////////////////
  // Open the destination queue to send message.
  //////////////////////////////////////////////////////////////////

  hr = MQOpenQueue(wszDestFormatNameBuffer,           // Format name of queue.
                  dwAccessMode,                      // Access mode of queue
                  dwShareMode,                       // Share mode of queue
                  &hQueue                            // OUT: Handle of queue
                  );
  if (FAILED(hr))
  {
     fprintf(stderr, "Failed in MQOpenQueue, error = 0x%x\n",hr);
     return -1;
  }

  //////////////////////////////////////////////////////////////////
  // Send message to queue.
  //////////////////////////////////////////////////////////////////

  hr = MQSendMessage(hQueue,                          // Handle to open queue
                     &msgprops,                       // Properties of message
                     NULL);                           // No transaction
  if (FAILED(hr))
  {
     fprintf(stderr, "Failed in MQSendMessage, error = 0x%x\n",hr);
     return -1;
  }

  //////////////////////////////////////////////////////////////////
  // Close queue.
  //////////////////////////////////////////////////////////////////

  hr =  MQCloseQueue(hQueue);
  if (FAILED(hr))
  {
     fprintf(stderr, "Failed in MQCloseQueue, error = 0x%x\n",hr);
     return -1;
  }

  printf("The private message was sent successfully.\n");
  return 0;

}


Sending Express and Recoverable Messages

When sending messages, you can select between two delivery modes: express and recoverable. The following example sends two messages, one sent express and the other recoverable.

To find out what affect delivery mode has on your network, run this example and check the delivery time of each message using the directory service.

To send express and recoverable messages

  1. Define the structures needed to send a message.
  2. Specify PROPID_M_DELIVERY and any other message properties that may be needed. This example specifies PROPID_M_DELIVERY and PROPID_M_LABEL.
  3. Initialize the MQMSGPROPS structure.
  4. Generate a format name for the queue. This example calls MQPathNameToFormatName to convert a known pathname to a format name.
  5. Call MQOpenQueue to open the destination queue with send access.
  6. Call MQSendMessage to send the messages to the queue. This example sends one message, then changes the delivery mode (and label) and sends a second message.
  7. Call MQCloseQueue to close the destination queue.
For a code example using | See
C++ | C/C++ Code Example


C/C++ Code Example: Sending Express and Recoverable Messages

The following example sends two messages to a known queue.

#include <windows.h>
#include <stdio.h>
#include <mq.h>                                       // Message Queuing header file

int main(int arg, char *argv[])

{

  ////////////////////////////////////////////////////////////////
  //  Define the required structures.
  ////////////////////////////////////////////////////////////////

  #define NUMBEROFPROPERTIES 2                       //Number of message properties
  DWORD cPropId = 0;

  MQMSGPROPS msgprops;
  MSGPROPID aMsgPropId[NUMBEROFPROPERTIES];
  MQPROPVARIANT aMsgPropVar[NUMBEROFPROPERTIES];
  HRESULT aMsgStatus[NUMBEROFPROPERTIES];

  HANDLE hQueue;                                      // Queue handle
  HRESULT hr;                                         // Define results.
  DWORD dwAccessMode = MQ_SEND_ACCESS;                // Access mode of queue
  DWORD dwShareMode = MQ_DENY_NONE;                   // Share mode of queue

  // Define format name buffer
  DWORD dwDestFormatNameBufferLength = 256;
  WCHAR wszDestFormatNameBuffer[256];

  //////////////////////////////////////////////////////////////////
  // Specify message properties.
  //////////////////////////////////////////////////////////////////

  aMsgPropId[cPropId] = PROPID_M_LABEL;                  // PROPVARIENT Field
  aMsgPropVar[cPropId].vt = VT_LPWSTR;                   // Type Indicator
  aMsgPropVar[cPropId].pwszVal = L"Recoverable Message"; // Message label
  cPropId++;

  aMsgPropId[cPropId] = PROPID_M_DELIVERY;            // MQPROPVARIANT Field
  aMsgPropVar[cPropId].vt = VT_UI1;                   // Type Indicator
  aMsgPropVar[cPropId].bVal = MQMSG_DELIVERY_RECOVERABLE;
  cPropId++;

  //////////////////////////////////////////////////////////////////
  // Initialize the MQMSGPROPS structure.
  //////////////////////////////////////////////////////////////////

  msgprops.cProp = cPropId;                           // Number of properties
  msgprops.aPropID = aMsgPropId;                      // Ids of properties
  msgprops.aPropVar = aMsgPropVar;                    // Values of properties
  msgprops.aStatus = aMsgStatus;                      // Error reports

  //////////////////////////////////////////////////////////////////
  // Obtain format name of queue.
  //////////////////////////////////////////////////////////////////

  hr = MQPathNameToFormatName(L".\\testqueue",
                              wszDestFormatNameBuffer,
                              &dwDestFormatNameBufferLength
                              );
  if (FAILED(hr))
  {
     fprintf(stderr, "Failed in MQPathNameToFormatName, error = 0x%x\n",hr);
     return -1;
  }

  //////////////////////////////////////////////////////////////////
  // Open the destination queue to send messages.
  //////////////////////////////////////////////////////////////////

  hr = MQOpenQueue(wszDestFormatNameBuffer,           // Format name of queue
                   dwAccessMode,                      // Access mode of queue
                   dwShareMode,                       // Share mode of queue
                   &hQueue                            // OUT: Handle of queue
                  );

  if (FAILED(hr))
  {
     fprintf(stderr, "Failed in MQOpenQueue, error = 0x%x\n",hr);
     return -1;
  }

  //////////////////////////////////////////////////////////////////
  // Send message to queue.
  //////////////////////////////////////////////////////////////////

  // Send message as "recoverable".
  hr = MQSendMessage(hQueue,                          // Handle to open queue
                     &msgprops,                       // Properties of message
                     NULL);                           // No transaction
  if (FAILED(hr))
  {
    fprintf(stderr, "Failed in MQSendMessage, error = 0x%x\n",hr);
    return -1;
  }

  msgprops.aPropVar[0].pwszVal = L"Express Message";
  msgprops.aPropVar[1].bVal = MQMSG_DELIVERY_EXPRESS;

  // Send message as "express".
  hr = MQSendMessage(hQueue,                          // Handle to open queue
                     &msgprops,                       // Properties of message
                     NULL);                           // No transaction
  if (FAILED(hr))
  {
    fprintf(stderr, "Failed in MQSendMessage, error = 0x%x\n",hr);
    return -1;
  }

  //////////////////////////////////////////////////////////////////
  // Close queue.
  //////////////////////////////////////////////////////////////////

  hr =  MQCloseQueue(hQueue);
  if (FAILED(hr))
  {
    fprintf(stderr, "Failed in MQCloseQueue, error = 0x%x\n",hr);
    return -1;
  }

  puts ("Both messages were sent to the queue. Compare their sent ");
  puts ("and arrived times to see how delivery mode affects ");
  puts ("the time it takes for the message to reach the queue.\n");

  return 0;

}


Reading Messages in a Queue

Reading messages in a queue is typically a two or three-function operation. To read only the first message in the queue, an application can call MQOpenQueue and MQReceiveMessage. However, if the application needs to navigate through the queue, it must call MQOpenQueue, MQCreateCursor, and MQReceiveMessage.

When reading messages in a queue, the application can peek at the messages in the queue or retrieve them.

Note When reading messages, the application can retrieve any message properties associated with the message. It is the application's responsibility to specify which message properties it requires (this includes the body of the message).

For an example of | See
Reading the first message in a queue. | Reading the first Message in a Queue
Asynchronously reading messages in a queue. | Reading Messages Asynchronously
Using a cursor to peek at each message in a queue | Reading Messages Using a Cursor
Checking to see whether the format name of an administration queue was sent along with the message | Retrieving the Format Name of an Administration Queue


Reading the First Message in a Queue

This example shows how to synchronously retrieve the message body of the first message in a queue. To expand this example to read other message properties, add the appropriate property identifiers and VT field to the MQMSGPROPS structure, and increment the NUMBEROFPROPERTIES constant for each additional property.

Note When reading messages synchronously, all calls are blocked until the next message is available or timeout occurs.

To read the body of a message

  1. Specify the structures needed to retrieve the message.
  2. Specify PROPID_M_BODY and PROPID_M_BODY_SIZE. The body size is needed to test if the message has a message body.
  3. Initialize the MQMSGPROPS structure.
  4. Obtain a format name for the queue. The following example calls MQPathNameToFormatName to generate a format name for the queue.
  5. Call MQOpenQueue to open the queue with receive access.
  6. Call MQReceiveMessage to retrieve the first message in the queue. The following example retrieves the message body so tests must be made to see 1) if the message body buffer is to small (in this case MQ_ERROR_BUFFER_TOO_SMALL is returned by MQReceiveMessage) and 2) that a message body was sent with the message (the returned value of PROPID_M_BODY_SIZE is not 0).
  7. Call MQCloseQueue to free the resources used by the open queue.
For a code example using | See
C++ | C/C++ Code Example


C/C++ Code Example: Reading Messages Synchronously

The following example opens a queue with receive access, then retrieves the first message in the queue.

#include <windows.h>
#include <stdio.h>
#include <mq.h>                              // Message Queuing header file

int main(int arg, char *argv[])

{

  #define NUMBER_OF_PROPERTIES  2        // Number of msg properties
  DWORD cPropId = 0;                     // Property counter

  //Define MQMSGPROPS structure.
  MQMSGPROPS msgprops;
  MSGPROPID aMsgPropId[NUMBER_OF_PROPERTIES];
  MQPROPVARIANT aMsgPropVar[NUMBER_OF_PROPERTIES];
  HRESULT aMsgStatus[NUMBER_OF_PROPERTIES];

  HANDLE hQueue;                 // Queue handle
  HRESULT hr;                    // Define results
  DWORD dwAccess;                // Access mode of queue
  DWORD dwShareMode;             // Share mode of queue
  DWORD dwRecAction;             // Receive action

  // Destination queue format name buffer
  DWORD dwDestFormatNameBufferLength = 256;
  WCHAR wszDestFormatNameBuffer[256];

  // Message body buffer
  DWORD dwBodyBufferSize = 1024;
  UCHAR *pucBodyBuffer = (UCHAR *)malloc(dwBodyBufferSize);

  /////////////////////////////////////////////////////////////
  // Specify the message body and body size properties.
  /////////////////////////////////////////////////////////////

  aMsgPropId[cPropId] = PROPID_M_BODY_SIZE;       // Property ID
  aMsgPropVar[cPropId].vt = VT_UI4;               // Type indicator
  cPropId++;

  aMsgPropId[cPropId] = PROPID_M_BODY;            // Property ID
  aMsgPropVar[cPropId].vt = VT_VECTOR|VT_UI1;     // Type indicator
  aMsgPropVar[cPropId].caub.pElems = (UCHAR*)pucBodyBuffer;
  aMsgPropVar[cPropId].caub.cElems = dwBodyBufferSize;

  cPropId++;

  /////////////////////////////////////////////////////////////
  // Initialize the MQMSGPROPS structure.
  /////////////////////////////////////////////////////////////

  msgprops.cProp = cPropId;          // Number of message properties
  msgprops.aPropID = aMsgPropId;     // Ids of message properties
  msgprops.aPropVar = aMsgPropVar;   // Values of message properties
  msgprops.aStatus  = aMsgStatus;    // Error reports

  /////////////////////////////////////////////////////////////////
  // Convert destination queue pathname to a format name.
  /////////////////////////////////////////////////////////////////

  hr = MQPathNameToFormatName(L".\\TestQueue",
                              wszDestFormatNameBuffer,
                              &dwDestFormatNameBufferLength);
  if (FAILED(hr))
  {
     fprintf(stderr, "Failed in MQPathNameToFormatName for destination queue, error = 0x%x\n",hr);
     return -1;
  }

  /////////////////////////////////////////////////////////////////
  // Open the destination queue to retrieve the message.
  /////////////////////////////////////////////////////////////////

  dwAccess = MQ_RECEIVE_ACCESS;             // Access mode of queue
  dwShareMode = MQ_DENY_RECEIVE_SHARE;      // Share mode of queue

  hr = MQOpenQueue(wszDestFormatNameBuffer, // Format name of queue
                   dwAccess,                // Access mode
                   dwShareMode,             // Share mode
                   &hQueue                  // OUT: Handle to queue
                   );
  if (FAILED(hr))
  {
     fprintf(stderr, "Failed opening destination queue, error = 0x%x\n",hr);
     return -1;
  }

  /////////////////////////////////////////////////////////////
  // Retrieve the message.
  /////////////////////////////////////////////////////////////

  dwRecAction = MQ_ACTION_RECEIVE;            // Receive action

  hr = MQReceiveMessage(hQueue,             // Queue handle
                        0,                  // Max time (msec)
                        dwRecAction,        // Receive action
                        &msgprops,          // Msg property structure
                        NULL,               // No OVERLAPPED structure
                        NULL,               // No callback function
                        NULL,               // No cursor
                        NULL                // No transaction
                        );

  /////////////////////////////////////////////////////////////
  // Test to see if a buffer overflow was returned. If true
  // reallocate the message body buffer and call
  // MQReceiveMessage again.
  /////////////////////////////////////////////////////////////

  if (hr==MQ_ERROR_BUFFER_OVERFLOW)
  {
     free(pucBodyBuffer);
     pucBodyBuffer = (UCHAR *)malloc(aMsgPropVar[0].ulVal);
     aMsgPropVar[1].caub.pElems = (UCHAR*)pucBodyBuffer;
     aMsgPropVar[1].caub.cElems = aMsgPropVar[0].ulVal;

     hr = MQReceiveMessage(hQueue,          // Queue handle
                           0,               // Max time (msec)
                           dwRecAction,     // Receive action
                           &msgprops,       // Msg property structure
                           NULL,            // No OVERLAPPED structure
                           NULL,            // No callback function
                           NULL,            // No cursor
                           NULL             // No transaction
                           );
  }

  if (FAILED(hr))
  {
    fprintf(stderr, "Failed retrieving message, error = 0x%x\n",hr);
    return 1;
  }

  /////////////////////////////////////////////////////////////
  // Test the returned value of PROPID_M_BODY_SIZE to see if
  // a message body exists. If the body exist print the body.
  /////////////////////////////////////////////////////////////

  if (aMsgPropVar[0].ulVal == 0)
  {
    puts ("No message body exists.");
  }
  else
  {
    wprintf(L"The message body is : %s.\n",(LPWSTR)pucBodyBuffer);
  }

  //////////////////////////////////////////////////////////////
  // Close the queue.
  //////////////////////////////////////////////////////////////

  hr = MQCloseQueue(hQueue);

  return 0;

}


Reading Messages Asynchronously

Applications can use a callback function, a Windows Event mechanism, or a Microsoft® Windows NT®/Windows® 2000 completion port to read messages asynchronously. When reading messages asynchronously, the application is notified if a message is available or if a timeout has occurred.

For example code using | See
A Callback Function | Callback Function Example
A Windows Event Mechanism | Windows Event Mechanism Example
A Windows NT/Windows 2000 Completion Port Mechanism | Windows NT/Windows 2000 Completion Port Example


Callback Function Example

This example uses a callback function (fnReceiveCallback is not NULL) to read the first message in a queue. In this case, the message is read by MQReceiveMessage and the returned message properties (and error codes) are handled by the registered callback function.

Note Once registered, a callback function cannot be unregistered. Closing the queue, closes the callback function as well.

When using a callback function, it is very important to allocate the memory for the MQMSGPROPS structure on the heap. Not on the stack. In addition, always free MQMSGPROPS within the callback function

When multiple asynchronous MQReceiveMessage calls are outstanding, several callbacks are registered; upon arrival of a message, the first registered callback is called. Internally, Message Queuing uses the WaitForMultipleObjects API which is limited to 64 objects per process.

To read a single message using a callback function

  1. Write the callback function.
  2. Call MQOpenQueue to open the queue with receive or peek access. If the queue is opened with receive access, the application can still peek at the messages in the queue.
  3. Specify the message properties to be retrieved, retrieving only those properties that are needed.
  4. Initialize the MQMSGPROPS structure on the heap.
  5. Call MQReceiveMessage to read the message from the queue, making sure to free the MQMSGPROPS structure from within the callback function.
  6. Call MQCloseQueue to close the queue, freeing all memory allocated for any pending MQReceiveMessage calls. Closing the queue, closes the callback function as well.

Code Example

The following example reads the first message of the queue using a callback function.

//////////////////////////////
// Receive callback function.
/////////////////////////////

void APIENTRY ReceiveCallbackRoutine(
   HRESULT hr,
   QUEUEHANDLE hSource,
   DWORD dwTimeout,
   DWORD dwAction,
   MQMSGPROPS* pMessageProps,
   LPOVERLAPPED lpOverlapped,
   HANDLE hCursor
  )
 {
  if (FAILED(hr))
   {
    // Error handler for Callback routine.
   }
  else
  {
   // Process message.
  }
 }

//////////////
// Open Queue
//////////////

HRESULT hr;
QUEUEHANDLE hQueue;

hr = MQOpenQueue(
     szwFormatNameBuffer,    // Format Name of the queue to be opened
     MQ_RECEIVE_ACCESS,      // Access rights to the Queue
     0,                      // No receive Exclusive
     &hQueue                 // OUT: handle to the opened Queue
);

if (FAILED(hr))
{
 // Error handler for MQOpenQueue.
}

MQMSGPROPS * pmsgprops;
MQPROPVARIANT *paVariant;
MSGPROPID * paPropId;
DWORD dwcPropId = 0;

//
//  The output parameters to an asynchronous call to MQReceiveMessage
//  should be kept intact until the operation completes, you should
//  not free or reuse them until the operation is complete.
//
pmsgprops = new MQMSGPROPS;
paVariant = new MQPROPVARIANT[ 10];
paPropId = new MSGPROPID[ 10];

//////////////////////////////////////////////////
// Prepare the message properties to be retrieved.
/////////////////////////////////////////////////

// Set the PROPID_M_BODY property.
paPropId[dwcPropId] = PROPID_M_BODY;                //PropId
paVariant[dwcPropId].vt = VT_VECTOR|VT_UI1;         //Type
paVariant[dwcPropId].caub.cElems = MSG_BODY_LEN ;    //Value
paVariant[dwcPropId].caub.pElems = new unsigned char[ MSG_BODY_LEN];

 dwcPropId++;

////////////////////////////////
// Initialize the MQMSGPROPS structure
///////////////////////////////
pmsgprops->cProp = dwcPropId;     //Number of properties
pmsgprops->aPropID = paPropId;        //Ids of properties
pmsgprops->aPropVar = paVariant;      //Values of properties
pmsgProps->aStatus  = NULL;           //No Error report

///////////////////////////////////////////////
//  Receive the message using callback function
//  ReceiveCallbackRoutine.
///////////////////////////////////////////////

hr = MQReceiveMessage(
    hQueue,                     // Handle to the Queue
    5 * 60 * 1000,              // Max time (msec) to wait
    MQ_ACTION_RECEIVE,          // Action
    pmsgprops,                  // Properties to retrieve
    NULL,                       // No OVERLAPPED structure
    ReceiveCallbackRoutine,     // Callback function
    NULL,                       // No Cursor
    NULL                        // No transaction
              );

if (FAILED(hr))
   {
     //  Error handler for MQReceiveMessage.
    }


Windows Event Mechanism Example

By using a Windows Event mechanism (fnReceiveCallback is NULL and lpOverlapped is not NULL). In this case, the hEvent member of the specified OVERLAPPED structure contains a valid handle to an event object. When a suitable message arrives, or a time-out occurs, the event object is set to the signaled state.

To read a message asynchronously using a Windows Event mechanism

  1. Open the queue with receive or peek access. The access mode used to open the queue does not determine how the messages are read from the queue. For example, if the queue is opened with receive access, the application can still peek at the messages in the queue.
  2. Specify the message properties to be retrieved. If you only need to look at the body of the message, only specify PROPID_M_BODY.
  3. Initialize the MQMSGPROPS structure.
  4. Create the Event object using OVERLAPPED structure.
  5. Read the message from the queue.
  6. Retrieve the Message Queuing return code returned to the overlapped structure. For MSMQ 1.0 application, this must be done by your application. For MSMQ 2.0 applications, call MQGetOverlappedResult.
  7. Write a Windows Event handler (typically a separate thread) and close the handle after it's signaled and you process the message.

Code Examples

The following example opens a queue with receive access, specifies the body of the message as the only message property to retrieve, and uses a Windows Event mechanism to read the first message of the queue.

//////////////
// Open Queue
//////////////

HRESULT hr;
QUEUEHANDLE hQueue;

hr = MQOpenQueue(
     szwFormatNameBuffer,    // Format Name of the queue to be opened
     MQ_RECEIVE_ACCESS,      // Access rights to the Queue
     0,                      // No receive Exclusive
     &hQueue                 // OUT: handle to the opened Queue
                );

if (FAILED(hr))
{
 // Error handler for MQOpenQueue.
}

MQMSGPROPS * pmsgprops;
MQPROPVARIANT *paVariant;
MSGPROPID * paPropId;
DWORD dwcPropId = 0;

//
//  The output parameters of an asynchronous call to MQReceiveMessage
//  should be kept intact until the operation completes, you cannot
//  free them or reuse them.
//
pmsgprops = new MQMSGPROPS;
paVariant = new MQPROPVARIANT[ 10];
paPropId = new MSGPROPID[ 10];

//////////////////////////////////////////////////
// Prepare the message properties to be retrieved.
/////////////////////////////////////////////////

// Set the PROPID_M_BODY property.
paPropId[dwcPropId] = PROPID_M_BODY;                //PropId
paVariant[dwcPropId].vt = VT_VECTOR|VT_UI1;         //Type
paVariant[dwcPropId].caub.cElems = MSG_BODY_LEN ;    //Value
paVariant[dwcPropId].caub.pElems = new unsigned char[ MSG_BODY_LEN];

 dwcPropId++;

////////////////////////////////
// Initialize the MQMSGPROPS structure
///////////////////////////////

pmsgprops->cProp = dwcPropId;     //Number of properties
pmsgprops->aPropID = paPropId;        //Ids of properties
pmsgprops->aPropVar = paVariant;      //Values of properties
pmsgprops->aStatus  = NULL;           //No Error report

/////////////////////////////////////////
//  Create Event object using OVERLAPPED
//  structure.
/////////////////////////////////////////

OVERLAPPED *pov = new OVERLAPPED ;
pov->hEvent = CreateEvent(0, FALSE, FALSE, 0);

/////////////////////////////////////////
//  Retrieve the message using OVERLAPPED
//  structure.
/////////////////////////////////////////

hr = MQReceiveMessage(
    hQueue,                     // Handle to the Queue
    5 * 60 * 1000,              // Max time (msec) to wait
    MQ_ACTION_RECEIVE,          // Action
    pmsgprops,                  // Properties to retrieve
    pov,                        // OVERLAPPED structure
    NULL,                       // No callback function
    NULL,                       // No Cursor
    NULL                        // No transaction
              );

if (FAILED(hr))
    {
        //  Error handler for MQReceiveMessage.
    }

//////////////////////////////
// Windows Event handler.
//////////////////////////////

if (hr == MQ_INFORMATION_OPERATION_PENDING)
    {
        hr = MQGetOverlappedResult(pov);
        // For MSMQ 1.0 applications, call
        // WaitForSingleObject(pov->hEvent, INFINITE);
    //
    // Parse received results
    //
    }

CloseHandle(pov->hEvent);
delete paVariant;  //Free resources
delete paPropId;


Windows NT/Windows 2000 Completion Port Example

The following procedure shows the basic steps for reading messages using a Windows NT/Windows 2000 completion port. The completion port mechanism allows you to associated a queue handle with a completion port to receive messages asynchronously.

Note Completion ports cannot be used by dependent client applications. On Message Queuing independent clients and servers, queue handles are implemented as Windows NT/Windows 2000 file handles and so, can be associated with completion ports. However, on dependent clients, queue handles are not file handles and as a result, cannot be used with completion ports.

To read a message asynchronously using a completion port

  1. Define the structures needed to retrieve messages, including an OVERLAPPED structure reference by MQReceiveMessage.
  2. Create one or more threads using a generic completion-port-thread start routine.
  3. Call MQOpenQueue to open the queue with receive access, associating its returned queue handle with the completion port.
  4. Call MQReceiveMessage as needed to start retrieving messages. As each message is successfully retrieved, the operating system uses the OVERLAPPED structure to notify the completion port thread handler that the receive event has been completed. (The Windows NT/Windows 2000 scheduler will select the best available completion port thread that is synchronously waiting for a completion notification.)
  5. Call MQCloseQueue to release all resources used to retrieve the messages.
For information on | See
Sample code for using a completion port |
The function used to create a completion ports | CreateIoCompletionPort
The function call used to retrieve the message | MQReceiveMessage


Reading Messages Using a Cursor

Cursors allow you to read a message that is not at the front of the queue. The cursor always maintains its position relative to the message to which it points.

The two functions used to manage the cursor are MQCreateCursor and MQCloseCursor. MQCreateCursor returns a cursor handle that is used in MQReceiveMessage, and MQCloseCursor releases the cursor's resources.

The example below uses a cursor to read the message label of each message in a queue.

To peek at each message in a queue

  1. Define the structures needed to retrieve the label of each message in the queue. See example below.
  2. Set the PROPID_M_LABEL and PROPID_M_LABEL_LEN properties.
  3. Initialize the MQMSGPROPS structure.
  4. Call MQPathNameToFormatName to generate the format name needed to open the queue.
  5. Call MQOpenQueue to open the queue with receive access. Opening the queue for receive access allows you to peek at the messages as well as receive them.
  6. Call MQCreateCursor to create the cursor used to navigate the queue.
  7. Call MQReceiveMessage to retrieve the label of each message in the queue. Note that the receive action parameter is changed to MQ_ACTION_PEEK_NEXT after the first message is read, and that the value of PROPID_M_LABEL_LEN must be reset after each message is read.
  8. Call MQCloseCursor and MQCloseQueue to release the cursor handle and queue handle resources.
For a code example using | See
C++ | C/C++ Code Example


C/C++ Code Example: Reading Messages Using a Cursor

This example peeks at each message in a known queue. If the message has a label, the label is displayed. Note the to navigate through the queue, dwRecAction is set to MQ_ACTION_PEEK_NEXT after the first message is read.

#include <windows.h>
#include <stdio.h>
#include <mq.h>                              // Message Queuing header file

int main(int arg, char *argv[])

{

  #define NUMBER_OF_PROPERTIES  2        // Number of msg properties
  DWORD cPropId = 0;                     // Property counter

  //Define MQMSGPROPS structure.
  MQMSGPROPS msgprops;
  MSGPROPID aMsgPropId[NUMBER_OF_PROPERTIES];
  PROPVARIANT aMsgPropVar[NUMBER_OF_PROPERTIES];
  HRESULT aMsgStatus[NUMBER_OF_PROPERTIES];

  HANDLE hQueue;                 // Queue handle
  HANDLE hCursor;                // Cursor handle
  HRESULT hr;                    // Define results
  DWORD dwAccess;                // Access mode of queue
  DWORD dwShareMode;             // Share mode of queue
  DWORD dwRecAction;             // Receive action

  // Destination queue format name buffer
  DWORD dwDestFormatNameBufferLength = 256;
  WCHAR wszDestFormatNameBuffer[256];

  // Message label buffer
  WCHAR wszLabelBuffer[250];

  /////////////////////////////////////////////////////////////
  // Specify message label.
  /////////////////////////////////////////////////////////////

  aMsgPropId[cPropId] = PROPID_M_LABEL;           // Property ID
  aMsgPropVar[cPropId].vt = VT_LPWSTR;            // Type indicator
  aMsgPropVar[cPropId].pwszVal = wszLabelBuffer;  // Value
  cPropId++;

  aMsgPropId[cPropId] = PROPID_M_LABEL_LEN;       // Property ID
  aMsgPropVar[cPropId].vt=VT_UI4;                 // Type indicator
  aMsgPropVar[cPropId].ulVal= 250;                // Value
  cPropId++;

  /////////////////////////////////////////////////////////////
  // Initialize the MQMSGPROPS structure.
  /////////////////////////////////////////////////////////////

  msgprops.cProp = cPropId;          // Number of message properties
  msgprops.aPropID = aMsgPropId;     // Ids of message properties
  msgprops.aPropVar = aMsgPropVar;   // Values of message properties
  msgprops.aStatus  = aMsgStatus;    // Error reports

  /////////////////////////////////////////////////////////////////
  // Convert destination queue pathname to a format name.
  /////////////////////////////////////////////////////////////////

  hr = MQPathNameToFormatName(L".\\TestQueue",
                              wszDestFormatNameBuffer,
                              &dwDestFormatNameBufferLength);
  if (FAILED(hr))
  {
     fprintf(stderr, "Failed in MQPathNameToFormatName for destination queue, error = 0x%x\n",hr);
     return -1;
  }

  /////////////////////////////////////////////////////////////////
  // Open the destination queue to retrieve the label
  // of each message.
  /////////////////////////////////////////////////////////////////

  dwAccess = MQ_RECEIVE_ACCESS;             // Access mode of queue
  dwShareMode = MQ_DENY_RECEIVE_SHARE;      // Share mode of queue

  hr = MQOpenQueue(wszDestFormatNameBuffer, // Format name of queue
                   dwAccess,                // Access mode
                   dwShareMode,             // Share mode
                   &hQueue                  // OUT: Handle to queue
                   );
  if (FAILED(hr))
  {
     fprintf(stderr, "Failed opening destination queue, error = 0x%x\n",hr);
     return -1;
  }

  /////////////////////////////////////////////////////////////
  // Create the cursor used to navigate through the queue.
  /////////////////////////////////////////////////////////////

  hr = MQCreateCursor(hQueue,          // Queue handle
                      &hCursor         // OUT: Handle to cursor
                      );
  if (FAILED(hr))
  {
     fprintf(stderr, "Failed creating cursor, error = 0x%x\n",hr);
     return -1;
  }

  /////////////////////////////////////////////////////////////
  // Peek at each message in the queue.
  /////////////////////////////////////////////////////////////

  dwRecAction = MQ_ACTION_PEEK_CURRENT; // Receive action

  do
  {
    hr = MQReceiveMessage(hQueue,           // Queue handle
                          0,                // Max time (msec)
                          dwRecAction,      // Receive action
                          &msgprops,        // Msg property structure
                          NULL,             // No OVERLAPPED structure
                          NULL,             // No callback function
                          hCursor,          // Cursor handle
                          NULL              // No transaction
                          );
    if (FAILED(hr))
    {
     fprintf(stderr, "Failed peeking at messages, error = 0x%x\n",hr);
     break;
    }

    if (msgprops.aPropVar[1].ulVal == NULL)
    {
       puts ("Message Label= None.");
    }
    else
    {
      wprintf(L"Message Label: %s.\n",wszLabelBuffer);
    }
    dwRecAction = MQ_ACTION_PEEK_NEXT;  // Reset receive action mode
    aMsgPropVar[1].ulVal= 250;           // Reset PROPID_M_LABEL_LEN

  } while (hr==0);

  /////////////////////////////////////////////////////////////
  // Close cursor and queue.
  /////////////////////////////////////////////////////////////

  hr = MQCloseCursor(hCursor);
  hr = MQCloseQueue(hQueue);

  return 0;

}


Retrieving the Format Name of an Administration Queue

When reading messages, the receiving application can see if the sending application specified an administration queue by checking to see whether the format name of a queue was sent along with the message.

To do this, the receiving application must retrieve the PROPID_M_ADMIN_QUEUE and PROPID_M_ADMIN_QUEUE_LEN properties.

To retrieve the format name of an administration queue

  1. Define the structures needed to retrieve the format name. This includes a format name buffer for the destination queue and administration queue.
  2. Set PROPID_M_ADMIN_QUEUE and PROPID_M_ADMIN_QUEUE_LEN.
  3. Optional. Add additional message properties to the MQMSGPROPS structure as needed.
  4. Initialize the MQMSGPROPS structure.
  5. Call MQPathNameToFormatName to generate format name for destination queue.
  6. Call MQOpenQueue to open the queue with receive access.
  7. Call MQReceiveMessage to retrieve the format name of the administration queue.
  8. Look at the returned value of PROPID_M_ADMIN_QUEUE_LEN to see if a format name was sent with the message. If this length property is not NULL (a format name was sent with the message), look at the format name returned by MQReceiveMessage. The example below prints out the returned format name
  9. Call MQCloseQueue to close the destination queue.
For a code example using | See
C++ | C/C++ Code Example


C/C++ Code Example: Retrieving the Format Name of an Administration Queue

The following example retrieves the format name of an administration queue from the first message in a known public queue.

#include <windows.h>
#include <stdio.h>
#include <mq.h>                              // Message Queuing header file

int main(int arg, char *argv[])

{
  ////////////////////////////////////////////////////////////
  //  Define the required structures.
  ////////////////////////////////////////////////////////////

  #define NUMBEROFPROPERTIES  2   // Number of properties
  DWORD cPropId = 0;              // Property counter

  //Define MQMSGPROPS structure.
  MQMSGPROPS msgprops;
  MSGPROPID aMsgPropId[NUMBEROFPROPERTIES];
  PROPVARIANT aMsgPropVar[NUMBEROFPROPERTIES];
  HRESULT aMsgStatus[NUMBEROFPROPERTIES];

  HANDLE hQueue;                               // Queue handle
  HRESULT hr;                                  // Define results
  DWORD dwAccess = MQ_RECEIVE_ACCESS;          // Access mode of queue
  DWORD dwShareMode = MQ_DENY_RECEIVE_SHARE;   // Share mode of queue
  DWORD dwRecAction = MQ_ACTION_PEEK_CURRENT;  // Receive action

  //Destination queue format name buffer
  DWORD dwDestFormatNameBufferLength = 256;
  WCHAR wszDestFormatNameBuffer[256];

  // Administration queue format name buffer
  DWORD dwAdminFormatNameBufferLength = 256;
  WCHAR wszAdminFormatNameBuffer[256];

  /////////////////////////////////////////////////////////////////
  // Set PROPID_M_ADMIN_QUEUE and PROPID_M_ADMIN_QUEUE_LEN.
  /////////////////////////////////////////////////////////////////

  aMsgPropId[cPropId] = PROPID_M_ADMIN_QUEUE;    // Property ID
  aMsgPropVar[cPropId].vt = VT_LPWSTR;           // Type indicator
  aMsgPropVar[cPropId].pwszVal = wszAdminFormatNameBuffer;
  cPropId++;

  aMsgPropId[cPropId] = PROPID_M_ADMIN_QUEUE_LEN;// Property ID
  aMsgPropVar[cPropId].vt = VT_UI4;              // Type indicator
  aMsgPropVar[cPropId].ulVal = dwAdminFormatNameBufferLength;
  cPropId++;

  /////////////////////////////////////////////////////////////////
  // Add additional message properties here. When additional
  // properties are added, increment cProp to
  // reflect the total number of properties retrieved.
  /////////////////////////////////////////////////////////////////

  /////////////////////////////////////////////////////////////////
  // Initialize the MQMSGPROPS structure.
  /////////////////////////////////////////////////////////////////

  msgprops.cProp = cPropId;            //Number of message properties
  msgprops.aPropID = aMsgPropId;       //Ids of message properties
  msgprops.aPropVar = aMsgPropVar;     //Values of message properties
  msgprops.aStatus  = aMsgStatus;      //Error reports

  /////////////////////////////////////////////////////////////////
  // Convert destination queue pathname to a format name.
  /////////////////////////////////////////////////////////////////

  hr = MQPathNameToFormatName(L".\\TestQueue",
                              wszDestFormatNameBuffer,
                              &dwDestFormatNameBufferLength);
  if (FAILED(hr))
  {
     fprintf(stderr, "Failed in MQPathNameToFormatName for destination queue, error = 0x%x\n",hr);
     return -1;
  }

  /////////////////////////////////////////////////////////////////
  // Open the destination queue to retrieve the format name
  // of the administration queue.
  /////////////////////////////////////////////////////////////////

  hr = MQOpenQueue(wszDestFormatNameBuffer, // Format name of queue
                   dwAccess,                // Access mode
                   dwShareMode,             // Share mode
                   &hQueue                  // OUT: Handle to queue
                   );
  if (FAILED(hr))
  {
     fprintf(stderr, "Failed opening destination queue, error = 0x%x\n",hr);
     return -1;
  }

  ////////////////////////////////////////////////////////////////
  // Retrieve format name of the administration queue
  // (PROPID_M_ADMIN_QUEUE) and the length of the format name
  // PROPID_M_ADMIN_QUEUE_LEN. If the returned value of
  // PROPID_M_ADMIN_QUEUE_LEN is NULL, no administration queue
  // was specified.
  /////////////////////////////////////////////////////////////////

  hr = MQReceiveMessage(
                        hQueue,            // Handle of queue
                        5*60*1000,         // Timeout = 5 minutes
                        dwRecAction,       // How message is retrieved
                            &msgprops,         // Properties to retrieve
                        NULL,              // NULL for sync read
                        NULL,              // NULL for sync read
                            NULL,              // No cursor
                        MQ_NO_TRANSACTION  // No transaction
                        );

  if (FAILED(hr))
  {
     fprintf(stderr, "Failed retrieving format name, error = 0x%x\n",hr);
     return -1;
  }
  if (msgprops.aPropVar[1].ulVal == NULL)
  {
     puts("No acknowledgment messages were requested.");
     return -1;
  }

  puts("The format name of the administration queue is:\n");
  wprintf(L"%s.\n",wszAdminFormatNameBuffer);

  /////////////////////////////////////////////////////////////////
  // Close the queue.
  /////////////////////////////////////////////////////////////////

  hr = MQCloseQueue(hQueue);

  if (FAILED(hr))
  {
     fprintf(stderr, "Failed closing destination queue, error = 0x%x\n",hr);
     return -1;
  }
  return 0;

}


Returning an Acknowledgment Message by a Connector Application

Acknowledgment messages returned by the connector application must be sent to the administration queue specified by the original message. Several properties must be set to the acknowledgment message values shown below, and others should be set to the values specified by the original message.

The following properties must be set to acknowledgment message values shown below.

Property | Setting
PROPID_M_ACKNOWLEDGE | MQMSG_ACKNOWLEDGMENT_NONE
PROPID_M_AUTH_LEVEL | MQMSG_AUTH_LEVEL_NONE
PROPID_M_BODY | For positive acknowledgments set to NULL. For negative acknowledgments (with the exception of encrypted message bodies), set to the body of the original message.
PROPID_M_CORRELATIONID | Message identifier of original message.
PROPID_M_CLASS | Appropriate acknowledgment class.
PROPID_M_JOURNAL | MQMSG_JOURNAL_NONE
PROPID_M_RESP_QUEUE | Destination queue of the original message.
PROPID_M_TIME_TO_BE_RECEIVED | INFINITE
PROPID_M_TIME_TO_REACH_QUEUE | INFINITE

All the other properties are set to the same values as the original message.

To send an acknowledgment message

  1. Open the administration queue specified by the original application.
  2. Set the acknowledgment default value required by Message Queuing.
  3. Set the remaining message properties. Set PROPID_M_BODY, PROPID_M_CORRELATIONID, PROPID_M_CLASS, and PROPID_M_RESP_QUEUE to the values specified above.
  4. Set PROPID_M_CONNECTOR_TYPE. This tells the application reading the acknowledgment message that the message was not created by Message Queuing.
  5. Call MQSendMessage to send the message.
For a code example using | See
C++ | C/C++ Code Example


C/C++ Code Example: Returning an Acknowledgment Message by a Connector Application

The following example creates an acknowledgment message and sends it back to the administration queue specified by the original message. It assumes that the format name of the administration queue (lpstrAdimQueue), all original message properties (pmsgprops), and the value of the acknowledgment (ackValue) are all available.

HRESULT CreateAck(LPWSTR lpstrAdminQueue,
                 USHORT AckValue,
                 MQMSGPROPS* pmsgprops
                 )

{
MQMSGPROPS SendMsgProp;
MSGPROPID     aPropID[40];
MQPROPVARIANT  aPropVar[40];
HRESULT        aStatus[40];
HRESULT        hr;
HANDLE hQueue = NULL;
DWORD cProp = 0;

//////////////////////////////////
// Open the administration queue
// specified by the original message.
/////////////////////////////////
hr = MQOpenQueue(lpstrAdminQueue,MQ_SEND_ACCESS,0, &hQueue);
if (FAILED(hr))
{
// Handle failure
// Return hr;
}

DWORD dwExtensionMsgSize = 0;
DWORD dwSenderidLen = 0;
DWORD dwBodySize = 0;
BOOL fEncrypted = FALSE;
DWORD i;

//////////////////////////////////////////////////
// Set the acknowledgment message default values.
//////////////////////////////////////////////////
aPropID[cProp] = PROPID_M_CLASS;
aPropVar[cProp].vt = VT_UI2;
aPropVar[cprop].uiVal = AckValue;
cProp++;

aPropID[cProp] = PROPID_M_ACKNOWLEDGE;
aPropVar[cProp].vt = VT_UI1;
aPropVar[cProp].bVal = MQMSG_ACKNOWLEDGMENT_NONE;
cProp++;

aPropID[cProp] = PROPID_M_TIME_TO_BE_RECEIVED;
aPropVar[cProp].vt = VT_UI4;
aPropVar[cProp].ulVal = INFINITE;
cProp++;

aPropID[cProp] = PROPID_M_TIME_TO_REACH_QUEUE;
aPropVar[cProp].vt = VT_UI4;
aPropVar[cProp].ulVal = INFINITE;
cProp++;

aPropID[cProp] = PROPID_M_JOURNAL;
aPropVar[cProp].vt = VT_UI1;
aPropVar[cProp].bVal = MQMSG_JOURNAL_NONE;
cProp++;

//////////////////////////////////////
// Set all other message properties to
// the values of the original message.
//////////////////////////////////////

// Get size and length of properties.

for (i = 0; i < pmsgprops->cProp ; i++)
{
switch(pmsgprops->aPropID[i])
{
    case PROPID_M_EXTENSION_LEN:
         dwExtensionMsgSize = pmsgprops->aPropVar[i].ulVal;
         break;

    case PROPID_M_SENDERID_LEN:
         dwSenderidLen = pmsgprops->aPropVar[i].ulVal;
         break;

    case PROPID_M_BODY_SIZE:
         dwBodySize = pmsgprops->aPropVar[i].ulVal;
         break;

    case PROPID_M_PRIV_LEVEL:
         fEncrypted = (pmsgprops->aPropVar[i].ulVal == MQMSG_PRIV_LEVEL_BODY);
            break;

             default:
             break;
   }
}

for (i = 0; i < pmsgprops->cProp ; i++)
{
switch (pmsgprops->aPropID[i])
{

         // Set correlation identifier
        case PROPID_M_MSGID:
            aPropID[NUMBEROFPROPERTIES] = PROPID_M_CORRELATIONID;
            aPropVar[NUMBEROFPROPERTIES].vt = VT_UI1|VT_VECTOR;
            aPropVar[NUMBEROFPROPERTIES].caub.cElems = pmsgprops->aPropVar[i].caub.cElems;
            aPropVar[NUMBEROFPROPERTIES].caub.pElems = pmsgprops->aPropVar[i].caub.pElems;
            cProp++;
            break;

        // Set message priority.
        case PROPID_M_PRIORITY:
            aPropID[NUMBEROFPROPERTIES] = PROPID_M_PRIORITY;
            aPropVar[NUMBEROFPROPERTIES].vt = VT_UI1;
            aPropVar[NUMBEROFPROPERTIES].bVal = pmsgprops->aPropVar[i].bVal;
            cProp++;
            break;

        // Set delivery mode.
        case PROPID_M_DELIVERY:
            aPropID[NUMBEROFPROPERTIES] = PROPID_M_DELIVERY;
            aPropVar[NUMBEROFPROPERTIES].vt = VT_UI1;
            aPropVar[NUMBEROFPROPERTIES].bVal = pmsgprops->aPropVar[i].bVal;
            cProp++;
            break;

        // Set application-specific information
       case PROPID_M_APPSPECIFIC:
            aPropID[NUMBEROFPROPERTIES] = PROPID_M_APPSPECIFIC;
            aPropVar[NUMBEROFPROPERTIES].vt = VT_UI4;
            aPropVar[NUMBEROFPROPERTIES].ulVal = pmsgprops->aPropVar[i].ulVal;
            cProp++;
            break;

        // Set message label to the same
        case PROPID_M_LABEL:
            aPropID[NUMBEROFPROPERTIES] = PROPID_M_LABEL;
            aPropVar[NUMBEROFPROPERTIES].vt = VT_LPWSTR;
            aPropVar[NUMBEROFPROPERTIES].pwszVal = pmsgprops->aPropVar[i].pwszVal;
                cProp++;
                break;
            //

        // Set extension information.
        case PROPID_M_EXTENSION:
            aPropID[NUMBEROFPROPERTIES] = PROPID_M_EXTENSION;
            aPropVar[NUMBEROFPROPERTIES].vt = VT_UI1|VT_VECTOR;
            aPropVar[NUMBEROFPROPERTIES].caub.cElems = dwExtensionMsgSize;
            aPropVar[NUMBEROFPROPERTIES].caub.pElems = pmsgprops->aPropVar[i].caub.pElems;
                cProp++;
                break;

        // Set acknowledge message response queue to
        // the destination queue of the original message.
        case PROPID_M_DEST_QUEUE:
            aPropID[NUMBEROFPROPERTIES] = PROPID_M_RESP_QUEUE;
            aPropVar[NUMBEROFPROPERTIES].vt = VT_LPWSTR;
            aPropVar[NUMBEROFPROPERTIES].pwszVal = pmsgprops->aPropVar[i].pwszVal;
            cProp++;
            break;

        //////////////////////////////////////////////
        // Set message body. If acknowledge is negative
        // and the original message isn't encrypted, add
        // message body of original message.
        //////////////////////////////////////////////
        case PROPID_M_BODY:
            if (MQCLASS_NACK(AckValue) && ! fEncrypted)
            {
                aPropID[NUMBEROFPROPERTIES] = PROPID_M_BODY;
                aPropVar[NUMBEROFPROPERTIES].vt = VT_UI1|VT_VECTOR;
                aPropVar[NUMBEROFPROPERTIES].caub.cElems = dwBodySize;
                aPropVar[NUMBEROFPROPERTIES].caub.pElems = pmsgprops->aPropVar[i].caub.pElems;
                cProp++;
            }
            break;

        default:
            break;
    }
}

//////////////////////////////////////////////////
// Set the connector type identifier (GUID) to
// indicate who generated the acknowledge message.
//////////////////////////////////////////////////
aPropID[NUMBEROFPROPERTIES] = PROPID_M_CONNECTOR_TYPE;
aPropVar[NUMBEROFPROPERTIES].vt = VT_CLSID;
aPropVar[NUMBEROFPROPERTIES].puuid = &g_gConnectorType;
cProp++;

SendMsgProp.aStatus = aStatus;
SendMsgProp.aPropID = aPropID;
SendMsgProp.aPropVar = aPropVar;
SendMsgProp.cProp =cProp;

////////////////////////////////////////////////
// Send the acknowledge message back to the
// administration queue specified by the
// original message.
/////////////////////////////////////////////////
hr = MQSendMessage(hQueue, &SendMsgProp, NULL);

MQCloseQueue(hQueue);

return hr;
}


Requesting and Validating Authentication

The following examples show how the sending application requests authentication when sending messages, and how the receiving application validates authentication when it reads the messages in the queue.

For an example of | See
Sending a message with an internal certificate attached | Requesting Authentication with an Internal Certificate
Sending a message with an external certificate attached | Requesting Authentication with an External Certificate
Retrieving a message to see if authentication was requested | Validating Authenticated Messages


Requesting Authentication with an Internal Certificate

To request authentication with an internal certificate, the sending application must set PROPID_M_AUTH_LEVEL to MQMSG_AUTH_LEVEL_ALWAYS and attach an internal certificate to the message. (Internal certificates cannot be used when operating in a Windows 2000 Workgroup environment.)

Note The certificate can be attached directly (as in the following code example), or Message Queuing can attach the certificate using security context information. You should use security context information when you are sending a large number of authenticated messages that all use the same certificate. For information on obtaining security context information, see MQGetSecurityContext.

Authentication has two parts: ensuring message integrity and validating who sent the message.

Message Queuing ensures message integrity whenever authentication is requested. When the receiving queue manager receives a message for which authentication is requested, it always verifies that no one tampered with or changed the content of the message.

By default, Message Queuing also validates who sent the message, but the sending application can disable this part of authentication by setting the PROPID_M_SENDERID_TYPE property of the message to MQMSG_SENDERID_TYPE_NONE.

Note The receiving application has no part in the authentication of the message. The receiving Message Queuing queue manager authenticates the message before it reaches its destination queue.

To request authentication with an internal certificate

  1. Define the structures needed to send the message to the queue.
  2. Specify PROPID_M_AUTH_LEVEL, setting its value to MQMSG_AUTH_LEVEL_ALWAYS.
  3. Optional. Specify any other message properties that may be needed. For example, you may want to add PROPID_M_ACKNOWLEDGE and PROPID_M_ADMIN_QUEUE to receive acknowledgment messages, PROPID_M_HASH_ALG to change the hash algorithm used when creating the digital signature, or PROPID_M_SECURITY_CONTEXT if you want to use security context information to attach the certificate.

    Note When using internal certificates do not specify PROPID_M_SENDER_CERT. This property is used only with external certificates.

  4. Initialize the MQMSGPROPS structure.
  5. Verify that an internal certificate is registered in your directory service.

    For MSMQ 2.0 applications, call MQRegisterCertificate if the certificate is not registered. By default, MSMQ 2.0 automatically registered an internal certificate the first time a new user logs on to an Message Queuing computer.

    For MSMQ 1.0 applications, you must register certificates by using MS Message Queue in Control Panel. By default, MSMQ 1.0 does not register certificates.

  6. Generate a format name for the queue. This example calls MQPathNameToFormatName to convert a known path name to a format name.
  7. Call MQOpenQueue to open the queue with send access.
  8. Call MQSendMessage to send the message to the queue.
  9. Call MQCloseQueue to release the resources.
For a code example using | See
C++ | C/C++ Code Example


C/C++ Code Example: Requesting Authentication with an Internal Certificate

This example sends a single message requesting authentication using the internal certificate.

#include <windows.h>
#include <stdio.h>
#include <mq.h>                              // Message Queuing header file

int main(int arg, char *argv[]){

  ////////////////////////////////////////////////////////////
  //  Define the required structures.
  ////////////////////////////////////////////////////////////

  #define NUMBER_OF_PROPERTIES  2      // Number of properties
  DWORD cPropId = 0;                   // Property counter

  //Define MQMSGPROPS structure.
  MQMSGPROPS MsgProps;
  MSGPROPID aMsgPropId[NUMBER_OF_PROPERTIES];
  PROPVARIANT aMsgPropVar[NUMBER_OF_PROPERTIES];
  HRESULT aMsgStatus[NUMBER_OF_PROPERTIES];

  // Define variables
  HANDLE hQueue;                               // Queue handle
  HRESULT hr;                                  // Define results
  DWORD dwAccess = MQ_SEND_ACCESS;             // Access mode of queue
  DWORD dwShareMode = MQ_DENY_NONE;            // Share Mode of queue
  DWORD dwCertCreateFlag = MQ_REGISTER_ALWAYS; // Create certificate flag

  // Define format name buffer for destination queue.
  DWORD dwDestFormatNameBufferLength = 256;
  WCHAR wszDestFormatNameBuffer[256];

  /////////////////////////////////////////////////////////////////
  // Specify the authentication level of the message:
  // PROPID_M_AUTH_LEVEL.
  /////////////////////////////////////////////////////////////////
  aMsgPropId[cPropId] = PROPID_M_AUTH_LEVEL;             // Property ID
  aMsgPropVar[cPropId].vt = VT_UI4;                      // Type indicator
  aMsgPropVar[cPropId].ulVal = MQMSG_AUTH_LEVEL_ALWAYS;  // Format name
  cPropId++;

  ////////////////////////////////////////////////////////////////
  // Add additional message properties as needed.
  /////////////////////////////////////////////////////////////////
  aMsgPropId[cPropId] = PROPID_M_LABEL;                // Property ID
  aMsgPropVar[cPropId].vt = VT_LPWSTR;                 // Type indicator
  aMsgPropVar[cPropId].pwszVal = L"Remote Removed API";      // Value
  cPropId++;

  /////////////////////////////////////////////////////////////////
  // Initialize the MQMSGPROPS structure.
  /////////////////////////////////////////////////////////////////
  MsgProps.cProp = cPropId;                         // Number of message properties
  MsgProps.aPropID = aMsgPropId;                    // Ids of message properties
  MsgProps.aPropVar = aMsgPropVar;                  // Values of message properties
  MsgProps.aStatus  = aMsgStatus;                   // Error reports

  /////////////////////////////////////////////////////////////////
  // Register internal certificate.
  /////////////////////////////////////////////////////////////////
  hr = MQRegisterCertificate(dwCertCreateFlag,
                             NULL,
                             0);
  if (FAILED(hr))
  {
    fprintf(stderr, "Failed in MQRegisterCertificate, error = 0x%x\n",hr);
    return -1;
  }

 /////////////////////////////////////////////////////////////////
  // Convert destination queue pathname to a format name.
  /////////////////////////////////////////////////////////////////
  hr = MQPathNameToFormatName(L".\\authtestqueue",
                              wszDestFormatNameBuffer,
                              &dwDestFormatNameBufferLength);
  if (FAILED(hr))
  {
    fprintf(stderr, "Failed in MQPathNameToFormatName for destination queue, error = 0x%x\n",hr);
    return -1;
  }

  /////////////////////////////////////////////////////////////////
  // Open the destination queue to send message.
  /////////////////////////////////////////////////////////////////
  hr = MQOpenQueue(wszDestFormatNameBuffer, // Format name of queue
                   dwAccess,                // Access mode
                   dwShareMode,             // Share mode
                   &hQueue);                // OUT: Handle to queue
  if (FAILED(hr))
  {
    fprintf(stderr, "Failed opening destination queue, error = 0x%x\n",hr);
    return -1;
  }

  /////////////////////////////////////////////////////////////////
  // Send message to the destination queue.
  /////////////////////////////////////////////////////////////////
  hr = MQSendMessage(hQueue,
                     &MsgProps,
                     NULL);
  if (FAILED(hr))
  {
    switch( hr )
    {
    case MQ_ERROR_NO_INTERNAL_USER_CERT:
         puts("Failed sending message! No internal certificate available.\n");
         break;
    default:
         fprintf(stderr, "Failed sending message, error = 0x%x\n",hr);
         break;
    }
    return -1;
  }

  /////////////////////////////////////////////////////////////////
  // Close the queue.
  /////////////////////////////////////////////////////////////////
  hr = MQCloseQueue(hQueue);
  if (FAILED(hr))
  {
    fprintf(stderr, "Failed closing destination queue, error = 0x%x\n",hr);
    return -1;
  }
  puts("The message is sent and the queue is closed.");
  return 0;

}


Requesting Authentication with an External Certificate

To request authentication with an external certificate, the sending application must obtain an external certificate and register it in the Internet Explorer certificate store, then set PROPID_M_AUTH_LEVEL to MQMSG_AUTH_LEVEL_ALWAYS, and attach the external certificate to the message.

Note The certificate can be attached directly (as in the following code example), or Message Queuing can attach the certificate using security context information. You should use security context information when you are sending a large number of authenticated messages that all use the same certificate. For information on obtaining security context information, see MQGetSecurityContext.

Authentication has two parts: ensuring message integrity and validating who sent the message.

Message integrity is ensured every time authentication is requested. When the receiving queue manager receives a message that needs to be authenticated, it always verifies that no one tampered with or changed the content of the message.

By default, Message Queuing also validates who sent the message, but the sending application can disable this part of authentication by setting the PROPID_M_SENDERID_TYPE property of the message to MQMSG_SENDERID_TYPE_NONE.

Note The receiving application has no part in the authentication of the message. The receiving Message Queuing queue manager authenticates the message before it reaches its destination queue.

To request authentication with an external certificate

  1. Obtain a certificate from an authorized certification authority. A common way to obtain a certificate is to request a class 1 certificate from VeriSign Commercial Software Publishers using Microsoft® Internet Explorer. If Internet Explorer is used to obtain the certificate, the certificate is automatically placed in the Microsoft Internet Explorer personal certificate store.

    Note For MSMQ 1.0 applications, use Internet Explorer, version 3.0 or later.

  2. Place the certificate in the Microsoft Internet Explorer personal certificate store (if Internet Explorer was used to obtain the certificate, this is done automatically). Message Queuing can use only certificates placed in this store.
  3. Define the structures needed to send the message to the queue. The example code below starts at this step.
  4. Specify PROPID_M_AUTH_LEVEL, setting it to MQMSG_AUTH_LEVEL_ALWAYS.
  5. Optional. Specify any other message properties that may be needed. For example, you may want to add PROPID_M_ACKNOWLEDGE and PROPID_M_ADMIN_QUEUE to receive acknowledgment messages, PROPID_M_HASH_ALG to change the hash algorithm used when creating the digital signature, or PROPID_M_SECURITY_CONTEXT if you want to use security context information to attach the certificate.
  6. Register the external certificate in your directory service. Message Queuing requires that you to register the external certificate.

    For MSMQ 2.0 applications, call MQRegisterCertificate.

    For MSMQ 1.0 applications, you must register certificates by using MS Message Queue in Control Panel.

  7. Initialize the MQMSGPROPS structure.
  8. Generate a format name for the queue. This example calls MQPathNameToFormatName to convert a known path name to a format name.
  9. Call MQOpenQueue to open the queue with send access.
  10. Call MQSendMessage to send the message to the queue.
  11. Call MQCloseQueue to release the resources.
For a code example using | See
C++ | C/C++ Code Example


C/C++ Code Example: Requesting Authentication with an External Certificate

This example sends a single message requesting authentication using the external certificate registered in "My" store.

#include <windows.h>
#include <stdio.h>
#include <mq.h>                               // Message Queuing header file
#include <wincrypt.h>

int main(int arg, char *argv[])

{
  ////////////////////////////////////////////////////////////
  //  Define the structures needed to send the message.
  ////////////////////////////////////////////////////////////

  #define NUMBEROFPROPERTIES  3               // Number of properties
  DWORD cPropId = 0;                          // Property counter

  //Define MQMSGPROPS structure.
  MQMSGPROPS MsgProps;
  MSGPROPID aMsgPropId[NUMBEROFPROPERTIES];
  PROPVARIANT aMsgPropVar[NUMBEROFPROPERTIES];
  HRESULT aMsgStatus[NUMBEROFPROPERTIES];

  HANDLE hQueue;                              // Queue handle
  HRESULT hr;                                 // Define results.
  DWORD dwAccess = MQ_SEND_ACCESS;            // Access mode of queue
  DWORD dwShareMode = MQ_DENY_NONE;           // Share Mode of queue

  //Destination queue format name buffer
  DWORD dwDestFormatNameBufferLength = 256;
  WCHAR wszDestFormatNameBuffer[256];

  ////////////////////////////////////////////////////////////////////
  // Obtain the external certificate. This example takes the first
  // certificate it finds in "My" store. The code can be modified to
  // find another certificate if necessary.
  ////////////////////////////////////////////////////////////////////

  PCCERT_CONTEXT pContext = NULL ;
  HCERTSTORE hStore = NULL ;
  HCRYPTPROV hProv = NULL ;

  if (!CryptAcquireContextA( &hProv,
                             NULL,
                             NULL,
                             PROV_RSA_FULL,
                             CRYPT_VERIFYCONTEXT))
  {
    return FALSE ;
  }

  hStore = CertOpenSystemStoreA( hProv, "My" ) ;
  if (!hStore)
  {
    return FALSE ;
  }

  // Take first certificate from store
  pContext = CertEnumCertificatesInStore(hStore, NULL) ;
  if (!pContext)
  {
    return FALSE ;
  }

  /////////////////////////////////////////////////////////////////
  // Specify the authentication level of the message:
  // PROPID_M_AUTH_LEVEL and PROPID_M_SENDER_CERT.
  /////////////////////////////////////////////////////////////////

  aMsgPropId[cPropId] = PROPID_M_AUTH_LEVEL;             // Property ID
  aMsgPropVar[cPropId].vt = VT_UI4;                      // Type indicator
  aMsgPropVar[cPropId].ulVal = MQMSG_AUTH_LEVEL_ALWAYS;  // Format name
  cPropId++;

  /////////////////////////////////////////////////////////////////
  // Specify PROPID_M_SENDER_CERT. Security context information
  // is not used in this example.
  /////////////////////////////////////////////////////////////////

  aMsgPropId[cPropId] = PROPID_M_SENDER_CERT;            // Property ID
  aMsgPropVar[cPropId].vt = VT_VECTOR | VT_UI1;          // Type indicator
  aMsgPropVar[cPropId].caub.pElems = pContext->pbCertEncoded ;
  aMsgPropVar[cPropId].caub.cElems = pContext->cbCertEncoded ;
  cPropId++;

  ////////////////////////////////////////////////////////////////
  // Add additional message properties as needed. This example
  // specifies a label for the message (PROPID_M_LABLE) as well.
  /////////////////////////////////////////////////////////////////

  aMsgPropId[cPropId] = PROPID_M_LABEL;                // Property ID
  aMsgPropVar[cPropId].vt = VT_LPWSTR;                 // Type indicator
  aMsgPropVar[cPropId].pwszVal = L"Authentication Test";  // Value
  cPropId++;

  /////////////////////////////////////////////////////////////////
  // Initialize the MQMSGPROPS structure.
  /////////////////////////////////////////////////////////////////

  MsgProps.cProp = cPropId;                         // Number of message properties.
  MsgProps.aPropID = aMsgPropId;                    // IDs of message properties
  MsgProps.aPropVar = aMsgPropVar;                  // Values of message properties
  MsgProps.aStatus  = aMsgStatus;                   // Error reports

  /////////////////////////////////////////////////////////////////
  // Register external certificate in the directory service.
  /////////////////////////////////////////////////////////////////

  DWORD dwCertCreateFlag = MQ_REGISTER_ALWAYS;
  hr = MQRegisterCertificate(dwCertCreateFlag,
                             pContext->pbCertEncoded,
                             pContext->cbCertEncoded);
  if (FAILED(hr))
  {
    fprintf(stderr, "Failed in MQRegisterCertificate, error = 0x%x\n",hr);
    return -1;
  }

  /////////////////////////////////////////////////////////////////
  // Convert destination queue pathname to a format name.
  /////////////////////////////////////////////////////////////////

  hr = MQPathNameToFormatName(L".\\testqueue",
                              wszDestFormatNameBuffer,
                              &dwDestFormatNameBufferLength);
  if (FAILED(hr))
  {
    fprintf(stderr, "Failed in MQPathNameToFormatName for destination queue, error = 0x%x\n",hr);
    return -1;
  }

  /////////////////////////////////////////////////////////////////
  // Open the destination queue to send message.
  /////////////////////////////////////////////////////////////////

  hr = MQOpenQueue(wszDestFormatNameBuffer, // Format name of queue
                   dwAccess,                // Access mode
                   dwShareMode,             // Share mode
                   &hQueue);                // OUT: Handle to queue
  if (FAILED(hr))
  {
    fprintf(stderr, "Failed opening destination queue, error = 0x%x\n",hr);
    return -1;
  }

  /////////////////////////////////////////////////////////////////
  // Send message to the destination queue.
  /////////////////////////////////////////////////////////////////

  hr = MQSendMessage(hQueue,
                     &MsgProps,
                     NULL);
  if (FAILED(hr))
  {
    switch( hr )
    {
      case MQ_ERROR_INVALID_CERTIFICATE:
        puts("Failed sending message! The external certificate is corrupted ");
        puts("or it has not been registered in the Microsoft Internet ") ;
        puts("Explorer personal certificate store.\n");
        break;

      default:
        fprintf(stderr, "Failed sending message, error = 0x%x\n",hr);
        break;
    }
    return -1;
  }

  /////////////////////////////////////////////////////////////////
  // Close the queue.
  /////////////////////////////////////////////////////////////////

  hr = MQCloseQueue(hQueue);
  if (FAILED(hr))
  {
    fprintf(stderr, "Failed closing destination queue, error = 0x%x\n",hr);
    return -1;
  }

  puts("The message is sent and the queue is closed.");
  return 0;

}


Validating Authenticated Messages

To find out if a message was authenticated, the receiving application must look to see if the sending application requested authentication.

Note There is no way for the receiving application to look at a message in a queue to see if Message Queuing failed to authenticate a message. Only messages that pass authentication are sent on to the queue. For this reason, the only way to tell if a message was authenticated is to see if the sending application requested authentication. If the sending application requested authentication and the message is in the queue, the message has been authenticated by Message Queuing.

To see if authentication was requested, retrieve the PROPID_M_AUTHENTICATED property of a message and check its returned value.

If the returned value of PROPID_M_AUTHENTICATED is MQMSG_AUTHENTICATION_REQUESTED, authentication was requested and the receiving queue manager authenticated the message. If the returned value is MQMSG_AUTHENTICATION_NOT_REQUESTED, the sending application did not request authentication, and it is up to the receiving application to decide if it should use the message.

Note For MSMQ 1.0 applications the returned values of PROPID_M_AUTHENTICATED are 1 if authentication was requested, or 0 if it was not.

If the message was authenticated, Message Queuing guarantees that no one tampered with the message, and if the sender identifier was passed along with the message, that the sender identifier found in PROPID_M_SENDERID is the same as the sender identifier used to register the certificate.

Note By default, Message Queuing always attaches the sender identifier to the message. However, if the sending application does not want to verify who sent the message, it can set PROPID_M_SENDERID_TYPE to MQMSG_SENDERID_TYPE_NONE, which in turn tells Message Queuing not to attach the sender identifier to the message.

Message Queuing does not validate the information in the external certificate. It is up to the receiving application to validate whatever additional information is provided by the external certificate.

To validate if a message was authenticated

  1. Specify the structures needed to read a message.
  2. Specify PROPID_M_AUTHENTICATED.
  3. Optionally, specify any other message properties that may be needed. This example also retrieves PROPID_M_SENDERID, PROPID_M_SENDERID_LEN, PROPID_M_SENDERID_TYPE, PROPID_M_LABEL, and PROPID_M_LABEL_LEN.
  4. Initialize the MQMSGPROPS structure.
  5. Obtain a format name for the queue. (The following example calls MQPathNameToFormatName to generate a format name for the queue.)
  6. Call MQOpenQueue to open the queue with receive access.
  7. Call MQCreateCursor to create the cursor for navigating through the queue.
  8. Call MQReceiveMessage to peek at each message in the queue. (This example retieves PROPID_M_AUTHENTICATED to see if authentication was requested and PROPID_SENDERID_TYPE to see if the sender identifier was sent with the message.)
  9. Call MQCloseQueue and MQCloseCursor to free the resources used by Message Queuing.
For a code example using | See
C++ | C/C++ Code Example


C/C++ Code Example: Validating Authenticated Messages

This example peeks at each message in the queue and determines whether the message was authenticated and if it was, whether a sender identifier was passed along with the message.

#include <windows.h>
#include <stdio.h>
#include <mq.h>                              // Message Queuing header file

int main(int arg, char *argv[])

{

  #define NUMBER_OF_PROPERTIES  6        // Number of msg properties
  DWORD cPropId = 0;                     // Property counter

  //Define MQMSGPROPS structure.
  MQMSGPROPS msgprops;
  MSGPROPID aMsgPropId[NUMBER_OF_PROPERTIES];
  PROPVARIANT aMsgPropVar[NUMBER_OF_PROPERTIES];
  HRESULT aMsgStatus[NUMBER_OF_PROPERTIES];

  HANDLE hQueue;                 // Queue handle
  HANDLE hCursor;                // Cursor handle
  HRESULT hr;                    // Define results
  DWORD dwAccess;                // Access mode of queue
  DWORD dwShareMode;             // Share mode of queue
  DWORD dwRecAction;             // Receive action

  // Destination queue format name buffer
  DWORD dwDestFormatNameBufferLength = 256;
  WCHAR wszDestFormatNameBuffer[256];

  // Label buffer
  WCHAR wszLabelBuffer[250];

  // SID binary buffer
  DWORD dwSIDBufferLength = 128;
  UCHAR *pucSIDBuffer = (UCHAR *)malloc(dwSIDBufferLength);

  /////////////////////////////////////////////////////////////
  // Specify message properties. This example looks at the
  // following properties: PROPID_M_AUTHENTICATED,
  /////////////////////////////////////////////////////////////

  aMsgPropId[cPropId] = PROPID_M_AUTHENTICATED;  // Property ID
  aMsgPropVar[cPropId].vt = VT_NULL;             // Type indicator
  aMsgPropVar[cPropId].bVal;                     // Value
  cPropId++;

  aMsgPropId[cPropId] = PROPID_M_SENDERID_TYPE;  // Property ID
  aMsgPropVar[cPropId].vt = VT_NULL;             // Type indicator
  aMsgPropVar[cPropId].ulVal;                    // Value
  cPropId++;

  aMsgPropId[cPropId] = PROPID_M_SENDERID_LEN;      // Property ID
  aMsgPropVar[cPropId].vt = VT_UI4;                 // Type indicator
  cPropId++;

  aMsgPropId[cPropId] = PROPID_M_SENDERID;            // Property ID
  aMsgPropVar[cPropId].vt = VT_VECTOR|VT_UI1;         // Type indicator
  aMsgPropVar[cPropId].caub.pElems = (UCHAR*)pucSIDBuffer;
  aMsgPropVar[cPropId].caub.cElems = dwSIDBufferLength;
  cPropId++;

  aMsgPropId[cPropId] = PROPID_M_LABEL;               // Property ID
  aMsgPropVar[cPropId].vt = VT_LPWSTR;                // Type indicator
  aMsgPropVar[cPropId].pwszVal = wszLabelBuffer;
  cPropId++;

  aMsgPropId[cPropId] = PROPID_M_LABEL_LEN;           // Property ID
  aMsgPropVar[cPropId].vt =VT_UI4;                    // Type indicator
  aMsgPropVar[cPropId].ulVal = 250;                   // Label buffer size
  cPropId++;

  /////////////////////////////////////////////////////////////
  // Initialize the MQMSGPROPS structure.
  /////////////////////////////////////////////////////////////

  msgprops.cProp = cPropId;                           // Number of message properties
  msgprops.aPropID = aMsgPropId;                      // Ids of message properties
  msgprops.aPropVar = aMsgPropVar;                    // Values of message properties
  msgprops.aStatus  = aMsgStatus;                     // Error reports

  /////////////////////////////////////////////////////////////////
  // Convert destination queue pathname to a format name.
  /////////////////////////////////////////////////////////////////

  hr = MQPathNameToFormatName(L".\\TestQueue",
                              wszDestFormatNameBuffer,
                              &dwDestFormatNameBufferLength);
  if (FAILED(hr))
  {
    fprintf(stderr, "Failed in MQPathNameToFormatName for destination queue, error = 0x%x\n",hr);
    return -1;
  }

  /////////////////////////////////////////////////////////////////
  // Open the destination queue to retrieve messages.
  /////////////////////////////////////////////////////////////////

  dwAccess = MQ_RECEIVE_ACCESS;             // Access mode of queue
  dwShareMode = MQ_DENY_RECEIVE_SHARE;      // Share mode of queue

  hr = MQOpenQueue(wszDestFormatNameBuffer, // Format name of queue
                   dwAccess,                // Access mode
                   dwShareMode,             // Share mode
                   &hQueue);                // OUT: Handle to queue
  if (FAILED(hr))
  {
    fprintf(stderr, "Failed opening destination queue, error = 0x%x\n",hr);
    return -1;
  }

  /////////////////////////////////////////////////////////////
  // Create the cursor used to navigate through the queue.
  /////////////////////////////////////////////////////////////

  hr = MQCreateCursor(hQueue,                         // Queue handle
                      &hCursor);                      // OUT: Handle to cursor
  if (FAILED(hr))
  {
    fprintf(stderr, "Failed creating cursor, error = 0x%x\n",hr);
    return -1;
  }

  /////////////////////////////////////////////////////////////
  // Peek at each message in the queue.
  /////////////////////////////////////////////////////////////

  dwRecAction = MQ_ACTION_PEEK_CURRENT;               // Receive action

  do
  {
    hr = MQReceiveMessage(hQueue,                     // Queue handle
                          0,                          // Max time (msec)
                          dwRecAction,                // Receive action
                          &msgprops,                  // Msg property structure
                          NULL,                       // No OVERLAPPED structure
                          NULL,                       // No callback function
                          hCursor,                    // Cursor handle
                          NULL);                      // No transaction
    if (FAILED(hr))
    {
      switch( hr )
      {
      case MQ_ERROR_LABEL_BUFFER_TOO_SMALL:
           aMsgPropVar[5].ulVal= 250;                 // Reset PROPID_M_LABEL_LEN.
           dwRecAction = MQ_ACTION_PEEK_CURRENT;      // Reset receive action mode.
           hr = MQReceiveMessage(hQueue,              // Queue handle
                                 0,                   // Max time (msec)
                                 dwRecAction,         // Receive action
                                 &msgprops,           // Msg property structure
                                 NULL,                // No OVERLAPPED structure
                                 NULL,                // No callback function
                                 hCursor,             // Cursor handle
                                 NULL);               // No transaction
           if (FAILED(hr))
           {
             fprintf(stderr, "Failed reading message, error = 0x%x\n",hr);
             return -1;
           }

      case MQ_ERROR_SENDERID_BUFFER_TOO_SMALL:
           free(pucSIDBuffer);
           pucSIDBuffer = (UCHAR *)malloc(msgprops.aPropVar[2].ulVal);
           msgprops.aPropVar[3].caub.pElems = (UCHAR*)pucSIDBuffer;
           msgprops.aPropVar[3].caub.cElems = msgprops.aPropVar[2].ulVal;
           dwRecAction = MQ_ACTION_PEEK_CURRENT;      // Reset receive action mode
           hr = MQReceiveMessage(hQueue,              // Queue handle
                                 0,                   // Max time (msec)
                                 dwRecAction,         // Receive action
                                 &msgprops,           // Msg property structure
                                 NULL,                // No OVERLAPPED structure
                                 NULL,                // No callback function
                                 hCursor,             // Cursor handle
                                 NULL);               // No transaction
           if (FAILED(hr))
           {
             fprintf(stderr, "Failed reading message, error = 0x%x\n",hr);
             return -1;
           }
           break;

      case MQ_ERROR_IO_TIMEOUT:
           fprintf(stderr, "All messages have been read. Time-out error (0x%x) returned.\n",hr);
           return -1;

      default:
           fprintf(stderr, "Failed reading message, error = 0x%x\n",hr);
           return -1;
      }
    }

    if (msgprops.aPropVar[0].bVal == 0)
    {
      wprintf(L"Message \"%s\" was not authenticated.\n",wszLabelBuffer);
    }
    else
    {
      wprintf(L"Message \"%s\" was authenticated.\n",wszLabelBuffer);
      switch(msgprops.aPropVar[1].ulVal )
      {
        case MQMSG_SENDERID_TYPE_NONE:
             wprintf(L"It was sent without an SID.\n");
             break;

        case MQMSG_SENDERID_TYPE_SID:
          wprintf(L"It was sent with an SID.\n");
          break;

        default:
          wprintf(L"It was sent with an unknown type of sender identification.\n");
          break;
      }
    }

    dwRecAction = MQ_ACTION_PEEK_NEXT;  // Reset receive action mode

  } while (hr==0);

  /////////////////////////////////////////////////////////////
  // Close cursor and queue.
  /////////////////////////////////////////////////////////////

  hr = MQCloseCursor(hCursor);
  hr = MQCloseQueue(hQueue);
  return 0;

}


Requesting Journaling

You can request journaling both for queues (target journaling) and computers (source journaling).

The following examples show how to request target and source journaling and how to read messages from the appropriate queue journal, computer journal, and dead-letter queue.

Note Applications cannot send messages to journal or dead-letter queues. When queue or source journaling is requested, Message Queuing sends a copy of message to the appropriate journal or dead-letter queue.

For an example of | See
Requesting target journaling when creating a queue | Requesting Target Journaling
Requesting source journaling when sending a message | Requesting Source Journaling
Reading messages from a queue journal | Reading Messages from a Queue Journal
Reading messages from a computer journal | Reading Messages from a Computer Journal
Reading messages from a dead-letter queue | Reading Messages from a Dead-Letter Queue


Requesting Target Journaling

Target journaling is requested by setting the journaling level (PROPID_Q_JOURNAL) of the queue. You can set the journaling level of the queue when you create the queue or later.

Note The following example sets the journaling level when creating a queue. To set the journaling level after the queue is created, call MQSetQueueProperties.

To request target journaling

  1. Define the structures needed to create the queue.
  2. Specify PROPID_Q_PATHNAME, PROPID_Q_JOURNAL, and PROPID_Q_JOURNAL_QUOTA in the MQQUEUEPROPS structure. In this example, "." is used to indicate the local computer.

    Note For Message Queuing servers and independent clients, the local machine is the local computer. However, for Message Queuing–dependent clients, the local machine is the client's Message Queuing server.

  3. Optional. Add additional queue properties as needed. In this example, PROPID_Q_LABEL is set to "Test Queue".
  4. Initialize the MQQUEUEPROPS structure.
  5. Call MQCreateQueue to create the queue.
For a code example using | See
C++ | C/C++ Code Example


C/C++ Code Example: Requesting Target Journaling

The following example requests target journaling while creating a public queue.

#include <windows.h>
#include <stdio.h>
#include <mq.h>                                       // Message Queuing header file

int main(int arg, char *argv[])

{
  ////////////////////////////////////////////////////////////
  //  Define structures needed to create queue.
  ////////////////////////////////////////////////////////////

  #define NUMBER_OF_PROPERTIES 4                      // Number of queue properties
  DWORD cPropId = 0;                                  // Define the property counter.

  //Define the MQQUEUPROPS structure.
  MQQUEUEPROPS QueueProps;
  PROPVARIANT aQueuePropVar[NUMBER_OF_PROPERTIES];
  QUEUEPROPID aQueuePropId[NUMBER_OF_PROPERTIES];
  HRESULT aQueueStatus[NUMBER_OF_PROPERTIES];

  HRESULT hr;                                         // Define results.
  PSECURITY_DESCRIPTOR pSecurityDescriptor=NULL;      // Security descriptor

  // Queue pathname
  LPWSTR wszPathName = L".\\TestQueue";

  // Queue label
  LPWSTR wszQueueLabel = L"Test Queue";

  // Format name buffer for queue
  DWORD dwFormatNameBufferLength = 256;               // Length of format name buffer
  WCHAR wszFormatNameBuffer[256];                     // Format name buffer

  /////////////////////////////////////////////////////////////////
  // Specify PROPID_Q_PATHNAME, PROPID_Q_JOURNAL, and
  // PROPID_Q_JOURNAL_QUOTA.
  /////////////////////////////////////////////////////////////////

  aQueuePropId[cPropId] = PROPID_Q_PATHNAME;          // Property ID
  aQueuePropVar[cPropId].vt = VT_LPWSTR;              // Type indicator
  aQueuePropVar[cPropId].pwszVal = wszPathName;       // Pathname of queue
  cPropId++;
   aQueuePropId[cPropId] = PROPID_Q_JOURNAL;          // Property ID
  aQueuePropVar[cPropId].vt = VT_UI1;                 // Type indicator
  aQueuePropVar[cPropId].bVal = MQ_JOURNAL;           // Journaling level
  cPropId++;

  aQueuePropId[cPropId] = PROPID_Q_JOURNAL_QUOTA;     // Property ID
  aQueuePropVar[cPropId].vt = VT_UI4 ;                // Type indicator
  aQueuePropVar[cPropId].ulVal = 1000;                // Quota in kilobytes
  cPropId++;

  /////////////////////////////////////////////////////////////////
  // Add additional queue properties here. When adding properties,
  // increment NUMBER_OF_PROPERTIES to reflect total number of
  // properties.
  /////////////////////////////////////////////////////////////////

  aQueuePropId[cPropId] = PROPID_Q_LABEL;             // Property ID
  aQueuePropVar[cPropId].vt = VT_LPWSTR;              // Type indicator
  aQueuePropVar[cPropId].pwszVal = wszQueueLabel;     // Label of queue
  cPropId++;

  /////////////////////////////////////////////////////////////////
  // Initialize the MQQUEUEPROPS structure.
  /////////////////////////////////////////////////////////////////

  QueueProps.cProp = cPropId;                         // Number of properties
  QueueProps.aPropID = aQueuePropId;                  // Ids of properties
  QueueProps.aPropVar = aQueuePropVar;                // Values of properties
  QueueProps.aStatus = aQueueStatus;                  // Error reports

  /////////////////////////////////////////////////////////////////
  //Create the Queue.
  /////////////////////////////////////////////////////////////////

  hr = MQCreateQueue(pSecurityDescriptor,             // Security descriptor
                     &QueueProps,                     // Queue properties
                     wszFormatNameBuffer,             // OUT: Format name of queue
                     &dwFormatNameBufferLength);      // OUT: Format name length
  if (FAILED(hr))
  {
    switch( hr )
    {
      case MQ_ERROR_QUEUE_EXISTS:
        fprintf(stderr, "The queue already exists!\n");
        break;
      default:
        fprintf(stderr, "Failed creating queue, error = 0x%x\n",hr);
        break;
    }
    return -1;
  }

  puts ("The queue is created with target journaling enabled!");
  return 0;

}


Requesting Source Journaling

Source journaling is requested by setting the journaling property of a message to MQMSG_JOURNAL, MQMSG_DEADLETTER, or both.

To track messages that were successfully sent by the local computer, set the journaling property of the message to MQMSG_JOURNAL. This tells Message Queuing to always save a copy of each message that it successfully sent.

This means that when you send messages to remote computers, a copy of the message is placed in the source computer's computer journal queue if the message was sent successfully. Note that this does not mean the message has successfully reached its destination queue, only that the computer was able to send the message.

On the other hand, when you send messages to local queues, a copy of the message is saved to the computer's journal queue only after the message has been removed from the local destination queue.

Message Queuing never stores more than one copy of a message on a single computer at one time. Therefore, if the local destination queue has also enabled target journaling, a copy of the message is placed in that queue's journal when the message is removed from the queue; the message is not, however, saved to the computer's journal queue. If, on the other hand, the local destination queue has not enabled target journaling, a copy of the message is placed in the computer's journal when the message is removed from the destination queue.

To track messages that were not delivered, set the journaling property of the message to MQMSG_DEADLETTER. When you specify this type of source journaling, Message Queuing reacts differently depending on the type of message you send.

For non-transactional messages, a copy of the message is placed in the dead-letter queue of any computer that cannot deliver the message. This can be the source computer, or any routing server used to pass the message on to its destination.

For transactional messages, a copy of the message is placed in the transactional dead letter queue of the source computer only if Message Queuing does not confirm that the message was retrieved from its destination queue. Confirmation is not returned if the message is not delivered, was not received, or the receiving transaction was aborted. These messages may be used as a guaranteed negative acknowledgment.

Note For transactional messages, MSMQ 1.0 and MSMQ 2.0 act differently.

MSMQ 1.0 only allows you to choose if you want to save copies of messages sent successfully. MSMQ 1.0 always sends non-confirmed transactional message to the transactional dead-letter queue, regardless of whether MQMSG_DEADLETTER is or is not specified.

MSMQ 2.0 allows complete control over source journaling. (If you are running MSMQ 1.0 applications on an MSMQ 2.0 computer, you can force the computer to use the MSMQ 1.0 semantics by setting the XactDeadLetterAlways registry entry to 1.)

To request source journaling

The example code provided here sends a non-transactional message to a remote queue, setting the journaling property to MQMSG_JOURNAL, which means a copy of the message will be saved if the message is successfully sent.

  1. Define the message property structures.
  2. Set the journal property PROPID_M_JOURNAL as needed. This example sets the journaling level to MQMSG_JOURNAL.
  3. Optional. Set additional message properties as needed. This example also sets the label of the message.
  4. Initialize the MQMSGPROPS structure.
  5. Open destination queue to send messages. This example calls MQPathNameToFormatName to convert a known pathname to a format name. Then calls MQOpenQueue to open the destination queue with send access.
  6. Call MQSendMessage to send the message to the destination queue. A copy of the message will be placed in the journal queue of the source computer as soon as the message is successfully sent.
  7. Call MQCloseQueue to close the destination queue.
For a code example using | See
C++ | C/C++ Code Example


C/C++ Code Example: Requesting Source Journaling

This example sends a message to a remote computer, requesting Message Queuing to keep a copy of the message if it is sent successfully.

# include <windows.h>
# include <stdio.h>
# include <mq.h>                                // Message Queuing header file

int main(int arg, char[])
{

  //////////////////////////////////////////////////////////////////
  // Define message property structure.
  //////////////////////////////////////////////////////////////////
  #define NUMBEROFPROPERTIES 2
  DWORD cPropId = 0;

  MQMSGPROPS MsgProps;
  MSGPROPID aMsgPropId[NUMBEROFPROPERTIES];
  MQPROPVARIANT aMsgPropVar[NUMBEROFPROPERTIES];
  HRESULT aMsgStatus[NUMBEROFPROPERTIES];

  HRESULT hr;

  //////////////////////////////////////////////////////////////////
  // Set journal property PROPID_M_JOURNAL.
  //////////////////////////////////////////////////////////////////
  aMsgPropId[cPropId] = PROPID_M_JOURNAL;
  aMsgPropVar[cPropId].vt = VT_UI1;
  aMsgPropVar[cPropId].bVal = MQMSG_JOURNAL;
  cPropId++;

  //////////////////////////////////////////////////////////////////
  // Set additional message properties. This example also sets
  // the message label property PROPID_M_LABEL.
  //////////////////////////////////////////////////////////////////
  aMsgPropId[cPropId] = PROPID_M_LABEL;
  aMsgPropVar[cPropId].vt = VT_LPWSTR;
  aMsgPropVar[cPropId].pwszVal = L"Test Message";
  cPropId++;

  //////////////////////////////////////////////////////////////////
  // Initialize the MQMSGPROPS structure.
  //////////////////////////////////////////////////////////////////
  MsgProps.cProp = cPropId;
  MsgProps.aPropID = aMsgPropId;
  MsgProps.aPropVar = aMsgPropVar;
  MsgProps.aStatus = aMsgStatus;

  //////////////////////////////////////////////////////////////////
  // Open destination queue with send access.
  //////////////////////////////////////////////////////////////////
  DWORD dwDestFormatNameBufferLength = 256;
  WCHAR szDestFormatNameBuffer[256];

  hr = MQPathNameToFormatName (L"remotecomputername\\TestQueue",
                               szDestFormatNameBuffer,
                               &dwDestFormatNameBufferLength);
  if (FAILED(hr))
  {
    fprintf(stderr, "Failed in MQPathNameToFormatName, error = 0x%x\n",hr);
    return -1;
  }

  HANDLE hQueue;
  DWORD dwAccess = MQ_SEND_ACCESS;
  DWORD dwShareMode = MQ_DENY_NONE;

  hr = MQOpenQueue (szDestFormatNameBuffer,
                    dwAccess,
                    dwShareMode,
                    &hQueue);
  if (FAILED(hr))
  {
    fprintf(stderr, "Failed in MQOpenQueue, error = 0x%x\n",hr);
 return -1;
  }

  //////////////////////////////////////////////////////////////////
  // Send message.
  //////////////////////////////////////////////////////////////////
  hr = MQSendMessage (hQueue,
                      &MsgProps,
                      NULL);
  if (FAILED(hr))
  {
    fprintf(stderr, "Failed in MQSendMessage, error = 0x%x\n",hr);
    return -1;
  }

  //////////////////////////////////////////////////////////////////
  // Close queue.
  //////////////////////////////////////////////////////////////////
  hr = MQCloseQueue (hQueue);
  if (FAILED(hr))
  {
    fprintf(stderr, "Failed in MQCloseQueue, error = 0x%x\n",hr);
    return -1;
  }

  puts("The message is sent. Check journal queue for copy of message.");
  return 0;

}


Reading Messages from a Queue Journal

To read messages from a queue journal you must first obtain the format name of the destination queue it is associated with.

The format name of the destination queue is combined with the "JOURNAL keyword to create the format name of the queue journal. Here is the syntax of a queue journal for both a public and private destination queue.

PUBLIC=QueueGUID;JOURNAL
(where PUBLIC=QueueGUID is the format name of a public destination queue.)

PRIVATE=MachineGUID\QueueNumber;JOURNAL
(where PRIVATE=MachineGUID\QueueNumber is the format name of a private destination queue.)

To retrieve a message from a queue journal

  1. Specify the structures needed to retrieve the message.
  2. Specify the message properties you want to retrieve. The following examples retrieve the label of the message.
  3. Initialize the MQMSGPROPS structure.
  4. Generate the format name for the destination queue. The following examples call MQPathNameToFormatName to generate a format name for the destination queue.
  5. Construct the format name for the queue journal. The syntax of the format name will very depending on the destination queue type (see the preceding format name examples).
  6. Call MQOpenQueue to open the queue with receive access.
  7. Call MQReceiveMessage to retrieve the first message in the queue.
  8. Call MQCloseQueue to free the resources used by the open queue.
For a code example using | See
C++ | C/C++ Code Example


C/C++ Code Example: Reading Messages from a Queue Journal

This example retrieves the first message in a queue journal.

#include <windows.h>
#include <stdio.h>
#include <mq.h>                // Message Queuing header file
#include <string.h>            // Defines wcscat

int main(int arg, char *argv[])

{
  ////////////////////////////////////////////////////////////
  //  Define the required structures.
  ////////////////////////////////////////////////////////////

  #define NUMBER_OF_PROPERTIES  2                     // Number of msg properties
  DWORD cPropId = 0;                                  // Property counter

  //Define MQMSGPROPS structure.
  MQMSGPROPS msgprops;
  MSGPROPID aMsgPropId[NUMBER_OF_PROPERTIES];
  PROPVARIANT aMsgPropVar[NUMBER_OF_PROPERTIES];
  HRESULT aMsgStatus[NUMBER_OF_PROPERTIES];

  HRESULT hr;                                         // Define results
  HANDLE hQueue;                                      // Handle of created queue
  DWORD dwAccess = MQ_RECEIVE_ACCESS;                 // Access mode of queue
  DWORD dwShareMode = MQ_DENY_RECEIVE_SHARE;          // Share Mode of queue
  DWORD dwReceiveAction = MQ_ACTION_RECEIVE;          // Receive action
  DWORD dwFormatNameBufferLength = 256;               // Length of format name buffer
  WCHAR szFormatNameBuffer[256];                      // Format name buffer

  // Specify message label buffer.
  WCHAR wszLabelBuffer[250];

  /////////////////////////////////////////////////////////////
  // Specify the message properties.
  /////////////////////////////////////////////////////////////

  aMsgPropId[cPropId] = PROPID_M_LABEL_LEN;        // Property ID
  aMsgPropVar[cPropId].vt =VT_UI4;                 // Type indicator
  aMsgPropVar[cPropId].ulVal = 250;                // Label buffer size
  cPropId++;

  aMsgPropId[cPropId] = PROPID_M_LABEL;            // Property ID
  aMsgPropVar[cPropId].vt = VT_LPWSTR;             // Type indicator
  aMsgPropVar[cPropId].pwszVal = wszLabelBuffer;   // Label buffer
  cPropId++;

  /////////////////////////////////////////////////////////////
  // Initialize the MQMSGPROPS structure.
  /////////////////////////////////////////////////////////////
  msgprops.cProp = cPropId;          // Number of message properties
  msgprops.aPropID = aMsgPropId;     // Ids of message properties
  msgprops.aPropVar = aMsgPropVar;   // Values of message properties
  msgprops.aStatus  = aMsgStatus;    // Error reports

  /////////////////////////////////////////////////////////////////
  // Generate the destination queue's format name using
  // MQPathNameToFormatName.
  /////////////////////////////////////////////////////////////////

  hr = MQPathNameToFormatName(L".\\TestQueue",
                              szFormatNameBuffer,
                              &dwFormatNameBufferLength);
  if (FAILED(hr))
  {
    fprintf(stderr, "Failed in MQPathNameToFormatName, error = 0x%x\n",hr);
    return -1;
  }

  /////////////////////////////////////////////////////////////////
  // Construct the queue journal's format name by appending
  // ";JOURNAL" to the format name of the destination queue.
  /////////////////////////////////////////////////////////////////

  wcscat(szFormatNameBuffer, L";JOURNAL");

  /////////////////////////////////////////////////////////////////
  // Open the queue journal to retrieve the message.
  /////////////////////////////////////////////////////////////////

  hr = MQOpenQueue(szFormatNameBuffer,     // Format name of queue
                   dwAccess,               // Access mode
                   dwShareMode,            // Share mode
                   &hQueue);               // OUT: Handle to queue
  if (FAILED(hr))
  {
    fprintf(stderr, "Failed in MQOpenQueue, error = 0x%x\n",hr);
    return -1;
  }

  ///////////////////////////////////////////////////////////////////
  // Retrieve the first message from the queue journal.
  ///////////////////////////////////////////////////////////////////

  hr = MQReceiveMessage(hQueue,                       // Queue handle
                        0,                            // Max time (msec)
                        dwReceiveAction,              // Receive action
                        &msgprops,                    // Msg property structure
                        NULL,                         // No OVERLAPPED structure
                        NULL,                         // No callback function
                        NULL,                         // No cursor
                        NULL);                        // No transaction
  if (FAILED(hr))
  {
    fprintf(stderr, "Failed in MQReceiveMessage, error = 0x%x\n",hr);
    return -1;
  }

  printf("A message was retrieved from the queue journal.\n");

  /////////////////////////////////////////////////////////////////
  // Close the queue.
  /////////////////////////////////////////////////////////////////

  hr = MQCloseQueue(hQueue);
  if (FAILED(hr))
  {
    fprintf(stderr, "Failed in MQCloseQueue, error = 0x%x\n",hr);
    return -1;
  }

  return 0;

}


Reading Messages from a Computer Journal

To read messages from a computer journal you must first obtain the machine identifier (GUID) of the computer associated with the computer journal.

The machine identifier is combined with the "Machine" and "JOURNAL keywords to create the format name of the computer journal. Here is the syntax of format name for the computer journal.

Machine=MachineGUID;JOURNAL

To retrieve a message from a computer journal

  1. Specify the structures needed to retrieve the message.
  2. Specify PROPID_QM_MACHINE_ID. This identifier is the machine GUID used in the format name of the computer journal.
  3. Initialize an MQQMPROPS structure.
  4. Specify the message properties to be retrieved.
  5. Initialize an MQMSGPROPS structure.
  6. Call MQGetMachineProperties to retrieve the machine identifier (PROPID_QM_MACHINE_ID) of the local computer.
  7. Construct the format name of the queue.
  8. Call MQOpenQueue and open the queue with receive access.
  9. Call MQReceiveMessage and retrieve message from the computer journal.
  10. Call MQCloseQueue to free the resources used by the open queue.
For a code example using | See
C++ to read messages from the computer journal | C/C++ Code Example


C/C++ Code Example: Reading Messages from a Computer Journal

This example retrieves the first message in a computer journal.

#include <windows.h>
#include <stdio.h>
#include <mq.h>                // Message Queuing header file
#include <rpc.h>               // Defines UuidToString and RpcStringFree

int main(int arg, char *argv[])

{
  ////////////////////////////////////////////////////////////
  //  Define required structures.
  ////////////////////////////////////////////////////////////

  #define NUMBER_OF_PROPERTIES 1                      // Number of QM properties
  DWORD cPropId=0;                                    // Property counter

  // Define queue manager property structure
  MQQMPROPS QMProps;
  QMPROPID aQMPropId[NUMBER_OF_PROPERTIES];           // Property ID array
  PROPVARIANT aQMPropVar[NUMBER_OF_PROPERTIES];       // Property value array
  HRESULT aQMStatus[NUMBER_OF_PROPERTIES];            // Property status array

  #define NUMBER_OF_MSGPROPERTIES  2                   // Number of msg properties
  DWORD cMsgPropId = 0;                                // Property counter

  // Define message property structure.
  MQMSGPROPS msgprops;
  MSGPROPID aMsgPropId[NUMBER_OF_MSGPROPERTIES];
  PROPVARIANT aMsgPropVar[NUMBER_OF_MSGPROPERTIES];
  HRESULT aMsgStatus[NUMBER_OF_MSGPROPERTIES];

  HRESULT hr;                                         // Define results.
  QUEUEHANDLE hQueue;                                 // Handle of created queue.
  DWORD dwAccess = MQ_RECEIVE_ACCESS;                 // Access mode of queue
  DWORD dwShareMode = MQ_DENY_RECEIVE_SHARE;          // Share mode of queue
  DWORD dwReceiveAction = MQ_ACTION_RECEIVE;          // Receive action mode

  DWORD dwFormatNameBufferLength = 256;               // Length of format name buffer
  WCHAR wszFormatNameBuffer[256];                     // Wide Format name buffer

  // Specify message label buffer.
  WCHAR wszLabelBuffer[250];

  //Buffers and string for translating Machine GUID
  CLSID guidMachineId;                                // Buffer for Machine GUID
  CHAR  szFormatNameBuffer[256];                      // Format name buffer
  UCHAR *pszUuid = 0;                                 // String GUID

  /////////////////////////////////////////////////////////////////
  // Specify Machine ID property
  /////////////////////////////////////////////////////////////////

  aQMPropId[cPropId] = PROPID_QM_MACHINE_ID;          // Property ID
  aQMPropVar[cPropId].vt = VT_CLSID;                  // Type indicator
  aQMPropVar[cPropId].puuid = &guidMachineId;         // GUID buffer
  cPropId++;

  /////////////////////////////////////////////////////////////////
  // Initialize MQQMPROPS structure.
  /////////////////////////////////////////////////////////////////

  QMProps.cProp = cPropId;                            // Number of QM properties
  QMProps.aPropID = aQMPropId;                        // IDs of properties
  QMProps.aPropVar = aQMPropVar;                      // Values of properties
  QMProps.aStatus = aQMStatus;                        // Error reports

  /////////////////////////////////////////////////////////////
  // Specify the message properties.
  /////////////////////////////////////////////////////////////

  aMsgPropId[cMsgPropId] = PROPID_M_LABEL_LEN;        // Property ID
  aMsgPropVar[cMsgPropId].vt =VT_UI4;                 // Type indicator
  aMsgPropVar[cMsgPropId].ulVal = 250;                // Label buffer size
  cMsgPropId++;

  aMsgPropId[cMsgPropId] = PROPID_M_LABEL;            // Property ID
  aMsgPropVar[cMsgPropId].vt = VT_LPWSTR;             // Type indicator
  aMsgPropVar[cMsgPropId].pwszVal = wszLabelBuffer;   // Label buffer
  cMsgPropId++;

  /////////////////////////////////////////////////////////////
  // Initialize the MQMSGPROPS structure.
  /////////////////////////////////////////////////////////////
  msgprops.cProp = cMsgPropId;                        // Number of message properties
  msgprops.aPropID = aMsgPropId;                      // Ids of message properties
  msgprops.aPropVar = aMsgPropVar;                    // Values of message properties
  msgprops.aStatus  = aMsgStatus;                     // Error reports

  /////////////////////////////////////////////////////////////////
  // Retrieve the machine identifier GUID.
  /////////////////////////////////////////////////////////////////

  hr = MQGetMachineProperties(NULL,
                              NULL,
                              &QMProps);
  if (FAILED(hr))
  {
    fprintf(stderr, "Failed in MQGetMachineProperties, error = 0x%x\n",hr);
    return -1;
  }

  /////////////////////////////////////////////////////////////////
  // Construct the format name for the computer journal. The returned
  // machine GUID is translated into a string, and then combined
  // with ";JOURNAL".
  /////////////////////////////////////////////////////////////////

  if(UuidToString(&guidMachineId, &pszUuid) != RPC_S_OK)
  {
    fprintf(stderr, "Failed in UuidToString.\n");
    return -1;
  }
  else
  {
    //Combine parts of format name
    sprintf( szFormatNameBuffer,
             "MACHINE=%s%s",
             pszUuid,
             ";JOURNAL");
    //translate to wide string.
    mbstowcs(wszFormatNameBuffer,
             szFormatNameBuffer,
             sizeof(szFormatNameBuffer));
    RpcStringFree(&pszUuid);
  }

  /////////////////////////////////////////////////////////////////
  // Open computer journal to retrieve message.
  /////////////////////////////////////////////////////////////////

  hr = MQOpenQueue(wszFormatNameBuffer,               // Format name of queue
                   dwAccess,                          // Access mode
                   dwShareMode,                       // Share mode
                   &hQueue);                          // OUT: Handle to queue
  if (FAILED(hr))
  {
    fprintf(stderr, "Failed in MQOpenQueue, error = 0x%x\n",hr);
    return -1;
  }

  ///////////////////////////////////////////////////////////////////
  // Retrieve the first message from the computer journal.
  ///////////////////////////////////////////////////////////////////

  hr = MQReceiveMessage(hQueue,                       // Queue handle
                        0,                            // Max time (msec)
                        dwReceiveAction,              // Receive action
                        &msgprops,                    // Msg property structure
                        NULL,                         // No OVERLAPPED structure
                        NULL,                         // No callback function
                        NULL,                         // No cursor
                        NULL);                        // No transaction
  if (FAILED(hr))
  {
    fprintf(stderr, "Failed in MQReceiveMessage, error = 0x%x\n",hr);
    return -1;
  }

  printf("A message was retrieved from the computer journal queue.\n");

  /////////////////////////////////////////////////////////////////
  // Close the queue.
  /////////////////////////////////////////////////////////////////

  hr = MQCloseQueue(hQueue);
  if (FAILED(hr))
  {
    fprintf(stderr, "Failed in MQCloseQueue, error = 0x%x\n",hr);
    return -1;
  }

  return 0;

}


Reading Messages from a Dead-Letter Queue

Reading messages from a dead-letter queue typically requires calls to three functions: a call to MQGetMachineProperties to retrieve the local computer identifier (its machine GUID), a call to MQOpenQueue to open the queue with receive access, and a call to MQReceiveMessage to read the message.

Note You cannot send messages to dead letter queue.

The following procedure can be used for opening a computers non-transaction dead letter queue (DEADLETTER) or transactional dead letter queue (DEADXACT).

To read a message from a dead-letter queue

  1. Define an MQQMPROPS structure that includes PROPID_QM_MACHINE_ID.
  2. Call MQGetMachineProperties to retrieve the machine identifier (PROPID_QM_MACHINE_ID) of the local computer.
  3. Translate the machine GUID into a string.
  4. Prepare the format name of the dead-letter queue. The example opens the non-transactional dead letter queue. To open the transaction dead letter queue replace DEADLETTER with DEADXACT when constructing the format name of the queue.
  5. Call MQOpenQueue and open the queue with receive access.
  6. Define an MQMSGPROPS structure for the message properties to be retrieved.
  7. Call MQReceiveMessage and retrieve the messages in the queue. The following call retrieves the first message in the queue.
For a code example using | See
C++ | C/C++ Code Example


C/C++ Code Example: Reading Messages from a Dead-Letter Queue

The following example opens the non-transactional dead-letter queue (DEADLETTER) and retrieves the message body of the first message in the queue.

HRESULT hr;
#define FORMAT_NAME_LEN 80
WCHAR wszFormatNameBuffer[ FORMAT_NAME_LEN];

//////////////////////////////////////////////////////
//  Define an MQQMPROPS structure for
//  PROPID_QM_MACHINE_ID.
//////////////////////////////////////////////////////

MQQMPROPS qmprops;
MQPROPVARIANT Variant;
MSGPROPID PropId;
GUID    guidMachineId;

// Set the PROPID_QM_MACHINE_ID property.
PropId = PROPID_QM_MACHINE_ID;                 //PropId
Variant.vt = VT_CLSID;                         //Type
Variant.puuid = &guidMachineId;                //Value

// Initialize the MQQMPROPS structure
qmprops.cProp = 1;                //Number of properties
qmprops.aPropID = &PropId;        //Id of properties
qmprops.aPropVar = &Variant;      //Value of properties
qmprops.aStatus  = NULL;          //No Error report

//////////////////////////////////////////////////////
//  Retrieving the identifier of the local
//  computer (machine GUID).
//////////////////////////////////////////////////////
hr = MQGetMachineProperties(
       NULL,
       NULL,
       &qmprops
       );
if (FAILED(hr))
{
    //
    //  Handle failure
    //
}

//////////////////////////////////////////////////////
//  Translating the machine GUID
//  into a string
//////////////////////////////////////////////////////
WCHAR wszMachineGuid[40];
WBYTE* pszUuid = 0;
if (UuidToString(&guidMachineId, &pszUuid) != RPC_S_OK)
{
    //
    //  Handle failure
    //
}
else
{
    wcscpy( wszMachineGuid, pszUuid );
    RpcStringFree(&pszUuid);
}

//////////////////////////////////////////////////////
//  Preparing the format name of the dead letter
//  queue. To open the transactional dead letter
//  replace DEADLETTER with DEADXACT.
//////////////////////////////////////////////////////
wsprintf( wszFormatNameBuffer,
          L"MACHINE=%s%s",
          wszMachineGuid,
          L";DEADLETTER"
          );

//////////////////////////////////////////////////////
//  Open the queue for receive
//////////////////////////////////////////////////////
QUEUEHANDLE hQueue;

hr = MQOpenQueue(
    wszFormatNameBuffer,
    MQ_RECEIVE_ACCESS,
    0,
    &hQueue
    );
if (FAILED(hr))
{
    //
    //  Handle failure
    //
}

//////////////////////////////////////////////////////
//  Define an MQMSGPROPS structure for the message
//  properties to be retrieved.
//////////////////////////////////////////////////////
MQMSGPROPS msgprops;
MQPROPVARIANT aVariant[10];
MSGPROPID aPropId[10];
DWORD cPropId = 0;

// Prepare property array (PROPVARIANT).
#define MSG_BODY_LEN    500
unsigned char ucMsgBody[MSG_BODY_LEN];
DWORD dwAppspecificIndex;

// Set the PROPID_M_BODY property.
aPropId[cPropId] = PROPID_M_BODY;                 //PropId
aVariant[cPropId].vt = VT_VECTOR|VT_UI1;          //Type
aVariant[cPropId].caub.cElems = MSG_BODY_LEN;     //Value
aVariant[cPropId].caub.pElems = ucMsgBody;

cPropId++;

// Initialize the MQMSGPROPS structure
msgprops.cProp = cPropId;       //Number of properties
msgprops.aPropID = aPropId;         //Ids of properties
msgprops.aPropVar = aVariant;       //Values of properties
msgprops.aStatus  = NULL;           //No Error report

//////////////////////////////////////////////////////
// Retrieve the first message in dead letter queue.
//////////////////////////////////////////////////////
hr = MQReceiveMessage(
 hQueue,               // Handle to the Queue
     5 * 60 * 1000,        // Max time (msec) to wait for message
     MQ_ACTION_RECEIVE,    // Action
     &msgprops,            // Properties to retrieve
    NULL,                  // No OVERLAPPED structure
    NULL,                  // No callback function
    NULL,                  // NO cursor
    NULL                   // No transaction
    );
if (FAILED(hr))
{
//
//  Handle failure
//
}


Filtering Messages

Receiving applications can use any message property or combination of properties to filter out a set a messages from a queue. Filters can be constructed to remove the desired messages from the queue when they are found or leave them there.

The examples provided here show several general purpose message-property filters. These examples could be easily modified to search for other message properties such as a specific message label or message identifier.

For an example based on | See
Application-specific information | Application-Specific Filter
Message class | Message Class Filter
When the message was sent | Sent Time Filter
When a message arrived | Arrived Time Filter


Application-specific Filter

This filter retrieves all message with a specific value of application-specific information.

This filter removes messages from the queue. When a message with the desired application-specific information is found, MQ_ACTION_RECEIVE is used to remove the message and MQ_ACTION_PEEK_CURRENT is used to look at the next message. When a message is removed from the queue, the cursor is automatically moved to the next message in the queue.

Note If you do not want to remove messages from the queue, use MQ_ACTION_PEEK_CURRENT to look at the current message, and use MQ_ACTION_PEEK_NEXT to move the cursor and look at the next message.

To create an application-specific filter

  1. Specify structures needed to create the filter.
  2. Specify PROPID_M_APPSPECIFIC.
  3. Optional. Add any other message properties that you want to retrieve.
  4. Initialize the MQMSGPROPS structure.
  5. Generate a format name for the queue. This example calls MQPathNameToFormatName to convert a known path name to a format name.
  6. Call MQOpenQueue to open the queue with receive access. Note receive access allows you to peek at and retrieve messages.
  7. Call MQCreateCursor to create a cursor for navigating through the queue.
  8. Call MQReceiveMessage with peek-current access to look at the first message in the queue. This also sets the cursor to the first message in the queue.
  9. Filter out the messages in the queue. Note that the receive action of the MQReceiveMessage calls switches between MQ_ACTION_RECEIVE and MQ_ACTION_PEEK_CURRENT if the message is removed, while only MQ_ACTION_PEEK_NEXT is used if the message does not fit the search criteria.
  10. Call MQCloseCursor and MQCloseQueue to release the resources.
For a code example using | See
C++ | C/C++ Code Example


C/C++ Code Example: Application-specific Filter

The following example filters out all messages based on application-specific information. It opens a known queue that contains messages, and then navigates through the queue, removing all messages with an application-specific value of 4.

#include <windows.h>
#include <stdio.h>
#include <mq.h>                                       // Message Queuing header file

int main(int arg, char *argv[])

{
  ////////////////////////////////////////////////////////////
  //  Define the required structures for the filter.
  ////////////////////////////////////////////////////////////

  #define NUMBEROFPROPERTIES 2                        // Number of properties
  DWORD cPropId = 0;                                  // Property counter

  //Define MQMSGPROPS structure.
  MQMSGPROPS msgprops;
  MSGPROPID aMsgPropId[NUMBEROFPROPERTIES];
  PROPVARIANT aMsgPropVar[NUMBEROFPROPERTIES];
  HRESULT aMsgStatus[NUMBEROFPROPERTIES];

  HANDLE hQueue;                                      // Queue handle
  HANDLE hCursor;                                     // Cursor handle
  HRESULT hr;                                         // Define results
  DWORD dwAccessMode = MQ_RECEIVE_ACCESS;             // Access mode of queue
  DWORD dwShareMode = MQ_DENY_RECEIVE_SHARE;          // Share Mode of queue
  DWORD dwRecAction = MQ_ACTION_PEEK_CURRENT;         // Receive action mode

  // Specify destination queue format name buffer
  DWORD dwDestFormatNameBufferLength = 256;
  WCHAR wszDestFormatNameBuffer[256];

  // Specify application specific index value for search criteria
  DWORD dwAppSpecificIndex = 4;

  /////////////////////////////////////////////////////////////////
  // Specify the search criteria (PROPID_M_APPSPECIFIC).
  /////////////////////////////////////////////////////////////////

  aMsgPropId[cPropId] = PROPID_M_APPSPECIFIC;         // Property Id
  aMsgPropVar[cPropId].vt = VT_UI4;                   // Type indicator
  aMsgPropVar[cPropId].ulVal = dwAppSpecificIndex;    // Application specific index
  cPropId++;

  /////////////////////////////////////////////////////////////////
  // Add additional message properties here.
  /////////////////////////////////////////////////////////////////

  /////////////////////////////////////////////////////////////////
  // Initialize the MQMSGPROPS structure.
  /////////////////////////////////////////////////////////////////

  msgprops.cProp = cPropId;                           // Number of message properties
  msgprops.aPropID = aMsgPropId;                      // Ids of message properties.
  msgprops.aPropVar = aMsgPropVar;                    // Values of message properties.
  msgprops.aStatus  = aMsgStatus;                     // Error reports

  /////////////////////////////////////////////////////////////////
  // Convert destination queue path name to a format name.
  /////////////////////////////////////////////////////////////////

  hr = MQPathNameToFormatName(L".\\TestQueue",
                              wszDestFormatNameBuffer,
                              &dwDestFormatNameBufferLength);
  if (FAILED(hr))
  {
     fprintf(stderr, "Failed in MQPathNameToFormatName for destination queue, error = 0x%x\n",hr);
     return -1;
  }

  /////////////////////////////////////////////////////////////////
  // Open the destination queue to filter messages.
  /////////////////////////////////////////////////////////////////

  hr = MQOpenQueue(wszDestFormatNameBuffer,           // Format name of queue
                   dwAccessMode,                      // Access mode
                   dwShareMode,                       // Share mode
                   &hQueue                            // OUT: Handle of queue

                   );

  if (FAILED(hr))
  {
     fprintf(stderr, "Failed opening destination queue, error = 0x%x\n",hr);
     return -1;
  }

  /////////////////////////////////////////////////////////////
  // Create the cursor used to navigate through the queue.
  /////////////////////////////////////////////////////////////

  hr = MQCreateCursor(hQueue,                         // Queue handle
                      &hCursor                        // OUT: Handle to cursor
                      );

  if (FAILED(hr))
  {
     fprintf(stderr, "Failed creating cursor, error = 0x%x\n",hr);
     return -1;
  }

  /////////////////////////////////////////////////////////////
  // Peek at first message in the queue.
  /////////////////////////////////////////////////////////////

  hr = MQReceiveMessage(hQueue,                       // Queue handle
                        0,                            // Max time (msec)
                        dwRecAction,                  // Receive action
                        &msgprops,                    // Msg property structure
                        NULL,                         // No OVERLAPPED structure
                        NULL,                         // No callback function
                        hCursor,                      // Cursor handle
                        NULL                          // No transaction
                        );
  if (FAILED(hr))
  {
     fprintf(stderr, "Failed peeking at first messages, error = 0x%x\n",hr);
     return -1;
  }

  /////////////////////////////////////////////////////////////
  // Filter messages from queue.
  /////////////////////////////////////////////////////////////

  do
  {
     if (msgprops.aPropVar[0].ulVal == 4)
     {
        dwRecAction = MQ_ACTION_RECEIVE;              // Receive action
        hr = MQReceiveMessage(hQueue,                 // Queue handle
                              0,                      // Max time (msec)
                              dwRecAction,            // Receive action
                              &msgprops,              // Msg property structure
                              NULL,                   // No OVERLAPPED structure
                              NULL,                   // No callback function
                              hCursor,                // Cursor handle
                              NULL                    // No transaction
                             );
        if (FAILED(hr))
        {
           fprintf(stderr, "Failed retrieving messages, error = 0x%x\n",hr);
           break;
        }
        puts("Removed message from queue.\n");
        dwRecAction = MQ_ACTION_PEEK_CURRENT;         // Reset to peek at current cursor position
     }
     else
     {
        dwRecAction = MQ_ACTION_PEEK_NEXT;             // Reset receive action mode
     }

     hr = MQReceiveMessage(hQueue,                    // Queue handle
                           0,                         // Max time (msec)
                           dwRecAction,               // Receive action
                           &msgprops,                 // Msg property structure
                           NULL,                      // No OVERLAPPED structure
                           NULL,                      // No callback function
                           hCursor,                   // Cursor handle
                           NULL                       // No transaction
                           );
     if (FAILED(hr))
     {
        if (hr == MQ_ERROR_IO_TIMEOUT)
        {
           puts("All messages are filtered from the queue.\n");
        }
        else
        {
           fprintf(stderr, "Failed peeking at next messages, error = 0x%x\n",hr);
        }
        break;
     }

  } while (hr==0);

  /////////////////////////////////////////////////////////////
  // Close cursor and queue.
  /////////////////////////////////////////////////////////////
  hr = MQCloseCursor(hCursor);
  if (FAILED(hr))
  {
     fprintf(stderr, "Failed closing cursor, error = 0x%x\n",hr);
  return -1;
  }

  hr = MQCloseQueue(hQueue);
  if (FAILED(hr))
  {
    fprintf(stderr, "Failed closing destination queue, error = 0x%x\n",hr);
    return -1;
  }

  return 0;

}


Message Class Filter

This filter retrieves all message with a specific message class from a known administration queue.

This filter removes messages from the queue. When a message with the desired class is found, MQ_ACTION_RECEIVE is used to remove the message and MQ_ACTION_PEEK_CURRENT is used to look at the next message. When a message is removed from the queue, the cursor is automatically moved to the next message in the queue.

Note If you do not want to remove messages from the queue, use MQ_ACTION_PEEK_CURRENT to look at the current message, and use MQ_ACTION_PEEK_NEXT to move the cursor and look at the next message.

To create a message class filter

  1. Specify structures needed to create filter.
  2. Specify PROPID_M_CLASS.
  3. Optional. Add any other message properties that you want to retrieve.
  4. Initialize the MQMSGPROPS structure.
  5. Generate a format name for the queue. This example calls MQPathNameToFormatName to convert a known path name to a format name.
  6. Call MQOpenQueue to open the queue with receive access. Note receive access allows you to peek at and retrieve messages.
  7. Call MQCreateCursor to create a cursor for navigating through the queue.
  8. Call MQReceiveMessage with peek-current access to look at the first message in the queue. This also sets the cursor to the first message in the queue.
  9. Filter out the messages in the queue. Note that the receive action of the MQReceiveMessage calls switches between MQ_ACTION_RECEIVE and MQ_ACTION_PEEK_CURRENT if the message is removed, while only MQ_ACTION_PEEK_NEXT is used if the message does not fit the search criteria.
  10. Call MQCloseCursor and MQCloseQueue to release the resources.
For a code example using | See
C++ | C/C++ Code Example


C/C++ Code Example: Message Class Filter

The following example filters out all messages based on message class. It opens a known administration queue that contains acknowledgment messages, and then navigates through the queue, removing all negative receive acknowledgment messages.

#include <windows.h>
#include <stdio.h>
#include <mq.h>                                       // Message Queuing header file

int main(int arg, char *argv[])

{
  ////////////////////////////////////////////////////////////
  //  Define the required structures for the filter.
  ////////////////////////////////////////////////////////////

  #define NUMBEROFPROPERTIES 2                        // Number of properties
  DWORD cPropId = 0;                                  // Property counter.

  //Define MQMSGPROPS structure.
  MQMSGPROPS msgprops;
  MSGPROPID aMsgPropId[NUMBEROFPROPERTIES];
  PROPVARIANT aMsgPropVar[NUMBEROFPROPERTIES];
  HRESULT aMsgStatus[NUMBEROFPROPERTIES];

  HANDLE hQueue;                                      // Queue handle
  HANDLE hCursor;                                     // Cursor handle
  HRESULT hr;                                         // Define results
  DWORD dwAccessMode = MQ_RECEIVE_ACCESS;             // Access mode of queue
  DWORD dwShareMode = MQ_DENY_RECEIVE_SHARE;          // Share Mode of queue
  DWORD dwRecAction = MQ_ACTION_PEEK_CURRENT;         // Receive action mode

  // Specify administration queue format name buffer
  DWORD dwAdminFormatNameBufferLength = 256;
  WCHAR wszAdminFormatNameBuffer[256];

  // Specify search criteria
  DWORD dwTestClass = MQMSG_CLASS_NACK_RECEIVE_TIMEOUT;

  /////////////////////////////////////////////////////////////////
  // Specify the message class (PROPIC_M_CLASS) property.
  /////////////////////////////////////////////////////////////////

  aMsgPropId[cPropId] = PROPID_M_CLASS;         // Property Id
  aMsgPropVar[cPropId].vt = VT_UI2;                   // Type indicator
  cPropId++;

  /////////////////////////////////////////////////////////////////
  // Add additional message properties here.
  /////////////////////////////////////////////////////////////////

  /////////////////////////////////////////////////////////////////
  // Initialize the MQMSGPROPS structure.
  /////////////////////////////////////////////////////////////////

  msgprops.cProp = cPropId;                           // Number of message properties
  msgprops.aPropID = aMsgPropId;                      // Ids of message properties
  msgprops.aPropVar = aMsgPropVar;                    // Values of message properties
  msgprops.aStatus  = aMsgStatus;                     // Error reports

  /////////////////////////////////////////////////////////////////
  // Convert administration queue path name to a format name.
  /////////////////////////////////////////////////////////////////

  hr = MQPathNameToFormatName(L".\\AdminQueue",
                              wszAdminFormatNameBuffer,
                              &dwAdminFormatNameBufferLength);
  if (FAILED(hr))
  {
     fprintf(stderr, "Failed in MQPathNameToFormatName for administration queue, error = 0x%x\n",hr);
     return -1;
  }

  /////////////////////////////////////////////////////////////////
  // Open the administration queue to filter messages.
  /////////////////////////////////////////////////////////////////

  hr = MQOpenQueue(wszAdminFormatNameBuffer,           // Format name of queue
                   dwAccessMode,                      // Access mode
                   dwShareMode,                       // Share mode
                   &hQueue                            // OUT: Handle of queue

                   );

  if (FAILED(hr))
  {
     fprintf(stderr, "Failed opening administration queue, error = 0x%x\n",hr);
     return -1;
  }

  /////////////////////////////////////////////////////////////
  // Create the cursor used to navigate through the queue.
  /////////////////////////////////////////////////////////////

  hr = MQCreateCursor(hQueue,                         // Queue handle
                      &hCursor                        // OUT: Handle to cursor
                      );

  if (FAILED(hr))
  {
     fprintf(stderr, "Failed creating cursor, error = 0x%x\n",hr);
     return -1;
  }

  /////////////////////////////////////////////////////////////
  // Peek at first message in the queue.
  /////////////////////////////////////////////////////////////

  hr = MQReceiveMessage(hQueue,                       // Queue handle
                        0,                            // Max time (msec)
                        dwRecAction,                  // Receive action
                        &msgprops,                    // Msg property structure
                        NULL,                         // No OVERLAPPED structure
                        NULL,                         // No callback function
                        hCursor,                      // Cursor handle
                        NULL                          // No transaction
                        );
  if (FAILED(hr))
  {
     fprintf(stderr, "Failed peeking at first messages, error = 0x%x\n",hr);
     return -1;
  }

  /////////////////////////////////////////////////////////////
  // Filter messages from queue.
  /////////////////////////////////////////////////////////////

  do
  {
     if (msgprops.aPropVar[0].uiVal == dwTestClass)
     {
        dwRecAction = MQ_ACTION_RECEIVE;              // Receive action
        hr = MQReceiveMessage(hQueue,                 // Queue handle
                              0,                      // Max time (msec)
                              dwRecAction,            // Receive action
                              &msgprops,              // Msg property structure
                              NULL,                   // No OVERLAPPED structure
                              NULL,                   // No callback function
                              hCursor,                // Cursor handle
                              NULL                    // No transaction
                             );
        if (FAILED(hr))
        {
           fprintf(stderr, "Failed retrieving messages, error = 0x%x\n",hr);
           break;
        }
        puts("Removed message from queue.\n");
        dwRecAction = MQ_ACTION_PEEK_CURRENT;         // Reset to peek at current cursor position
     }
     else
     {
        dwRecAction = MQ_ACTION_PEEK_NEXT;             // Reset receive action mode
     }

     hr = MQReceiveMessage(hQueue,                    // Queue handle
                           0,                         // Max time (msec)
                           dwRecAction,               // Receive action
                           &msgprops,                 // Msg property structure
                           NULL,                      // No OVERLAPPED structure
                           NULL,                      // No callback function
                           hCursor,                   // Cursor handle
                           NULL                       // No transaction
                           );
     if (FAILED(hr))
     {
        if (hr == MQ_ERROR_IO_TIMEOUT)
        {
           puts("All messages are filtered from the queue.\n");
        }
        else
        {
           fprintf(stderr, "Failed peeking at next messages, error = 0x%x\n",hr);
        }
        break;
     }

  } while (hr==0);

  /////////////////////////////////////////////////////////////
  // Close cursor and queue.
  /////////////////////////////////////////////////////////////
  hr = MQCloseCursor(hCursor);
  if (FAILED(hr))
  {
     fprintf(stderr, "Failed closing cursor, error = 0x%x\n",hr);
  return -1;
  }

  hr = MQCloseQueue(hQueue);
  if (FAILED(hr))
  {
    fprintf(stderr, "Failed closing administration queue, error = 0x%x\n",hr);
    return -1;
  }

  return 0;

}


Sent Time Filter

This filter retrieves all message that were sent to the queue within the last hour.

When a message with correct time stamp is found, MQ_ACTION_RECEIVE is used to remove the message and MQ_ACTION_PEEK_CURRENT is used to look at the next message. When a message is removed from the queue, the cursor is automatically moved to the next message in the queue.

Note If you do not want to remove messages from the queue, use MQ_ACTION_PEEK_CURRENT to look at the current message, and use MQ_ACTION_PEEK_NEXT to move the cursor to the next message.

To create a message class filter

  1. Specify structures needed to create filter.
  2. Specify PROPID_M_SENTTIME.
  3. Optional. Add any other message properties that you want to retrieve. The following code also retrieves the label of each message.
  4. Initialize the MQMSGPROPS structure.
  5. Generate a format name for the queue. This example calls MQPathNameToFormatName to convert a known path name to a format name.
  6. Call MQOpenQueue to open the queue with receive access. Note receive access allows you to peek at and retrieve messages.
  7. Call MQCreateCursor to create a cursor for navigating through the queue.
  8. Call MQReceiveMessage with peek-current access to look at the first message in the queue. This also sets the cursor to the first message in the queue.
  9. Filter out the messages that were sent within the last hour. Note that the receive action of the MQReceiveMessage uses MQ_ACTION_RECEIVE and MQ_ACTION_PEEK_CURRENT if the message is removed, while only MQ_ACTION_PEEK_NEXT is used if the message does not fit the search criteria.
  10. Call MQCloseCursor and MQCloseQueue to release the resources.
For a code example using | See
C++ | C/C++ Code Example


C/C++ Code Example: Sent Time Filter

The following example filters out all messages based the time they were sent to the queue. It opens a known queue, peeks at the first message to point the cursor to the first message in the queue, and then navigates through the queue. The label and sent time stamp is displayed for each message removed from the queue.

#include <windows.h>
#include <stdio.h>
#include <mq.h>                                       // Message Queuing header file
#include <time.h>

int main(int arg, char *argv[])

{

  /////////////////////////////////////////////////////////
  //
  //  Define the required structures for the filter.
  //
  /////////////////////////////////////////////////////////

  #define NUMBEROFPROPERTIES 3                        // Number of properties
  DWORD cPropId = 0;                                  // Property counter

  // Define MQMSGPROPS structure.
  MQMSGPROPS msgprops;
  MSGPROPID aMsgPropId[NUMBEROFPROPERTIES];
  PROPVARIANT aMsgPropVar[NUMBEROFPROPERTIES];
  HRESULT aMsgStatus[NUMBEROFPROPERTIES];
  HANDLE hQueue;                                      // Queue handle
  HANDLE hCursor;                                     // Cursor handle
  HRESULT hr;                                         // Define results

  DWORD dwAccessMode = MQ_RECEIVE_ACCESS;             // Access mode of queue
  DWORD dwShareMode = MQ_DENY_RECEIVE_SHARE;          // Share Mode of queue
  DWORD dwRecAction = MQ_ACTION_PEEK_CURRENT;         // Receive action mode

  // Specify destination queue format name buffer
  DWORD dwDestFormatNameBufferLength = 256;
  WCHAR wszDestFormatNameBuffer[256];

  // Specify message label buffer
  WCHAR wszLabelBuffer[250];

  // Specify sent time buffer and structure
  time_t dwSentTime;
  struct tm *gmt;

  /////////////////////////////////////////////////////////
  //
  // Specify message properties PROPID_M_SENTTIME,
  // PROPID_M_LABEL, and PROPID_M_LABEL_LEN.
  //
  /////////////////////////////////////////////////////////

  aMsgPropId[cPropId] = PROPID_M_SENTTIME;            // Property Id
  aMsgPropVar[cPropId].vt = VT_UI4;                   // Type indicator
  aMsgPropVar[cPropId].ulVal = dwSentTime;             // Sent time
  cPropId++;

  aMsgPropId[cPropId] = PROPID_M_LABEL_LEN;           // Property ID
  aMsgPropVar[cPropId].vt =VT_UI4;                    // Type indicator
  aMsgPropVar[cPropId].ulVal = 250;                   // Label buffer size
  cPropId++;

  aMsgPropId[cPropId] = PROPID_M_LABEL;               // Property ID
  aMsgPropVar[cPropId].vt = VT_LPWSTR;                // Type indicator
  aMsgPropVar[cPropId].pwszVal = wszLabelBuffer;      // Label buffer
  cPropId++;

  /////////////////////////////////////////////////////////////////
  //
  // Initialize the MQMSGPROPS structure.
  //
  /////////////////////////////////////////////////////////////////

  msgprops.cProp = cPropId;                           // Number of message properties
  msgprops.aPropID = aMsgPropId;                      // Ids of message properties.
  msgprops.aPropVar = aMsgPropVar;                    // Values of message properties.
  msgprops.aStatus  = aMsgStatus;                     // Error reports

  /////////////////////////////////////////////////////////////////
  //
  // Convert destination queue path name to a format name.
  //
  /////////////////////////////////////////////////////////////////

  hr = MQPathNameToFormatName(L".\\testqueue",
                              wszDestFormatNameBuffer,
                              &dwDestFormatNameBufferLength);

  if (FAILED(hr))
  {
    fprintf(stderr, "Failed in MQPathNameToFormatName for destination queue, error = 0x%x\n",hr);
    return -1;
  }

  /////////////////////////////////////////////////////////////////
  //
  // Open the destination queue to filter messages. The queue is
  // opened with receive access so that messages can be peeked at
  // and recieved.
  //
  /////////////////////////////////////////////////////////////////

  hr = MQOpenQueue(wszDestFormatNameBuffer,           // Format name of queue
                   dwAccessMode,                      // Access mode
                   dwShareMode,                       // Share mode
                   &hQueue                            // OUT: Handle of queue
                   );
  if (FAILED(hr))
  {
    fprintf(stderr, "Failed opening destination queue, error = 0x%x\n",hr);
    return -1;
  }

  /////////////////////////////////////////////////////////////
  //
  // Create the cursor used to navigate through the queue.
  //
  /////////////////////////////////////////////////////////////

  hr = MQCreateCursor(hQueue,                         // Queue handle
                      &hCursor                        // OUT: Handle to cursor
                      );
  if (FAILED(hr))
  {
    fprintf(stderr, "Failed creating cursor, error = 0x%x\n",hr);
    return -1;
  }

  /////////////////////////////////////////////////////////////
  //
  // Peek at first message in the queue. The ReceiveAction
  // parameter is set to MQ_ACTION_PEEK_CURRENT to set
  // the cursor to the first message in the queue.
  //
  /////////////////////////////////////////////////////////////

  hr = MQReceiveMessage(hQueue,                       // Queue handle
                        0,                            // Max time (msec)
                        dwRecAction,                  // Receive action
                        &msgprops,                    // Msg property structure
                        NULL,                         // No OVERLAPPED structure
                        NULL,                         // No callback function
                        hCursor,                      // Cursor handle
                        NULL                          // No transaction
                        );

  if (FAILED(hr))
  {
    switch( hr )
    {
      case MQ_ERROR_IO_TIMEOUT:
        puts("There are no messages in the queue!");
        break;

      default:
        fprintf(stderr, "Failed peeking at first message, error = 0x%x\n",hr);
        break;
    }
    return -1;
  }

  /////////////////////////////////////////////////////////////
  //
  // Filter messages from queue.
  //
  /////////////////////////////////////////////////////////////

  do
  {
    if (msgprops.aPropVar[0].ulVal > time(NULL) - (60*60))
    {
      dwRecAction = MQ_ACTION_RECEIVE;              // Receive action
      hr = MQReceiveMessage(hQueue,                 // Queue handle
                            0,                      // Max time (msec)
                            dwRecAction,            // Receive action
                            &msgprops,              // Msg property structure
                            NULL,                   // No OVERLAPPED structure
                            NULL,                   // No callback function
                            hCursor,                // Cursor handle
                            NULL                    // No transaction
                            );
      if (FAILED(hr))
      {
        fprintf(stderr, "Failed retrieving messages, error = 0x%x\n",hr);
        break;
      }

    dwSentTime=msgprops.aPropVar[0].ulVal;
    gmt=localtime(&dwSentTime);
      // Test to see if label exists
    if (msgprops.aPropVar[1].ulVal == NULL)
    {
        wprintf (L"A message with no label was sent at: \t%S", asctime(gmt));
      }
      else
      {
       wprintf(L"Message %s",wszLabelBuffer);
       wprintf(L" was sent at: \t%S", asctime(gmt));
    }
    aMsgPropVar[1].ulVal= 250;                    // Reset PROPID_M_LABEL_LEN
    dwRecAction = MQ_ACTION_PEEK_CURRENT;         // Reset to peek at current cursor position
    }

    else
    {
      dwRecAction = MQ_ACTION_PEEK_NEXT;             // Reset receive action mode
    }

    hr = MQReceiveMessage(hQueue,                    // Queue handle
                          0,                         // Max time (msec)
                          dwRecAction,               // Receive action
                          &msgprops,                 // Msg property structure
                          NULL,                      // No OVERLAPPED structure
                          NULL,                      // No callback function
                          hCursor,                   // Cursor handle
                          NULL                       // No transaction
                          );
    if (FAILED(hr))
    {
      if (hr == MQ_ERROR_IO_TIMEOUT)
      {
         puts("All messages are filtered from the queue.\n");
      }

      else
      {
        fprintf(stderr, "Failed peeking at next messages, error = 0x%x\n",hr);
      }
      break;
    }

  } while (hr==0);

  /////////////////////////////////////////////////////////////
  //
  // Close cursor and queue.
  //
  /////////////////////////////////////////////////////////////

  hr = MQCloseCursor(hCursor);
  if (FAILED(hr))
  {
    fprintf(stderr, "Failed closing cursor, error = 0x%x\n",hr);
    return -1;
  }

  hr = MQCloseQueue(hQueue);
  if (FAILED(hr))
  {
    fprintf(stderr, "Failed closing destination queue, error = 0x%x\n",hr);
    return -1;
  }

  return 0;

}


Arrived Time Filter

This filter retrieves all message that arrived in the queue within the last hour.

When a message with correct time stamp is found, MQ_ACTION_RECEIVE is used to remove the message and MQ_ACTION_PEEK_CURRENT is used to look at the next message. When a message is removed from the queue, the cursor is automatically moved to the next message in the queue.

Note If you do not want to remove messages from the queue, use MQ_ACTION_PEEK_CURRENT to look at the current message, and use MQ_ACTION_PEEK_NEXT to move the cursor to the next message.

To create an arrived time filter

  1. Specify structures needed to create filter.
  2. Specify PROPID_M_ARRIVEDTIME.
  3. Optional. Add any other message properties that you want to retrieve. The following code also retrieves the label of each message.
  4. Initialize the MQMSGPROPS structure.
  5. Generate a format name for the queue. This example calls MQPathNameToFormatName to convert a known path name to a format name.
  6. Call MQOpenQueue to open the queue with receive access. Note receive access allows you to peek at and retrieve messages.
  7. Call MQCreateCursor to create a cursor for navigating through the queue.
  8. Call MQReceiveMessage with peek-current access to look at the first message in the queue. This also sets the cursor to the first message in the queue.
  9. Filter out the messages that arrived within the last hour. Note that the receive action of the MQReceiveMessage uses MQ_ACTION_RECEIVE and MQ_ACTION_PEEK_CURRENT if the message is removed, while only MQ_ACTION_PEEK_NEXT is used if the message does not fit the search criteria.
  10. Call MQCloseCursor and MQCloseQueue to release the resources.
For a code example using | See
C++ | C/C++ Code Example


C/C++ Code Example: Arrived Time Filter

The following example filters out all messages based the time they arrived in the queue. It opens a known queue, peeks at the first message to point the cursor to the first message in the queue, and then navigates through the queue. The label and arrived time stamp are displayed for each message removed from the queue.

#include <windows.h>
#include <stdio.h>
#include <mq.h>                                       // Message Queuing header file
#include <time.h>

int main(int arg, char *argv[])

{

  /////////////////////////////////////////////////////////
  //
  //  Define the required structures for the filter.
  //
  /////////////////////////////////////////////////////////

  #define NUMBEROFPROPERTIES 3                        // Number of properties
  DWORD cPropId = 0;                                  // Property counter

  // Define MQMSGPROPS structure.
  MQMSGPROPS msgprops;
  MSGPROPID aMsgPropId[NUMBEROFPROPERTIES];
  PROPVARIANT aMsgPropVar[NUMBEROFPROPERTIES];
  HRESULT aMsgStatus[NUMBEROFPROPERTIES];
  HANDLE hQueue;                                      // Queue handle
  HANDLE hCursor;                                     // Cursor handle
  HRESULT hr;                                         // Define results

  DWORD dwAccessMode = MQ_RECEIVE_ACCESS;             // Access mode of queue
  DWORD dwShareMode = MQ_DENY_RECEIVE_SHARE;          // Share Mode of queue
  DWORD dwRecAction = MQ_ACTION_PEEK_CURRENT;         // Receive action mode

  // Specify destination queue format name buffer
  DWORD dwDestFormatNameBufferLength = 256;
  WCHAR wszDestFormatNameBuffer[256];

  // Specify message label buffer
  WCHAR wszLabelBuffer[250];

   // Specify arrived time buffer and structure
  time_t dwArrivedTime;
  struct tm *gmt;
  /////////////////////////////////////////////////////////
  //
  // Specify message properties PROPID_M_ARRIVEDTIME,
  // PROPID_M_LABEL, and PROPID_M_LABEL_LEN.
  //
  /////////////////////////////////////////////////////////

  aMsgPropId[cPropId] = PROPID_M_ARRIVEDTIME;         // Property Id
  aMsgPropVar[cPropId].vt = VT_UI4;                   // Type indicator
  aMsgPropVar[cPropId].ulVal = dwArrivedTime;         // Arrived time
  cPropId++;

  aMsgPropId[cPropId] = PROPID_M_LABEL_LEN;           // Property ID
  aMsgPropVar[cPropId].vt =VT_UI4;                    // Type indicator
  aMsgPropVar[cPropId].ulVal = 250;                   // Label buffer size
  cPropId++;

  aMsgPropId[cPropId] = PROPID_M_LABEL;               // Property ID
  aMsgPropVar[cPropId].vt = VT_LPWSTR;                // Type indicator
  aMsgPropVar[cPropId].pwszVal = wszLabelBuffer;      // Label buffer
  cPropId++;

  /////////////////////////////////////////////////////////////////
  //
  // Initialize the MQMSGPROPS structure.
  //
  /////////////////////////////////////////////////////////////////

  msgprops.cProp = cPropId;                           // Number of message properties
  msgprops.aPropID = aMsgPropId;                      // Ids of message properties.
  msgprops.aPropVar = aMsgPropVar;                    // Values of message properties.
  msgprops.aStatus  = aMsgStatus;                     // Error reports

  /////////////////////////////////////////////////////////////////
  //
  // Convert destination queue path name to a format name.
  //
  /////////////////////////////////////////////////////////////////

  hr = MQPathNameToFormatName(L".\\testqueue",
                              wszDestFormatNameBuffer,
                              &dwDestFormatNameBufferLength);

  if (FAILED(hr))
  {
    fprintf(stderr, "Failed in MQPathNameToFormatName for destination queue, error = 0x%x\n",hr);
    return -1;
  }

  /////////////////////////////////////////////////////////////////
  //
  // Open the destination queue to filter messages. The queue is
  // opened with receive access so that messages can be peeked at
  // and recieved.
  //
  /////////////////////////////////////////////////////////////////

  hr = MQOpenQueue(wszDestFormatNameBuffer,           // Format name of queue
                   dwAccessMode,                      // Access mode
                   dwShareMode,                       // Share mode
                   &hQueue                            // OUT: Handle of queue
                   );
  if (FAILED(hr))
  {
    fprintf(stderr, "Failed opening destination queue, error = 0x%x\n",hr);
    return -1;
  }

  /////////////////////////////////////////////////////////////
  //
  // Create the cursor used to navigate through the queue.
  //
  /////////////////////////////////////////////////////////////

  hr = MQCreateCursor(hQueue,                         // Queue handle
                      &hCursor                        // OUT: Handle to cursor
                      );
  if (FAILED(hr))
  {
    fprintf(stderr, "Failed creating cursor, error = 0x%x\n",hr);
    return -1;
  }

  /////////////////////////////////////////////////////////////
  //
  // Peek at first message in the queue. The ReceiveAction
  // parameter is set to MQ_ACTION_PEEK_CURRENT to set
  // the cursor to the first message in the queue.
  //
  /////////////////////////////////////////////////////////////

  hr = MQReceiveMessage(hQueue,                       // Queue handle
                        0,                            // Max time (msec)
                        dwRecAction,                  // Receive action
                        &msgprops,                    // Msg property structure
                        NULL,                         // No OVERLAPPED structure
                        NULL,                         // No callback function
                        hCursor,                      // Cursor handle
                        NULL                          // No transaction
                        );

  if (FAILED(hr))
  {
    switch( hr )
    {
      case MQ_ERROR_IO_TIMEOUT:
        puts("There are no messages in the queue!");
        break;

      default:
        fprintf(stderr, "Failed peeking at first message, error = 0x%x\n",hr);
        break;
    }
    return -1;
  }

  /////////////////////////////////////////////////////////////
  //
  // Filter messages from queue.
  //
  /////////////////////////////////////////////////////////////

  do
  {
    if (msgprops.aPropVar[0].ulVal > time(NULL) - (60*60))
    {
      dwRecAction = MQ_ACTION_RECEIVE;              // Receive action
      hr = MQReceiveMessage(hQueue,                 // Queue handle
                            0,                      // Max time (msec)
                            dwRecAction,            // Receive action
                            &msgprops,              // Msg property structure
                            NULL,                   // No OVERLAPPED structure
                            NULL,                   // No callback function
                            hCursor,                // Cursor handle
                            NULL                    // No transaction
                            );
      if (FAILED(hr))
      {
        fprintf(stderr, "Failed retrieving messages, error = 0x%x\n",hr);
        break;
      }

      dwArrivedTime=msgprops.aPropVar[0].ulVal;
      gmt=localtime(&dwArrivedTime);
      // Test to see if label exists
      if (msgprops.aPropVar[1].ulVal == NULL)
      {
        wprintf (L"A message with no label arrived at: \t%S", asctime(gmt));
      }
      else
      {
        wprintf(L"Message %s",wszLabelBuffer);
        wprintf(L" arrived at: \t%S", asctime(gmt));
      }

    aMsgPropVar[1].ulVal= 250;                    // Reset PROPID_M_LABEL_LEN
    dwRecAction = MQ_ACTION_PEEK_CURRENT;         // Reset to peek at current cursor position
    }

    else
    {
      dwRecAction = MQ_ACTION_PEEK_NEXT;             // Reset receive action mode
    }

    hr = MQReceiveMessage(hQueue,                    // Queue handle
                          0,                         // Max time (msec)
                          dwRecAction,               // Receive action
                          &msgprops,                 // Msg property structure
                          NULL,                      // No OVERLAPPED structure
                          NULL,                      // No callback function
                          hCursor,                   // Cursor handle
                          NULL                       // No transaction
                          );
    if (FAILED(hr))
    {
      if (hr == MQ_ERROR_IO_TIMEOUT)
      {
         puts("All messages are filtered from the queue.\n");
      }

      else
      {
        fprintf(stderr, "Failed peeking at next messages, error = 0x%x\n",hr);
      }
      break;
    }

  } while (hr==0);

  /////////////////////////////////////////////////////////////
  //
  // Close cursor and queue.
  //
  /////////////////////////////////////////////////////////////

  hr = MQCloseCursor(hCursor);
  if (FAILED(hr))
  {
    fprintf(stderr, "Failed closing cursor, error = 0x%x\n",hr);
    return -1;
  }

  hr = MQCloseQueue(hQueue);
  if (FAILED(hr))
  {
    fprintf(stderr, "Failed closing destination queue, error = 0x%x\n",hr);
    return -1;
  }

  return 0;

}


Retrieving Queue Properties

After a queue is created, its properties can be retrieved by calling MQGetQueueProperties. You can always retrieve the properties of public queues; however, you can retrieve the properties of private queues only if they are located on your local computer.

Note Properties of public queues can also be retrieved by doing a query on the directory service. For details on performing a query, see Locating a Public Queue.

In most cases, any application can retrieve the properties of a queue. However, if MQ_ERROR_ACCESS_DENIED is returned to the MQGetQueueProperties call, the queue's access control is blocking the application from retrieving the queue's properties. For information on setting a queue's access rights, see Setting Access Control Security for a Queue.

For an example of | See
Retrieving the authentication level of the queue | Retrieving PROPID_Q_AUTHENTICATE
Retrieving the priority level of the queue | Retrieving PROPID_Q_BASEPRIORITY
Retrieving the time when the queue was created | Retrieving PROPID_Q_CREATE_TIME
Retrieving the identifier of the queue | Retrieving PROPID_Q_INSTANCE
Retrieve the journaling level of the queue | Retrieving PROPID_Q_JOURNAL
Retrieving the maximum size of the queue journal | Retrieving PROPID_Q_JOURNAL_QUOTA
Retrieving the label of the queue | Retrieving PROPID_Q_LABEL
Retrieving the time when the queue's properties were last modified | Retrieving PROPID_Q_MODIFY_TIME
Retrieving the pathname of the queue | Retrieving PROPID_Q_PATHNAME
Retrieving the privacy level of the queue | Retrieving PROPID_Q_PRIV_LEVEL
Retrieving the maximum size of the queue | Retrieving PROPID_Q_QUOTA.
Retrieving the transaction level of the queue | Retrieving PROPID_Q_TRANSACTION
Retrieving the queue's service type | Retrieving PROPID_Q_TYPE


Retrieving PROPID_Q_AUTHENTICATE

The authentication level of the queue (PROPID_Q_AUTHENTICATE) specifies whether the queue accepts only authenticated messages. By default, a queue accepts both authenticated and non-authenticated messages.

To retrieve PROPID_Q_AUTHENTICATE

  1. Define the structures needed to retrieve queue properties.
  2. Specify PROPID_Q_AUTHENTICATE.
  3. Add any additional queue properties. When adding properties, increment the cProp variable to reflect the number of properties added.
  4. Initialize the MQQUEUEPROPS structure.
  5. Call MQPathNameToFormatName to retrieve a format name for the queue. Note the pathname of the queue indicates a local public queue whose name is "testqueue".
  6. Call MQGetQueueProperties.
  7. Examine the value of the returned property. In this example, the authentication level of the queue is printed to the screen.
For a code example using | See
C++ | C/C++ Code Example


C/C++ Code Example: Retrieving PROPID_Q_AUTHENTICATE

The following example retrieves the PROPID_Q_AUTHENTICATE property for a known queue and then prints the returned value to the screen.

#include <windows.h>
#include <stdio.h>
#include <mq.h>                       // Message Queuing header file

int main(int arg, char *argv[])

{
  ////////////////////////////////////////////////////////////////////
  //  Define the required structures.
  ///////////////////////////////////////////////////////////////////

  #define NUMBEROFPROPERTIES 1
  DWORD cPropId = 0;

  MQQUEUEPROPS qprops;
  PROPVARIANT aQueuePropVar[NUMBEROFPROPERTIES];
  QUEUEPROPID aQueuePropId[NUMBEROFPROPERTIES];
  HRESULT aQueueStatus[NUMBEROFPROPERTIES];

  HRESULT hr;
  DWORD dwFormatNameBufferLength = 256;
  WCHAR wszFormatNameBuffer[256];

  ////////////////////////////////////////////////////////////////////
  // Specify PROPID_Q_AUTHENTICATE.
  ////////////////////////////////////////////////////////////////////

  aQueuePropId[cPropId] = PROPID_Q_AUTHENTICATE; // Property ID
  aQueuePropVar[cPropId].vt = VT_UI1;            // Type indicator
  cPropId++;

  ////////////////////////////////////////////////////////////////////
  // Add additional queue properties here. When adding
  // properties, increment cProp to
  // reflect total number of properties.
  ////////////////////////////////////////////////////////////////////

  ////////////////////////////////////////////////////////////////////
  // Initialize the MQQUEUEPROPS structure.
  ////////////////////////////////////////////////////////////////////

  qprops.cProp = cPropId;               // Number of properties
  qprops.aPropID = aQueuePropId;        // Ids of properties
  qprops.aPropVar = aQueuePropVar;      // Values of properties
  qprops.aStatus = aQueueStatus;        // Error reports

  ////////////////////////////////////////////////////////////////////
  //Get format name of queue.
  ////////////////////////////////////////////////////////////////////

  hr = MQPathNameToFormatName(L".\\testqueue",
                              wszFormatNameBuffer,
                                  &dwFormatNameBufferLength);
  if (FAILED(hr))
  {
    fprintf(stderr, "Failed in MQPathNameToFormatName, error = 0x%x\n",hr);
  return -1;
  }

  ////////////////////////////////////////////////////////////////////
  // Get queue property.
  ////////////////////////////////////////////////////////////////////

  hr = MQGetQueueProperties(wszFormatNameBuffer, &qprops);
  if (FAILED(hr))
  {
    fprintf(stderr, "Failed in MQGetQueueProperties, error = 0x%x\n",hr);
    return -1;
  }

  ////////////////////////////////////////////////////////////////////
  // Review returned value. This example prints
  // out the authentication level of the queue.
  ////////////////////////////////////////////////////////////////////

  if (aQueuePropVar[0].bVal == MQ_AUTHENTICATE)
        printf("PROPID_Q_AUTHENTICATE is set to MQ_AUTHENTICATE.\n");
    else
    printf("PROPID_Q_AUTHENTICATE is set to MQ_AUTHENTICATE_NONE.\n");

  return 0;

}


Retrieving PROPID_Q_BASEPRIORITY

The priority level of a queue (PROPID_Q_BASEPRIORITY) specifies a single base priority for all messages sent to a public queue. By default, the priority level of a queue is 0.

To retrieve PROPID_Q_BASEPRIORITY

  1. Define the structures needed to retrieve the properties. These include the MQQUEUEPROPS structure.
  2. Specify PROPID_Q_BASEPRIORITY.
  3. Add any additional queue properties. When adding properties, increment the cProp variable to reflect the number of properties added.
  4. Initialize the MQQUEUEPROPS structure.
  5. Call MQPathNameToFormatName to retrieve a format name for the queue. Note the pathname of the queue indicates a local public queue whose name is "testqueue".
  6. Call MQGetQueueProperties.
  7. Examine the value of the returned property. In this example, the authentication level of the queue is printed to the screen.
For a code example using | See
C++ | C/C++ Code Example


C/C++ Code Example: Retrieving PROPID_Q_BASEPRIORITY

The following example retrieves the PROPID_Q_BASEPRIORITY property for a known queue and then prints the returned value to the screen.

#include <windows.h>
#include <stdio.h>
#include <mq.h>                       // Message Queuing header file

int main(int arg, char *argv[])

{
  ////////////////////////////////////////////////////////////////////
  //  Define structures.
  ////////////////////////////////////////////////////////////////////

  #define NUMBEROFPROPERTIES 1
  DWORD cPropId = 0;

  MQQUEUEPROPS qprops;
  PROPVARIANT aQueuePropVar[NUMBEROFPROPERTIES];
  QUEUEPROPID aQueuePropId[NUMBEROFPROPERTIES];
  HRESULT aQueueStatus[NUMBEROFPROPERTIES];

  HRESULT hr;
  DWORD dwFormatNameBufferLength = 256;
  WCHAR wszFormatNameBuffer[256];

  ////////////////////////////////////////////////////////////////////
  // Specify PROPID_Q_BASEPRIORITY.
  ////////////////////////////////////////////////////////////////////

  aQueuePropId[cPropId] = PROPID_Q_BASEPRIORITY; // Property ID
  aQueuePropVar[cPropId].vt = VT_I2;            // Type indicator
  cPropId++;

  ////////////////////////////////////////////////////////////////////
  // Add additional queue properties here. When adding
  // properties, increment cProp to
  // reflect total number of properties.
  ////////////////////////////////////////////////////////////////////

  ////////////////////////////////////////////////////////////////////
  // Initialize the MQQUEUEPROPS structure.
  ////////////////////////////////////////////////////////////////////

  qprops.cProp = cPropId;           // Number of properties
  qprops.aPropID = aQueuePropId;        // Ids of properties
  qprops.aPropVar = aQueuePropVar;      // Values of properties
  qprops.aStatus = aQueueStatus;        // Error reports

  ////////////////////////////////////////////////////////////////////
  //Get format name of queue.
  ////////////////////////////////////////////////////////////////////

  hr = MQPathNameToFormatName(L".\\testqueue",
                              wszFormatNameBuffer,
                                  &dwFormatNameBufferLength);
  if (FAILED(hr))
  {
    fprintf(stderr, "Failed in MQPathNameToFormatName, error = 0x%x\n",hr);
  return -1;
  }

  ////////////////////////////////////////////////////////////////////
  // Get queue property.
  ////////////////////////////////////////////////////////////////////

  hr = MQGetQueueProperties(wszFormatNameBuffer, &qprops);
  if (FAILED(hr))
  {
    fprintf(stderr, "Failed in MQGetQueueProperties, error = 0x%x\n",hr);
    return -1;
  }

  ////////////////////////////////////////////////////////////////////
  // Review returned value. This example prints
  // out the priority level of the queue.
  ////////////////////////////////////////////////////////////////////

  printf("PROPID_Q_BASEPRIORITY is set to ");
  printf("%d.\n", aQueuePropVar[0].iVal);

  return 0;

}


Retrieving PROPID_Q_CREATE_TIME

The create time of a queue (PROPID_Q_CREATE_TIME) is set by Message Queuing when the queue is created (this property cannot be set by an application). Note that in this example, the C run-time function ctime() is used to display the returned value in a local date and time format.

Note When using C run-time functions, include time.h in your source code.

To retrieve PROPID_Q_CREATE_TIME

  1. Define the structures needed to retrieve the properties.
  2. Specify PROPID_Q_CREATE_TIME.
  3. Add any additional queue properties. When adding properties, increment the cProp variable to reflect the number of properties added.
  4. Initialize the MQQUEUEPROPS structure.
  5. Call MQPathNameToFormatName to retrieve a format name for the queue. Note the pathname of the queue indicates a local public queue whose name is "testqueue".
  6. Call MQGetQueueProperties.
  7. Examine the value of the returned property. In this example, ctime() is used to translate the returned value to a local date and time format.
For a code example using | See
C++ | C/C++ Code Example


C/C++ Code Example: Retrieving PROPID_Q_CREATE_TIME

The following example retrieves the PROPID_Q_CREATE_TIME property for a known queue and then prints the returned value to the screen.

#include <windows.h>
#include <stdio.h>
#include <mq.h>                       // Message Queuing header file
#include <time.h>                     // Defines ctime().

int main(int arg, char *argv[])

{
  ////////////////////////////////////////////////////////////////////
  //  Define structures.
  ////////////////////////////////////////////////////////////////////

  #define NUMBEROFPROPERTIES 1
  DWORD cPropId = 0;

  MQQUEUEPROPS qprops;
  PROPVARIANT aQueuePropVar[NUMBEROFPROPERTIES];
  QUEUEPROPID aQueuePropId[NUMBEROFPROPERTIES];
  HRESULT aQueueStatus[NUMBEROFPROPERTIES];

  HRESULT hr;
  DWORD dwFormatNameBufferLength = 256;
  WCHAR wszFormatNameBuffer[256];

  ////////////////////////////////////////////////////////////////////
  // Specify PROPID_Q_CREATE_TIME.
  ////////////////////////////////////////////////////////////////////

  aQueuePropId[cPropId] = PROPID_Q_CREATE_TIME; // Property ID
  aQueuePropVar[cPropId].vt = VT_I4;            // Type indicator
  cPropId++;

  ////////////////////////////////////////////////////////////////////
  // Add additional queue properties here. When adding
  // properties, increment cProp to
  // reflect total number of properties.
  ////////////////////////////////////////////////////////////////////

  ////////////////////////////////////////////////////////////////////
  // Initialize the MQQUEUEPROPS structure.
  ////////////////////////////////////////////////////////////////////

  qprops.cProp = cPropId;               // Number of properties
  qprops.aPropID = aQueuePropId;        // Ids of properties
  qprops.aPropVar = aQueuePropVar;      // Values of properties
  qprops.aStatus = aQueueStatus;        // Error reports

  ////////////////////////////////////////////////////////////////////
  //Get format name of queue.
  ////////////////////////////////////////////////////////////////////

  hr = MQPathNameToFormatName(L".\\testqueue",
                              wszFormatNameBuffer,
                                  &dwFormatNameBufferLength);
  if (FAILED(hr))
  {
    fprintf(stderr, "Failed in MQPathNameToFormatName, error = 0x%x\n",hr);
  return -1;
  }

  ////////////////////////////////////////////////////////////////////
  // Get queue property.
  ////////////////////////////////////////////////////////////////////

  hr = MQGetQueueProperties(wszFormatNameBuffer, &qprops);
  if (FAILED(hr))
  {
    fprintf(stderr, "Failed in MQGetQueueProperties, error = 0x%x\n",hr);
    return -1;
  }

  ////////////////////////////////////////////////////////////////////
  // Review returned value. This example prints
  // out when the queue was created.
  ////////////////////////////////////////////////////////////////////

  printf("The queue was created on ");
  printf("%s.\n", ctime(&aQueuePropVar[0].lVal));

  return 0;

}


Retrieving PROPID_Q_INSTANCE

The queue identifier (PROPID_Q_INSTANCE) is a GUID that identifies the queue. It is created by Message Queuing when the queue is created.

When retrieving the queue identifier, you must allocate a buffer of type CLSID for the returned GUID.

To retrieve PROPID_Q_INSTANCE

  1. Define the structures needed to retrieve the properties. This includes the CLSID structure needed for the returned queue instance.
  2. Specify PROPID_Q_INSTANCE.
  3. Add any additional queue properties. When adding properties, increment the cProp variable to reflect the number of properties added.
  4. Initialize the MQQUEUEPROPS structure.
  5. Call MQPathNameToFormatName to retrieve a format name for the queue. Note the pathname of the queue indicates a local public queue whose name is "testqueue".
  6. Call MQGetQueueProperties.
  7. Examine the value of the returned property. In this example, the identifier of the queue is printed to the screen.
For a code example using | See
C++ | C/C++ Code Example


C/C++ Code Example: Retrieving PROPID_Q_INSTANCE

The following example retrieves the PROPID_Q_INSTANCE property for a known queue and then prints the returned value to the screen. This example uses the RPC function UuidToString to display the retrieved queue identifier. The library and header files for this function are rpcrt4.lib and rpc.h respectively.

#include <windows.h>
#include <stdio.h>
#include <mq.h>                   // Message Queuing header file
#include <rpc.h>                  // Defines UuidToString

int main(int arg, char *argv[])

{
  ////////////////////////////////////////////////////////////////////
  //  Define structures.
  ////////////////////////////////////////////////////////////////////

  #define NUMBEROFPROPERTIES 1
  DWORD cPropId = 0;

  MQQUEUEPROPS qprops;
  PROPVARIANT aQueuePropVar[NUMBEROFPROPERTIES];
  QUEUEPROPID aQueuePropId[NUMBEROFPROPERTIES];
  HRESULT aQueueStatus[NUMBEROFPROPERTIES];

  HRESULT hr;
  DWORD dwFormatNameBufferLength = 256;
  WCHAR wszFormatNameBuffer[256];

  // Define buffer for returned instance GUID.
  CLSID InstanceBuffer;

  ////////////////////////////////////////////////////////////////////
  // Specify PROPID_Q_INSTANCE.
  ////////////////////////////////////////////////////////////////////

  aQueuePropId[cPropId] = PROPID_Q_INSTANCE;    // Property ID
  aQueuePropVar[cPropId].vt = VT_CLSID;         // Type indicator
  aQueuePropVar[cPropId].puuid = &InstanceBuffer;
  cPropId++;

  ////////////////////////////////////////////////////////////////////
  // Add additional queue properties here. When adding
  // properties, increment cProp to
  // reflect total number of properties.
  ////////////////////////////////////////////////////////////////////

  ////////////////////////////////////////////////////////////////////
  // Initialize the MQQUEUEPROPS structure.
  ////////////////////////////////////////////////////////////////////
  qprops.cProp = cPropId;           // Number of properties
  qprops.aPropID = aQueuePropId;        // Ids of properties
  qprops.aPropVar = aQueuePropVar;      // Values of properties
  qprops.aStatus = aQueueStatus;        // Error reports

  ////////////////////////////////////////////////////////////////////
  //Get format name of queue.
  ////////////////////////////////////////////////////////////////////

  hr = MQPathNameToFormatName(L".\\testqueue",
                              wszFormatNameBuffer,
                              &dwFormatNameBufferLength);
  if (FAILED(hr))
  {
    fprintf(stderr, "Failed in MQPathNameToFormatName, error = 0x%x\n",hr);
        return -1;
  }

  ////////////////////////////////////////////////////////////////////
  // Get queue property.
  ////////////////////////////////////////////////////////////////////

  hr = MQGetQueueProperties(wszFormatNameBuffer, &qprops);
  if (FAILED(hr))
  {
    fprintf(stderr, "Failed in MQGetQueueProperties, error = 0x%x\n",hr);
        return -1;
  }

  ////////////////////////////////////////////////////////////////////
  // Review returned value. This example prints
  // out the identifier of the queue.
  ////////////////////////////////////////////////////////////////////

  UCHAR *pszInstanceGUID;
  if (UuidToString(aQueuePropVar[0].puuid, &pszInstanceGUID)== RPC_S_OK)
  {
    printf("The identifier for this queue is: ");
    printf("%s.\n", pszInstanceGUID);
    RpcStringFree(&pszInstanceGUID);
  }

  return 0;

}


Retrieving PROPID_Q_JOURNAL

The journaling level of the queue (PROPID_Q_JOURNAL) specifies whether messages retrieved from the queue are also copied to its queue journal. By default, messages are not copied to the queue journal.

To retrieve PROPID_Q_JOURNAL

  1. Define the structures needed to retrieve the properties. This includes the MQQUEUEPROPS structure.
  2. Specify PROPID_Q_JOURNAL.
  3. Add any additional queue properties. When adding properties, increment the cProp variable to reflect the number of properties added.
  4. Initialize the MQQUEUEPROPS structure.
  5. Call MQPathNameToFormatName to retrieve a format name for the queue. Note the pathname of the queue indicates a local public queue whose name is "testqueue".
  6. Call MQGetQueueProperties.
  7. Examine the value of the returned property. In this example, the journaling level of the queue is printed to the screen.
For a code example using | See
C++ | C/C++ Code Example


C/C++ Code Example: Retrieving PROPID_Q_JOURNAL

The following example retrieves the PROPID_Q_JOURNAL property for a known queue and then prints the returned value to the screen.

#include <windows.h>
#include <stdio.h>
#include <mq.h>                       // Message Queuing header file

int main(int arg, char *argv[])

{
  ////////////////////////////////////////////////////////////////////
  //  Define structures.
  ////////////////////////////////////////////////////////////////////

  #define NUMBEROFPROPERTIES 1
  DWORD cPropId = 0;

  MQQUEUEPROPS qprops;
  PROPVARIANT aQueuePropVar[NUMBEROFPROPERTIES];
  QUEUEPROPID aQueuePropId[NUMBEROFPROPERTIES];
  HRESULT aQueueStatus[NUMBEROFPROPERTIES];

  HRESULT hr;

  DWORD dwFormatNameBufferLength = 256;
  WCHAR wszFormatNameBuffer[256];

  ////////////////////////////////////////////////////////////////////
  // Specify PROPID_Q_JOURNAL.
  ///////////////////////////////////////////////////////////////////

  aQueuePropId[cPropId] = PROPID_Q_JOURNAL;      // Property ID
  aQueuePropVar[cPropId].vt = VT_UI1;            // Type indicator
  cPropId++;

  ////////////////////////////////////////////////////////////////////
  // Add additional queue properties here. When adding
  // properties, increment cProp to
  // reflect total number of properties.
  ////////////////////////////////////////////////////////////////////

  ////////////////////////////////////////////////////////////////////
  // Initialize the MQQUEUEPROPS structure.
  ////////////////////////////////////////////////////////////////////

  qprops.cProp = cPropId;           // Number of properties
  qprops.aPropID = aQueuePropId;        // Ids of properties
  qprops.aPropVar = aQueuePropVar;      // Values of properties
  qprops.aStatus = aQueueStatus;        // Error reports

  ////////////////////////////////////////////////////////////////////
  //Get format name of queue.
  ////////////////////////////////////////////////////////////////////

  hr = MQPathNameToFormatName(L".\\testqueue",
                              wszFormatNameBuffer,
                                  &dwFormatNameBufferLength);
  if (FAILED(hr))
  {
    fprintf(stderr, "Failed in MQPathNameToFormatName, error = 0x%x\n",hr);
  return -1;
  }

  ////////////////////////////////////////////////////////////////////
  // Get queue property.
  ////////////////////////////////////////////////////////////////////

  hr = MQGetQueueProperties(wszFormatNameBuffer, &qprops);
  if (FAILED(hr))
  {
    fprintf(stderr, "Failed in MQGetQueueProperties, error = 0x%x\n",hr);
    return -1;
  }

  ////////////////////////////////////////////////////////////////////
  // Review returned value. This example prints
  // out the journaling level of the queue.
  ////////////////////////////////////////////////////////////////////

  if (aQueuePropVar[0].bVal == MQ_JOURNAL)
        printf("PROPID_Q_JOURNAL is set to MQ_JOURNAL.\n");
  else
    printf("PROPID_Q_JOURNAL is set to MQ_JOURNAL_NONE.\n");

  return 0;

}


Retrieving PROPID_Q_JOURNAL_QUOTA

The queue journal's quota (PROPID_Q_JOURNAL_QUOTA) is the maximum size of the queue journal. By default, a queue journal's maximum size is set to INFINITE.

To retrieve PROPID_Q_JOURNAL_QUOTA

  1. Define the structures needed to retrieve the properties.
  2. Specify PROPID_Q_JOURNAL_QUOTA.
  3. Add any additional queue properties. When adding properties, increment the cProp variable to reflect the number of properties added.
  4. Initialize the MQQUEUEPROPS structure.
  5. Call MQPathNameToFormatName to retrieve a format name for the queue. Note the pathname of the queue indicates a local public queue whose name is "testqueue".
  6. Call MQGetQueueProperties.
  7. Examine the returned value of the property.
For a code example using | See
C++ | C/C++ Code Example


C/C++ Code Example: Retrieving PROPID_Q_JOURNAL_QUOTA

The following example retrieves the PROPID_Q_JOURNAL_QUOTA property for a known queue and then prints the returned value to the screen.

#include <windows.h>
#include <stdio.h>
#include <mq.h>                       // Message Queuing header file

int main(int arg, char *argv[])

{
  ////////////////////////////////////////////////////////////////////
  //  Define structures.
  ////////////////////////////////////////////////////////////////////

  #define NUMBEROFPROPERTIES 1
  DWORD cPropId = 0;

  MQQUEUEPROPS qprops;
  PROPVARIANT aQueuePropVar[NUMBEROFPROPERTIES];
  QUEUEPROPID aQueuePropId[NUMBEROFPROPERTIES];
  HRESULT aQueueStatus[NUMBEROFPROPERTIES];

  HRESULT hr;
  DWORD dwFormatNameBufferLength = 256;
  WCHAR wszFormatNameBuffer[256];

  ////////////////////////////////////////////////////////////////////
  // Specify PROPID_Q_JOURNAL_QUOTA.
  ////////////////////////////////////////////////////////////////////

  aQueuePropId[cPropId] = PROPID_Q_JOURNAL_QUOTA; // Property ID
  aQueuePropVar[cPropId].vt = VT_UI4;            // Type indicator
  cPropId++;

  ////////////////////////////////////////////////////////////////////
  // Add additional queue properties here. When adding
  // properties, increment cProp to
  // reflect total number of properties.
  ////////////////////////////////////////////////////////////////////

  ////////////////////////////////////////////////////////////////////
  // Initialize the MQQUEUEPROPS structure.
  ////////////////////////////////////////////////////////////////////

  qprops.cProp = cPropId;           // Number of properties
  qprops.aPropID = aQueuePropId;        // Ids of properties
  qprops.aPropVar = aQueuePropVar;      // Values of properties
  qprops.aStatus = aQueueStatus;        // Error reports

  ////////////////////////////////////////////////////////////////////
  //Get format name of queue.
  ////////////////////////////////////////////////////////////////////

  hr = MQPathNameToFormatName(L".\\testqueue",
                              wszFormatNameBuffer,
                                  &dwFormatNameBufferLength);
  if (FAILED(hr))
  {
    fprintf(stderr, "Failed in MQPathNameToFormatName, error = 0x%x\n",hr);
  return -1;
  }

  ////////////////////////////////////////////////////////////////////
  // Get queue property.
  ////////////////////////////////////////////////////////////////////

  hr = MQGetQueueProperties(wszFormatNameBuffer, &qprops);
  if (FAILED(hr))
  {
    fprintf(stderr, "Failed in MQGetQueueProperties, error = 0x%x\n",hr);
    return -1;
  }

  ////////////////////////////////////////////////////////////////////
  // Review returned value. This example prints out the
  // maximum size of the queue journal of a known queue.
  ////////////////////////////////////////////////////////////////////

  printf("The maximum size of the known queue's "];
  printf("queue journal is ");

  if (aQueuePropVar[0].ulVal == -1)
     printf("INFINITE. \n");
     else
     printf("%d.\n",aQueuePropVar[0].ulVal);

  return 0;

}


Retrieving PROPID_Q_LABEL

The queue's label (PROPID_Q_LABEL) provides a description of the queue.

When you are retrieving PROPID_Q_LABEL, the type indicator in the MQQUEUEPROPS structure must be set to VT_NULL, and MQFreeMemory must be called after the return value is used. The VT_NULL setting tells Message Queuing to allocate the memory needed for the returned label, and MQFreeMemory frees the Message Queuing–allocated memory.

To retrieve PROPID_Q_LABEL

  1. Define the structures needed to retrieve the properties.
  2. Specify PROPID_Q_LABEL. The type indicator must be set to VT_NULL so that Message Queuing allocates memory for the label.
  3. Add any additional queue properties. When adding properties, increment the cProp variable to reflect the number of properties added.
  4. Initialize the MQQUEUEPROPS structure.
  5. Call MQPathNameToFormatName to retrieve a format name for the queue. Note the pathname of the queue indicates a local public queue whose name is "testqueue".
  6. Call MQGetQueueProperties.
  7. Examine the value of the returned property. In this example, the authentication level of the queue is printed to the screen.
  8. Call MQFreeMemory to free the memory allocated by Message Queuing.
For a code example using | See
C++ | C/C++ Code Example


C/C++ Code Example: Retrieving PROPID_Q_LABEL

The following example retrieves the PROPID_Q_LABEL property for a known queue and then prints the returned value to the screen. Note that the memory (used to store the label) allocated by Message Queuing is freed using MQFreeMemory.

#include <windows.h>
#include <stdio.h>
#include <mq.h>                   // Message Queuing header file

int main(int arg, char *argv[])

{
  ////////////////////////////
  //  Define structures.
  ////////////////////////////

  #define NUMBEROFPROPERTIES 1
  DWORD cPropId = 0;

  MQQUEUEPROPS qprops;
  PROPVARIANT aQueuePropVar[NUMBEROFPROPERTIES];
  QUEUEPROPID aQueuePropId[NUMBEROFPROPERTIES];
  HRESULT aQueueStatus[NUMBEROFPROPERTIES];

  HRESULT hr;
  DWORD dwFormatNameBufferLength = 256;
  WCHAR wszFormatNameBuffer[256];

  ////////////////////////////////////////////////////////////////////
  // Specify PROPID_Q_LABEL. The type
  // indicator must be set to VT_NULL.
  ////////////////////////////////////////////////////////////////////

  aQueuePropId[cPropId] = PROPID_Q_LABEL;    // Property ID
  aQueuePropVar[cPropId].vt = VT_NULL;       // Type indicator
  cPropId++;

  ////////////////////////////////////////////////////////////////////
  // Add additional queue properties here. When adding
  // properties, increment cProp to
  // reflect total number of properties.
  ////////////////////////////////////////////////////////////////////

  ////////////////////////////////////////////////////////////////////
  // Initialize the MQQUEUEPROPS structure.
  ////////////////////////////////////////////////////////////////////

  qprops.cProp = cPropId;           // Number of properties
  qprops.aPropID = aQueuePropId;        // Ids of properties
  qprops.aPropVar = aQueuePropVar;      // Values of properties
  qprops.aStatus = aQueueStatus;        // Error reports

  ////////////////////////////////////////////////////////////////////
  //Get format name of queue.
  ////////////////////////////////////////////////////////////////////

  hr = MQPathNameToFormatName(L".\\testqueue",
                              wszFormatNameBuffer,
                              &dwFormatNameBufferLength);
  if (FAILED(hr))
  {
    fprintf(stderr, "Failed in MQPathNameToFormatName, error = 0x%x\n",hr);
        return -1;
  }

  ////////////////////////////////////////////////////////////////////
  // Get queue property.
  ////////////////////////////////////////////////////////////////////

  hr = MQGetQueueProperties(wszFormatNameBuffer, &qprops);
  if (FAILED(hr))
  {
    fprintf(stderr, "Failed in MQGetQueueProperties, error = 0x%x\n",hr);
        return -1;
  }

  ////////////////////////////////////////////////////////////////////
  // Review returned value. This example prints
  // out the label of the queue.
  ////////////////////////////////////////////////////////////////////

  wprintf(L"The label of the queue is :");
  wprintf(L" %s.\n", aQueuePropVar[0].pwszVal);

  ////////////////////////////////////////////////////////////////////
  // Free memory allocated by Message Queuing.
  ////////////////////////////////////////////////////////////////////

MQFreeMemory(aQueuePropVar[0].pwszVal);
   if (FAILED(hr))
    {
    fprintf(stderr, "Failed in MQFreeMemory, error = 0x%x\n",hr);
        return -1;
    }

  return 0;

}


Retrieving PROPID_Q_MODIFY_TIME

The modify time of a queue (PROPID_Q_MODIFY_TIME) is set by Message Queuing whenever the queue's properties are set. This includes when Message Queuing creates the queue, when the properties are changed by MQSetQueueProperties, or through Message Queuing Explorer. Note that in this example, the C run-time function ctime() is used to display the returned value in a local date and time format.

Note When using C run-time functions, include time.h in your source code.

To retrieve PROPID_Q_MODIFY_TIME

  1. Define the structures needed to retrieve the properties.
  2. Specify PROPID_Q_MODIFY_TIME.
  3. Add any additional queue properties. When adding properties, increment the cProp variable to reflect the number of properties added.
  4. Initialize the MQQUEUEPROPS structure.
  5. Call MQPathNameToFormatName to retrieve a format name for the queue. Note the pathname of the queue indicates a local public queue whose name is "testqueue".
  6. Call MQGetQueueProperties.
  7. Examine the value of the returned property. In this example, ctime() is used to translate the returned value to a local date and time format.
For a code example using | See
C++ | C/C++ Code Example


C/C++ Code Example: Retrieving PROPID_Q_MODIFY_TIME

The following example retrieves the PROPID_Q_MODIFY_TIME property for a known queue and then prints the returned value to the screen.

#include <windows.h>
#include <stdio.h>
#include <mq.h>                       // Message Queuing header file
#include <time.h>                     // Defines ctime()

int main(int arg, char *argv[])

{
  ////////////////////////////////////////////////////////////////////
  //  Define structures.
  ////////////////////////////////////////////////////////////////////

  #define NUMBEROFPROPERTIES 1
  DWORD cPropId = 0;

  MQQUEUEPROPS qprops;
  PROPVARIANT aQueuePropVar[NUMBEROFPROPERTIES];
  QUEUEPROPID aQueuePropId[NUMBEROFPROPERTIES];
  HRESULT aQueueStatus[NUMBEROFPROPERTIES];

  HRESULT hr;
  DWORD dwFormatNameBufferLength = 256;
  WCHAR wszFormatNameBuffer[256];

  ////////////////////////////////////////////////////////////////////
  // Specify PROPID_Q_MODIFY_TIME.
  ////////////////////////////////////////////////////////////////////

  aQueuePropId[cPropId] = PROPID_Q_MODIFY_TIME; // Property ID
  aQueuePropVar[cPropId].vt = VT_I4;            // Type indicator
  cPropId++;

  ////////////////////////////////////////////////////////////////////
  // Add additional queue properties here. When adding
  // properties, increment cProp to
  // reflect total number of properties.
  ////////////////////////////////////////////////////////////////////

  ////////////////////////////////////////////////////////////////////
  // Initialize the MQQUEUEPROPS structure.
  ////////////////////////////////////////////////////////////////////

  qprops.cProp = cPropId;           // Number of properties
  qprops.aPropID = aQueuePropId;        // Ids of properties
  qprops.aPropVar = aQueuePropVar;      // Values of properties
  qprops.aStatus = aQueueStatus;        // Error reports

  ////////////////////////////////////////////////////////////////////
  //Get format name of queue.
  ////////////////////////////////////////////////////////////////////

  hr = MQPathNameToFormatName(L".\\testqueue",
                              wszFormatNameBuffer,
                                  &dwFormatNameBufferLength);
  if (FAILED(hr))
  {
    fprintf(stderr, "Failed in MQPathNameToFormatName, error = 0x%x\n",hr);
  return -1;
  }

  ////////////////////////////////////////////////////////////////////
  // Get queue property.
  ////////////////////////////////////////////////////////////////////

  hr = MQGetQueueProperties(wszFormatNameBuffer, &qprops);
  if (FAILED(hr))
  {
    fprintf(stderr, "Failed in MQGetQueueProperties, error = 0x%x\n",hr);
    return -1;
  }

  ////////////////////////////////////////////////////////////////////
  // Review returned value. This example prints out
  // when the queue's properties were last modified.
  ////////////////////////////////////////////////////////////////////

  printf("The queue's properties were last modified on ");
  printf("%s.\n", ctime(&aQueuePropVar[0].lVal));

  return 0;

}


Retrieving PROPID_Q_PATHNAME

The queue's pathname (PROPID_Q_PATHNAME) indicates the name of the computer where the queue's messages are stored, if the queue is public or private, and the name of the queue.

When PROPID_Q_PATHNAME is retrieved, the type indicator in the MQQUEUEPROPS structure must be set to VT_NULL, and MQFreeMemory must be called after the return value is used. The VT_NULL setting tells Message Queuing to allocate the memory needed for the returned pathname, and MQFreeMemory frees the Message Queuing allocated memory.

To retrieve PROPID_Q_PATHNAME

  1. Define the structures needed to retrieve the properties. These include the MQQUEUEPROPS structure.
  2. Specify PROPID_Q_PATHNAME. The type indicator must be set to VT_NULL so that Message Queuing allocates memory for the pathname.
  3. Add any additional queue properties. When adding properties, increment the cProp variable to reflect the number of properties added.
  4. Initialize the MQQUEUEPROPS structure.
  5. Call MQPathNameToFormatName to retrieve a format name for the queue. Note the pathname of the queue indicates a local public queue whose name is "testqueue".
  6. Call MQGetQueueProperties.
  7. Examine the value of the returned property. In this example, the pathname of the queue is printed to the screen.
  8. Call MQFreeMemory to free the memory allocated by Message Queuing.
For a code example using | See
C++ | C/C++ Code Example


C/C++ Code Example: Retrieving PROPID_Q_PATHNAME

The following example retrieves the PROPID_Q_PATHNAME property for a known queue and then prints the returned value to the screen. Note that the memory (used to store the label) allocated by Message Queuing is freed using MQFreeMemory.

#include <windows.h>
#include <stdio.h>
#include <mq.h>                   // Message Queuing header file

int main(int arg, char *argv[])

{
  ////////////////////////////////////////////////////////////////////
  //  Define structures.
  ////////////////////////////////////////////////////////////////////

  #define NUMBEROFPROPERTIES 1
  DWORD cPropId = 0;

  MQQUEUEPROPS qprops;
  PROPVARIANT aQueuePropVar[NUMBEROFPROPERTIES];
  QUEUEPROPID aQueuePropId[NUMBEROFPROPERTIES];
  HRESULT aQueueStatus[NUMBEROFPROPERTIES];

  HRESULT hr;
  DWORD dwFormatNameBufferLength = 256;
  WCHAR wszFormatNameBuffer[256];

  ////////////////////////////////////////////////////////////////////
  // Specify PROPID_Q_PATHNAME. The type
  // indicator must be set to VT_NULL.
  ////////////////////////////////////////////////////////////////////

  aQueuePropId[cPropId] = PROPID_Q_PATHNAME;    // Property ID
  aQueuePropVar[cPropId].vt = VT_NULL;       // Type indicator
  cPropId++;

  ////////////////////////////////////////////////////////////////////
  // Add additional queue properties here. When adding
  // properties, increment cProp to
  // reflect total number of properties.
  ////////////////////////////////////////////////////////////////////

  ////////////////////////////////////////////////////////////////////
  // Initialize the MQQUEUEPROPS structure.
  ////////////////////////////////////////////////////////////////////
  qprops.cProp = cPropId;           // Number of properties
  qprops.aPropID = aQueuePropId;        // Ids of properties
  qprops.aPropVar = aQueuePropVar;      // Values of properties
  qprops.aStatus = aQueueStatus;        // Error reports

  ////////////////////////////////////////////////////////////////////
  //Get format name of queue.
  ////////////////////////////////////////////////////////////////////

  hr = MQPathNameToFormatName(L".\\testqueue",
                              wszFormatNameBuffer,
                              &dwFormatNameBufferLength);
  if (FAILED(hr))
  {
    fprintf(stderr, "Failed in MQPathNameToFormatName, error = 0x%x\n",hr);
        return -1;
  }

  ////////////////////////////////////////////////////////////////////
  // Get queue property.
  ////////////////////////////////////////////////////////////////////

  hr = MQGetQueueProperties(wszFormatNameBuffer, &qprops);
  if (FAILED(hr))
  {
    fprintf(stderr, "Failed in MQGetQueueProperties, error = 0x%x\n",hr);
        return -1;
  }

  ////////////////////////////////////////////////////////////////////
  // Review returned value. This example prints
  // out the pathname of the queue.
  ////////////////////////////////////////////////////////////////////

  wprintf(L"The label of the queue is :");
  wprintf(L" %s.\n", aQueuePropVar[0].pwszVal);

  ////////////////////////////////////////////////////////////////////
  // Free memory allocated by Message Queuing.
  ////////////////////////////////////////////////////////////////////

  MQFreeMemory(aQueuePropVar[0].pwszVal);
  if (FAILED(hr))
    {
    fprintf(stderr, "Failed in MQFreeMemory, error = 0x%x\n",hr);
        return -1;
    }

  return 0;

}


Retrieving PROPID_Q_PRIV_LEVEL

The queue's privacy level (PROPID_Q_PRIV_LEVEL) specifies how the queue handles private (encrypted) messages. By default, a queue can accept private or non-private messages. However, PROPID_Q_PRIV_LEVEL can also be set to accept only private or non-private messages.

To retrieve PROPID_Q_PRIV_LEVEL

  1. Define the structures needed to retrieve the properties.
  2. Specify PROPID_Q_PRIV_LEVEL.
  3. Add any additional queue properties. When adding properties, increment the cProp variable to reflect the number of properties added.
  4. Initialize the MQQUEUEPROPS structure.
  5. Call MQPathNameToFormatName to retrieve a format name for the queue. Note the pathname of the queue indicates a local public queue whose name is "testqueue".
  6. Call MQGetQueueProperties.
  7. Examine the returned value of the property. This example prints out the privacy level of the queue.
For a code example using | See
C++ | C/C++ Code Example


C/C++ Code Example: Retrieving PROPID_Q_PRIV_LEVEL

The following example retrieves the PROPID_Q_PRIV_LEVEL property for a known queue and then prints the queue's privacy level to the screen.

#include <windows.h>
#include <stdio.h>
#include <mq.h>                       // Message Queuing header file

int main(int arg, char *argv[])

{
  ////////////////////////////////////////////////////////////////////
  //  Define structures.
  ////////////////////////////////////////////////////////////////////

  #define NUMBEROFPROPERTIES 1
  DWORD cPropId = 0;

  MQQUEUEPROPS qprops;
  PROPVARIANT aQueuePropVar[NUMBEROFPROPERTIES];
  QUEUEPROPID aQueuePropId[NUMBEROFPROPERTIES];
  HRESULT aQueueStatus[NUMBEROFPROPERTIES];

  HRESULT hr;
  DWORD dwFormatNameBufferLength = 256;
  WCHAR wszFormatNameBuffer[256];

  ////////////////////////////////////////////////////////////////////
  // Specify PROPID_Q_PRIV_LEVEL.
  ////////////////////////////////////////////////////////////////////

  aQueuePropId[cPropId] = PROPID_Q_PRIV_LEVEL; // Property ID
  aQueuePropVar[cPropId].vt = VT_UI4;          // Type indicator
  cPropId++;

  ////////////////////////////////////////////////////////////////////
  // Add additional queue properties here. When adding
  // properties, increment cProp to
  // reflect total number of properties.
  ////////////////////////////////////////////////////////////////////

  ////////////////////////////////////////////////////////////////////
  // Initialize the MQQUEUEPROPS structure.
  ////////////////////////////////////////////////////////////////////

  qprops.cProp = cPropId;           // Number of properties
  qprops.aPropID = aQueuePropId;        // Ids of properties
  qprops.aPropVar = aQueuePropVar;      // Values of properties
  qprops.aStatus = aQueueStatus;        // Error reports

  ////////////////////////////////////////////////////////////////////
  //Get format name of queue.
  ////////////////////////////////////////////////////////////////////

  hr = MQPathNameToFormatName(L".\\testqueue",
                              wszFormatNameBuffer,
                                  &dwFormatNameBufferLength);
  if (FAILED(hr))
  {
    fprintf(stderr, "Failed in MQPathNameToFormatName, error = 0x%x\n",hr);
  return -1;
  }

  ////////////////////////////////////////////////////////////////////
  // Get queue property.
  ////////////////////////////////////////////////////////////////////

  hr = MQGetQueueProperties(wszFormatNameBuffer, &qprops);
  if (FAILED(hr))
  {
    fprintf(stderr, "Failed in MQGetQueueProperties, error = 0x%x\n",hr);
    return -1;
  }

  ////////////////////////////////////////////////////////////////////
  // Review returned value. This example prints
  // out the privacy level of the queue.
  ////////////////////////////////////////////////////////////////////

  printf("The privacy level of the queue is ");

  if (aQueuePropVar[0].ulVal == MQ_PRIV_LEVEL_NONE)
     printf("MQ_PRIV_LEVEL_NONE. \n");
     else
        {
        if (aQueuePropVar[0].ulVal == MQ_PRIV_LEVEL_BODY)
          printf("MQ_PRIV_LEVEL_BODY. \n");
          else
          printf("MQ_PRIV_LEVEL_OPTIONAL. \n");
        }

  return 0;

}


Retrieving PROPID_Q_QUOTA

The queue's quota (PROPID_Q_QUOTA) is the maximum size of the queue. By default, a queue's maximum size is set to INFINITE.

To retrieve PROPID_Q_QUOTA

  1. Define the structures needed to retrieve the properties. This includes the MQQUEUEPROPS structure.
  2. Specify PROPID_Q_QUOTA.
  3. Add any additional queue properties. When adding properties, increment the cProp variable to reflect the number of properties added.
  4. Initialize the MQQUEUEPROPS structure.
  5. Call MQPathNameToFormatName to retrieve a format name for the queue. Note the pathname of the queue indicates a local public queue whose name is "testqueue".
  6. Call MQGetQueueProperties.
  7. Examine the returned value of the property.
For a code example using | See
C++ | C/C++ Code Example


C/C++ Code Example: Retrieving PROPID_Q_QUOTA

The following example retrieves the PROPID_Q_QUOTA property for a known queue and then prints the returned value to the screen.

#include <windows.h>
#include <stdio.h>
#include <mq.h>                       // Message Queuing header file

int main(int arg, char *argv[])

{
  ////////////////////////////////////////////////////////////////////
  //  Define structures.
  ////////////////////////////////////////////////////////////////////

  #define NUMBEROFPROPERTIES 1
  DWORD cPropId = 0;

  MQQUEUEPROPS qprops;
  PROPVARIANT aQueuePropVar[NUMBEROFPROPERTIES];
  QUEUEPROPID aQueuePropId[NUMBEROFPROPERTIES];
  HRESULT aQueueStatus[NUMBEROFPROPERTIES];

  HRESULT hr;
  DWORD dwFormatNameBufferLength = 256;
  WCHAR wszFormatNameBuffer[256];

  ////////////////////////////////////////////////////////////////////
  // Specify PROPID_Q_QUOTA.
  ////////////////////////////////////////////////////////////////////

  aQueuePropId[cPropId] = PROPID_Q_QUOTA;    // Property ID
  aQueuePropVar[cPropId].vt = VT_UI4;        // Type indicator
  cPropId++;

  ////////////////////////////////////////////////////////////////////
  // Add additional queue properties here. When adding
  // properties, increment cProp to
  // reflect total number of properties.
  ////////////////////////////////////////////////////////////////////

  ////////////////////////////////////////////////////////////////////
  // Initialize the MQQUEUEPROPS structure.
  ////////////////////////////////////////////////////////////////////

  qprops.cProp = cPropId;           // Number of properties
  qprops.aPropID = aQueuePropId;        // Ids of properties
  qprops.aPropVar = aQueuePropVar;      // Values of properties
  qprops.aStatus = aQueueStatus;        // Error reports

  ////////////////////////////////////////////////////////////////////
  //Get format name of queue.
  ////////////////////////////////////////////////////////////////////

  hr = MQPathNameToFormatName(L".\\testqueue",
                              wszFormatNameBuffer,
                                  &dwFormatNameBufferLength);
  if (FAILED(hr))
  {
    fprintf(stderr, "Failed in MQPathNameToFormatName, error = 0x%x\n",hr);
  return -1;
  }

  ////////////////////////////////////////////////////////////////////
  // Get queue property.
  ////////////////////////////////////////////////////////////////////

  hr = MQGetQueueProperties(wszFormatNameBuffer, &qprops);
  if (FAILED(hr))
  {
    fprintf(stderr, "Failed in MQGetQueueProperties, error = 0x%x\n",hr);
    return -1;
  }

  ////////////////////////////////////////////////////////////////////
  // Review returned value. This example prints
  // out the maximum size of the queue.
  ////////////////////////////////////////////////////////////////////

  printf("The maximum size of the queue is ");

  if (aQueuePropVar[0].ulVal == -1)
     printf("INFINITE. \n");
     else
     printf("%d.\n",aQueuePropVar[0].ulVal);

  return 0;

}


Retrieving PROPID_Q_TRANSACTION

The queue's transaction level (PROPID_Q_TRANSACTION) specifies whether the queue accepts transactional messages or non-transactional messages. It cannot accept both. By default, a queue is created as a non-transactional queue.

Unlike most queue properties, PROPID_Q_TRANSACTION can be set only when the queue is created.

To retrieve PROPID_Q_TRANSACTION

  1. Define the structures needed to retrieve the properties. This includes the MQQUEUEPROPS structure.
  2. Specify PROPID_Q_TRANSACTION.
  3. Add any additional queue properties. When adding properties, increment the cProp variable to reflect the number of properties added.
  4. Initialize the MQQUEUEPROPS structure.
  5. Call MQPathNameToFormatName to retrieve a format name for the queue. Note the pathname of the queue indicates a local public queue whose name is "testqueue".
  6. Call MQGetQueueProperties.
  7. Examine the value of the returned property. In this example, the transaction level of the queue is printed to the screen.
For a code example using | See
C++ | C/C++ Code Example


C/C++ Code Example: Retrieving PROPID_Q_TRANSACTION

The following example retrieves the PROPID_Q_TRANSACTION property for a known queue and then prints the returned value to the screen.

#include <windows.h>
#include <stdio.h>
#include <mq.h>                       // Message Queuing header file

int main(int arg, char *argv[])

{
  ////////////////////////////////////////////////////////////////////
  //  Define structures.
  ////////////////////////////////////////////////////////////////////

  #define NUMBEROFPROPERTIES 1
  DWORD cPropId = 0;

  MQQUEUEPROPS qprops;
  PROPVARIANT aQueuePropVar[NUMBEROFPROPERTIES];
  QUEUEPROPID aQueuePropId[NUMBEROFPROPERTIES];
  HRESULT aQueueStatus[NUMBEROFPROPERTIES];

  HRESULT hr;
  DWORD dwFormatNameBufferLength = 256;
  WCHAR wszFormatNameBuffer[256];

  ////////////////////////////////////////////////////////////////////
  // Specify PROPID_Q_TRANSACTION.
  ////////////////////////////////////////////////////////////////////

  aQueuePropId[cPropId] = PROPID_Q_TRANSACTION; // Property ID
  aQueuePropVar[cPropId].vt = VT_UI1;            // Type indicator
  cPropId++;

  ////////////////////////////////////////////////////////////////////
  // Add additional queue properties here. When adding
  // properties, increment cProp to
  // reflect total number of properties.
  ////////////////////////////////////////////////////////////////////

  ////////////////////////////////////////////////////////////////////
  // Initialize the MQQUEUEPROPS structure.
  ////////////////////////////////////////////////////////////////////

  qprops.cProp = cPropId;           // Number of properties
  qprops.aPropID = aQueuePropId;        // Ids of properties
  qprops.aPropVar = aQueuePropVar;      // Values of properties
  qprops.aStatus = aQueueStatus;        // Error reports

  ////////////////////////////////////////////////////////////////////
  //Get format name of queue.
  ////////////////////////////////////////////////////////////////////

  hr = MQPathNameToFormatName(L".\\testqueue",
                              wszFormatNameBuffer,
                                  &dwFormatNameBufferLength);
  if (FAILED(hr))
  {
    fprintf(stderr, "Failed in MQPathNameToFormatName, error = 0x%x\n",hr);
  return -1;
  }

  ////////////////////////////////////////////////////////////////////
  // Get queue property.
  ////////////////////////////////////////////////////////////////////

  hr = MQGetQueueProperties(wszFormatNameBuffer, &qprops);
  if (FAILED(hr))
  {
    fprintf(stderr, "Failed in MQGetQueueProperties, error = 0x%x\n",hr);
    return -1;
  }

  ////////////////////////////////////////////////////////////////////
  // Review returned value. This example prints
  // out the authentication level of the queue.
  ////////////////////////////////////////////////////////////////////

  if (aQueuePropVar[0].bVal == MQ_TRANSACTIONAL)
        printf("PROPID_Q_TRANSACTION is set to MQ_TRANSACTIONAL.\n");
    else
    printf("PROPID_Q_TRANSACTION is set to MQ_TRANSACTIONAL_NONE.\n");

  return 0;

}


Retrieving PROPID_Q_TYPE

The queue's type (PROPID_Q_TYPE) identifies the queue. Some queue types are defined by Message Queuing. However, applications can define their own queue types so that they can later locate a set of queues by their type.

Note For locating queues see MQLocateBegin.

When retrieving the queue type, you must allocate a buffer of type CLSID for the returned GUID.

To retrieve PROPID_Q_TYPE

  1. Define the structures needed to retrieve the properties. This includes the CLSID structure for the returned type GUID.
  2. Specify PROPID_Q_TYPE.
  3. Add any additional queue properties. When adding properties, increment the cProp variable to reflect the number of properties added.
  4. Initialize the MQQUEUEPROPS structure.
  5. Call MQPathNameToFormatName to retrieve a format name for the queue. Note the pathname of the queue indicates a local public queue whose name is "testqueue".
  6. Call MQGetQueueProperties.
  7. Examine the value of the returned property. In this example, the type of the queue is printed to the screen.
For a code example using | See
C++ | C/C++ Code Example


C/C++ Code Example: Retrieving PROPID_Q_TYPE

The following example retrieves the PROPID_Q_TYPE property for a known queue and then prints the returned value to the screen. This example uses the RPC function UuidToString to display the type GUID of the queue. The library and header files for this function are rpcrt4.lib and rpc.h respectively.

#include <windows.h>
#include <stdio.h>
#include <mq.h>                   // Message Queuing header file
#include <rpc.h>                  // Defines UuidToString

int main(int arg, char *argv[])

{
  ////////////////////////////////////////////////////////////////////
  //  Define structures.
 ////////////////////////////////////////////////////////////////////

  #define NUMBEROFPROPERTIES 1
  DWORD cPropId = 0;

  MQQUEUEPROPS qprops;
  PROPVARIANT aQueuePropVar[NUMBEROFPROPERTIES];
  QUEUEPROPID aQueuePropId[NUMBEROFPROPERTIES];
  HRESULT aQueueStatus[NUMBEROFPROPERTIES];

  HRESULT hr;
  DWORD dwFormatNameBufferLength = 256;
  WCHAR wszFormatNameBuffer[256];

  // Define buffer for returned type GUID.
  CLSID TypeBuffer;

  ////////////////////////////////////////////////////////////////////
  // Specify PROPID_Q_TYPE.
  ////////////////////////////////////////////////////////////////////

  aQueuePropId[cPropId] = PROPID_Q_TYPE;    // Property ID
  aQueuePropVar[cPropId].vt = VT_CLSID;         // Type indicator
  aQueuePropVar[cPropId].puuid = &TypeBuffer;
  cPropId++;

  ////////////////////////////////////////////////////////////////////
  // Add additional queue properties here. When adding
  // properties, increment cProp to
  // reflect total number of properties.
  ////////////////////////////////////////////////////////////////////

  ////////////////////////////////////////////////////////////////////
  // Initialize the MQQUEUEPROPS structure.
  ////////////////////////////////////////////////////////////////////
  qprops.cProp = cPropId;           // Number of properties
  qprops.aPropID = aQueuePropId;        // Ids of properties
  qprops.aPropVar = aQueuePropVar;      // Values of properties
  qprops.aStatus = aQueueStatus;        // Error reports

  ////////////////////////////////////////////////////////////////////
  //Get format name of queue.
  ////////////////////////////////////////////////////////////////////

  hr = MQPathNameToFormatName(L".\\testqueue",
                              wszFormatNameBuffer,
                              &dwFormatNameBufferLength);
  if (FAILED(hr))
  {
    fprintf(stderr, "Failed in MQPathNameToFormatName, error = 0x%x\n",hr);
        return -1;
  }

  ////////////////////////////////////////////////////////////////////
  // Get queue property.
  ////////////////////////////////////////////////////////////////////

  hr = MQGetQueueProperties(wszFormatNameBuffer, &qprops);
  if (FAILED(hr))
  {
    fprintf(stderr, "Failed in MQGetQueueProperties, error = 0x%x\n",hr);
        return -1;
  }

  ////////////////////////////////////////////////////////////////////
  // Review returned value. This example prints
  // out the type of the queue.
  ////////////////////////////////////////////////////////////////////

  UCHAR *pszTypeGUID;
  if (UuidToString(aQueuePropVar[0].puuid, &pszTypeGUID)== RPC_S_OK)
  {
    printf("The identifier for this queue is: ");
    printf("%s.\n", pszTypeGUID);
    RpcStringFree(&pszTypeGUID);
  }

  return 0;

}


Setting a Queue Properties

Platform SDK: Message Queuing

Setting Queue Properties

After a queue is created, its properties can be dynamically set by calling MQSetQueueProperties. All open instances of the queue are immediately affected when MQSetQueueProperties is called.

Note Not all properties can be set by MQSetQueueProperties. If an example of setting a property is not listed below, the property is only be set by Message Queuing, or it can only be set when the queue is created.

For an example of | See
Setting the authentication level of the queue | Setting PROPID_Q_AUTHENTICATE
Setting the priority level of the queue | Setting PROPID_Q_BASEPRIORITY
Setting the journaling level of the queue | Setting PROPID_Q_JOURNAL
Setting the maximum size of the queue journal | Setting PROPID_Q_JOURNAL_QUOTA
Setting the label of the queue | Setting PROPID_Q_LABEL
Setting the privacy level of the queue | Setting PROPID_Q_PRIV_LEVEL
Setting the maximum size of the queue | Setting PROPID_Q_QUOTA
Setting the type of service performed by the queue | Setting PROPID_Q_TYPE


Setting PROPID_Q_AUTHENTICATE

The authentication level of the queue (PROPID_Q_AUTHENTICATE) specifies whether the queue accepts only authenticated messages. By default, a queue accepts both authenticated and non-authenticated messages.

Note In most cases, any application can set a queue's properties. However, if MQ_ERROR_ACCESS_DENIED is returned by MQSetQueueProperties, the queue's access control is blocking the application from setting the properties of the queue. For information about access rights, see Access Control.

To set PROPID_Q_AUTHENTICATE

  1. Define the structures needed to set queue properties.
  2. Specify PROPID_Q_AUTHENTICATE, indicating the new authentication level of the queue.
  3. Optional. Add additional properties as needed. This example only sets the authentication level of the queue.
  4. Initialize the MQQUEUEPROPS structure.
  5. Call MQPathNameToFormatName to retrieve a format name for the queue. Note the pathname of the queue indicates a local public queue whose name is "testqueue".
  6. Call MQSetQueueProperties to set the authentication level of the queue.
For a code example using | See
C++ | C/C++ Code Example


C/C++ Code Example: Setting PROPID_Q_AUTHENTICATE

The following example sets the PROPID_Q_AUTHENTICATE property for a known queue and then prints the new value to the screen.

#include <windows.h>
#include <stdio.h>
#include <mq.h>                   // Message Queuing header file

int main(int arg, char *argv[])

{
  //////////////////////////////////////////////////////////
  //  Define the required structures.
  //////////////////////////////////////////////////////////

  #define NUMBEROFPROPERTIES 1
  DWORD cPropId = 0;

  MQQUEUEPROPS qprops;
  PROPVARIANT aQueuePropVar[NUMBEROFPROPERTIES];
  QUEUEPROPID aQueuePropId[NUMBEROFPROPERTIES];
  HRESULT aQueueStatus[NUMBEROFPROPERTIES];

  HRESULT hr;
  DWORD dwFormatNameBufferLength = 256;
  WCHAR wszFormatNameBuffer[256];

  //////////////////////////////////////////////////////////
  // Specify PROPID_Q_AUTHENTICATE.
  //////////////////////////////////////////////////////////

  aQueuePropId[cPropId] = PROPID_Q_AUTHENTICATE; // Property ID
  aQueuePropVar[cPropId].vt = VT_UI1;            // Type indicator
  aQueuePropVar[cPropId].bVal = MQ_AUTHENTICATE; // New setting
  cPropId++;

  ////////////////////////////////////////////////////////
  // Add additional queue properties here. When adding
  // properties, increment cProp to
  // reflect total number of properties.
  //////////////////////////////////////////////////////////

  //////////////////////////////////////////////////////////
  // Initialize the MQQUEUEPROPS structure.
  //////////////////////////////////////////////////////////

  qprops.cProp = cPropId;           // Number of properties
  qprops.aPropID = aQueuePropId;        // Ids of properties
  qprops.aPropVar = aQueuePropVar;      // Values of properties
  qprops.aStatus = aQueueStatus;        // Error reports

  //////////////////////////////////////////////////////////
  //Get format name of queue.
  //////////////////////////////////////////////////////////

  hr = MQPathNameToFormatName(L".\\testqueue",
                              wszFormatNameBuffer,
                                  &dwFormatNameBufferLength);
  if (FAILED(hr))
  {
     fprintf(stderr, "Failed in MQPathNameToFormatName, error = 0x%x\n",hr);
     return -1;
  }

  //////////////////////////////////////////////////////////
  // Set queue property.
  //////////////////////////////////////////////////////////

  hr = MQSetQueueProperties(wszFormatNameBuffer, &qprops);
  if (FAILED(hr))
  {
     fprintf(stderr, "Failed in MQGetQueueProperties, error = 0x%x\n",hr);
     return -1;
  }

  //////////////////////////////////////////////////////////
  // Review new value. This example prints
  // out the authentication level of the queue.
  //////////////////////////////////////////////////////////

  if (aQueuePropVar[0].bVal == MQ_AUTHENTICATE)
      printf("PROPID_Q_AUTHENTICATE is set to MQ_AUTHENTICATE.\n");
  else
     printf("PROPID_Q_AUTHENTICATE is set to MQ_AUTHENTICATE_NONE.\n");

  return 0;

}


Setting PROPID_Q_BASEPRIORITY

The priority level of a queue (PROPID_Q_BASEPRIORITY) specifies a single base priority for all messages sent to a public queue. By default, the priority level of a queue is 0.

Note In most cases, any application can set a queue's properties. However, if MQ_ERROR_ACCESS_DENIED is returned by MQSetQueueProperties, the queue's access control is blocking the application from setting the properties of the queue. For information about access rights, see Access Control.

To set PROPID_Q_BASEPRIORITY

  1. Define the structures needed to set queue properties.
  2. Specify PROPID_Q_BASEPRIORITY, indicating the new authentication level of the queue.
  3. Optional. Add additional properties as needed. This example only sets the priority level of the queue.
  4. Initialize the MQQUEUEPROPS structure.
  5. Call MQPathNameToFormatName to retrieve a format name for the queue. Note the pathname of the queue indicates a local public queue whose name is "testqueue".
  6. Call MQSetQueueProperties to set the priority level of the queue.
For a code example using | See
C++ | C/C++ Code Example


C/C++ Code Example: Setting PROPID_Q_BASEPRIORITY

The following example sets the PROPID_Q_BASEPRIORITY property for a known queue and then prints the new value to the screen.

#include <windows.h>
#include <stdio.h>
#include <mq.h>                   // Message Queuing header file

int main(int arg, char *argv[])

{
  //////////////////////////////////////////////////////////
  //  Define the required structures.
  //////////////////////////////////////////////////////////

  #define NUMBEROFPROPERTIES 1
  DWORD cPropId = 0;

  MQQUEUEPROPS qprops;
  PROPVARIANT aQueuePropVar[NUMBEROFPROPERTIES];
  QUEUEPROPID aQueuePropId[NUMBEROFPROPERTIES];
  HRESULT aQueueStatus[NUMBEROFPROPERTIES];

  HRESULT hr;
  DWORD dwFormatNameBufferLength = 256;
  WCHAR wszFormatNameBuffer[256];

  //////////////////////////////////////////////////////////
  // Specify PROPID_Q_BASEPRIORITY.
  //////////////////////////////////////////////////////////

  aQueuePropId[cPropId] = PROPID_Q_BASEPRIORITY; // Property ID
  aQueuePropVar[cPropId].vt = VT_I2;             // Type indicator
  aQueuePropVar[cPropId].iVal = 1000;            // New setting
  cPropId++;

  ////////////////////////////////////////////////////////
  // Add additional queue properties here. When adding
  // properties, increment cProp to
  // reflect total number of properties.
  //////////////////////////////////////////////////////////

  //////////////////////////////////////////////////////////
  // Initialize the MQQUEUEPROPS structure.
  //////////////////////////////////////////////////////////

  qprops.cProp = cPropId;           // Number of properties
  qprops.aPropID = aQueuePropId;        // Ids of properties
  qprops.aPropVar = aQueuePropVar;      // Values of properties
  qprops.aStatus = aQueueStatus;        // Error reports

  //////////////////////////////////////////////////////////
  //Get format name of queue.
  //////////////////////////////////////////////////////////

  hr = MQPathNameToFormatName(L".\\testqueue",
                              wszFormatNameBuffer,
                                  &dwFormatNameBufferLength);
  if (FAILED(hr))
  {
     fprintf(stderr, "Failed in MQPathNameToFormatName, error = 0x%x\n",hr);
     return -1;
  }

  //////////////////////////////////////////////////////////
  // Set queue property.
  //////////////////////////////////////////////////////////

  hr = MQSetQueueProperties(wszFormatNameBuffer, &qprops);
  if (FAILED(hr))
  {
     fprintf(stderr, "Failed in MQGetQueueProperties, error = 0x%x\n",hr);
     return -1;
  }

  //////////////////////////////////////////////////////////
  // Review new value. This example prints
  // out the priority level of the queue.
  //////////////////////////////////////////////////////////

  printf("PROPID_Q_BASEPRIORITY is set to ");
  printf("%d.\n", aQueuePropVar[0].iVal);

  return 0;

}


Setting PROPID_Q_JOURNAL

The journaling level of the queue (PROPID_Q_JOURNAL) specifies whether messages retrieved from the queue are also copied to the queue's queue journal. By default, messages are not copied to the queue journal.

Note In most cases, any application can set a queue's properties. However, if MQ_ERROR_ACCESS_DENIED is returned by MQSetQueueProperties, the queue's access control is blocking the application from setting the properties of the queue. For information about access rights, see Access Control.

To set PROPID_Q_JOURNAL

  1. Define the structures needed to set queue properties.
  2. Specify PROPID_Q_JOURNAL, indicating the new journaling level of the queue.
  3. Optional. Add additional properties as needed. This example only sets the journaling level of the queue.
  4. Initialize the MQQUEUEPROPS structure.
  5. Call MQPathNameToFormatName to retrieve a format name for the queue. Note the pathname of the queue indicates a local public queue whose name is "testqueue".
  6. Call MQSetQueueProperties to set the journaling level of the queue.
For a code example using | See
C++ | C/C++ Code Example


C/C++ Code Example: Setting PROPID_Q_JOURNAL

The following example sets the PROPID_Q_JOURNAL property for a known queue and then prints the new value to the screen.

#include <windows.h>
#include <stdio.h>
#include <mq.h>                   // Message Queuing header file

int main(int arg, char *argv[])

{
  //////////////////////////////////////////////////////////
  //  Define the required structures.
  //////////////////////////////////////////////////////////

  #define NUMBEROFPROPERTIES 1
  DWORD cPropId = 0;

  MQQUEUEPROPS qprops;
  PROPVARIANT aQueuePropVar[NUMBEROFPROPERTIES];
  QUEUEPROPID aQueuePropId[NUMBEROFPROPERTIES];
  HRESULT aQueueStatus[NUMBEROFPROPERTIES];

  HRESULT hr;
  DWORD dwFormatNameBufferLength = 256;
  WCHAR wszFormatNameBuffer[256];

  //////////////////////////////////////////////////////////
  // Specify PROPID_Q_JOURNAL.
  //////////////////////////////////////////////////////////

  aQueuePropId[cPropId] = PROPID_Q_JOURNAL;   // Property ID
  aQueuePropVar[cPropId].vt = VT_I1;          // Type indicator
  aQueuePropVar[cPropId].bVal = MQ_JOURNAL;   // New setting
  cPropId++;

  ////////////////////////////////////////////////////////
  // Add additional queue properties here. When adding
  // properties, increment cProp to
  // reflect total number of properties.
  //////////////////////////////////////////////////////////

  //////////////////////////////////////////////////////////
  // Initialize the MQQUEUEPROPS structure.
  //////////////////////////////////////////////////////////

  qprops.cProp = cPropId;           // Number of properties
  qprops.aPropID = aQueuePropId;        // Ids of properties
  qprops.aPropVar = aQueuePropVar;      // Values of properties
  qprops.aStatus = aQueueStatus;        // Error reports

  //////////////////////////////////////////////////////////
  //Get format name of queue.
  //////////////////////////////////////////////////////////

  hr = MQPathNameToFormatName(L".\\testqueue",
                              wszFormatNameBuffer,
                                  &dwFormatNameBufferLength);
  if (FAILED(hr))
  {
     fprintf(stderr, "Failed in MQPathNameToFormatName, error = 0x%x\n",hr);
     return -1;
  }

  //////////////////////////////////////////////////////////
  // Set queue property.
  //////////////////////////////////////////////////////////

  hr = MQSetQueueProperties(wszFormatNameBuffer, &qprops);
  if (FAILED(hr))
  {
     fprintf(stderr, "Failed in MQGetQueueProperties, error = 0x%x\n",hr);
     return -1;
  }

  //////////////////////////////////////////////////////////
  // Review new value. This example prints
  // out the journaling level of the queue.
  //////////////////////////////////////////////////////////

  if (aQueuePropVar[0].bVal == MQ_JOURNAL)
     printf("PROPID_Q_JOURNAL is set to MQ_JOURNAL.\n");
  else
     printf("PROPID_Q_JOURNAL is set to MQ_JOURNAL_NONE.\n");

  return 0;

}


Setting PROPID_Q_JOURNAL_QUOTA

The queue journal's quota (PROPID_Q_JOURNAL_QUOTA) is the maximum size of the queue journal. By default, a queue journal's maximum size is set to INFINITE.

Note In most cases, any application can set a queue's properties. However, if MQ_ERROR_ACCESS_DENIED is returned by MQSetQueueProperties, the queue's access control is blocking the application from setting the properties of the queue. For information about access rights, see Access Control.

To set PROPID_Q_JOURNAL_QUOTA

  1. Define the structures needed to set queue properties.
  2. Specify PROPID_Q_JOURNAL_QUOTA, indicating the new maximum size of the queue journal.
  3. Optional. Add additional properties as needed. This example only sets the maximum size of the queue journal.
  4. Initialize the MQQUEUEPROPS structure.
  5. Call MQPathNameToFormatName to retrieve a format name for the queue. Note the pathname of the queue indicates a local public queue whose name is "testqueue".
  6. Call MQSetQueueProperties to set the maximum size of the queue journal.
For a code example using | See
C++ | C/C++ Code Example


C/C++ Code Example: Setting PROPID_Q_JOURNAL_QUOTA

The following example sets the PROPID_Q_JOURNAL_QUOTA property for a known queue and then prints the new value to the screen.

#include <windows.h>
#include <stdio.h>
#include <mq.h>                   // Message Queuing header file

int main(int arg, char *argv[])

{
  //////////////////////////////////////////////////////////
  //  Define the required structures.
  //////////////////////////////////////////////////////////

  #define NUMBEROFPROPERTIES 1
  DWORD cPropId = 0;

  MQQUEUEPROPS qprops;
  PROPVARIANT aQueuePropVar[NUMBEROFPROPERTIES];
  QUEUEPROPID aQueuePropId[NUMBEROFPROPERTIES];
  HRESULT aQueueStatus[NUMBEROFPROPERTIES];

  HRESULT hr;
  DWORD dwFormatNameBufferLength = 256;
  WCHAR wszFormatNameBuffer[256];

  //////////////////////////////////////////////////////////
  // Specify PROPID_Q_JOURNAL_QUOTA.
  //////////////////////////////////////////////////////////

  aQueuePropId[cPropId] = PROPID_Q_JOURNAL_QUOTA; // Property ID
  aQueuePropVar[cPropId].vt = VT_I4;             // Type indicator
  aQueuePropVar[cPropId].ulVal = 100;            // New setting
  cPropId++;

  ////////////////////////////////////////////////////////
  // Add additional queue properties here. When adding
  // properties, increment cProp to
  // reflect total number of properties.
  //////////////////////////////////////////////////////////

  //////////////////////////////////////////////////////////
  // Initialize the MQQUEUEPROPS structure.
  //////////////////////////////////////////////////////////

  qprops.cProp = cPropId;           // Number of properties
  qprops.aPropID = aQueuePropId;        // Ids of properties
  qprops.aPropVar = aQueuePropVar;      // Values of properties
  qprops.aStatus = aQueueStatus;        // Error reports

  //////////////////////////////////////////////////////////
  //Get format name of queue.
  //////////////////////////////////////////////////////////

  hr = MQPathNameToFormatName(L".\\testqueue",
                              wszFormatNameBuffer,
                                  &dwFormatNameBufferLength);
  if (FAILED(hr))
  {
     fprintf(stderr, "Failed in MQPathNameToFormatName, error = 0x%x\n",hr);
     return -1;
  }

  //////////////////////////////////////////////////////////
  // Set queue property.
  //////////////////////////////////////////////////////////

  hr = MQSetQueueProperties(wszFormatNameBuffer, &qprops);
  if (FAILED(hr))
  {
     fprintf(stderr, "Failed in MQGetQueueProperties, error = 0x%x\n",hr);
     return -1;
  }

  //////////////////////////////////////////////////////////
  // Review new value. This example prints
  // out the maximum size of the queue journal.
  //////////////////////////////////////////////////////////

  printf("PROPID_Q_JOURNAL_QUOTA is set to ");
  printf("%d.\n", aQueuePropVar[0].ulVal);

  return 0;

}


Setting PROPID_Q_LABEL

The queue's label (PROPID_Q_LABEL) provides a description of the queue.

Note In most cases, any application can set a queue's properties. However, if MQ_ERROR_ACCESS_DENIED is returned by MQSetQueueProperties, the queue's access control is blocking the application from setting the properties of the queue. For information about access rights, see Access Control.

To set PROPID_Q_LABEL

  1. Define the structures needed to set queue properties.
  2. Specify PROPID_Q_LABEL, indicating the new label of the queue.
  3. Optional. Add additional properties as needed. This example only sets a new label for the queue.
  4. Initialize the MQQUEUEPROPS structure.
  5. Call MQPathNameToFormatName to retrieve a format name for the queue. Note the pathname of the queue indicates a local public queue whose name is "testqueue".
  6. Call MQSetQueueProperties to set the label of the queue.
For a code example using | See
C++ | C/C++ Code Example


C/C++ Code Example: Setting PROPID_Q_LABEL

The following example sets the PROPID_Q_LABEL property for a known queue and then prints the new value to the screen.

#include <windows.h>
#include <stdio.h>
#include <mq.h>                   // Message Queuing header file

int main(int arg, char *argv[])

{
  //////////////////////////////////////////////////////////
  //  Define the required structures.
  //////////////////////////////////////////////////////////

  #define NUMBEROFPROPERTIES 1
  DWORD cPropId = 0;

  MQQUEUEPROPS qprops;
  PROPVARIANT aQueuePropVar[NUMBEROFPROPERTIES];
  QUEUEPROPID aQueuePropId[NUMBEROFPROPERTIES];
  HRESULT aQueueStatus[NUMBEROFPROPERTIES];

  HRESULT hr;
  DWORD dwFormatNameBufferLength = 256;
  WCHAR wszFormatNameBuffer[256];

  //////////////////////////////////////////////////////////
  // Specify PROPID_Q_LABEL.
  //////////////////////////////////////////////////////////

  aQueuePropId[cPropId] = PROPID_Q_LABEL; // Property ID
  aQueuePropVar[cPropId].vt = VT_LPWSTR;  // Type indicator
  aQueuePropVar[cPropId].pwszVal = L"New Label"; // New setting
  cPropId++;

  ////////////////////////////////////////////////////////
  // Add additional queue properties here. When adding
  // properties, increment cProp to
  // reflect total number of properties.
  //////////////////////////////////////////////////////////

  //////////////////////////////////////////////////////////
  // Initialize the MQQUEUEPROPS structure.
  //////////////////////////////////////////////////////////

  qprops.cProp = cPropId;           // Number of properties
  qprops.aPropID = aQueuePropId;        // Ids of properties
  qprops.aPropVar = aQueuePropVar;      // Values of properties
  qprops.aStatus = aQueueStatus;        // Error reports

  //////////////////////////////////////////////////////////
  //Get format name of queue.
  //////////////////////////////////////////////////////////

  hr = MQPathNameToFormatName(L".\\testqueue",
                              wszFormatNameBuffer,
                                  &dwFormatNameBufferLength);
  if (FAILED(hr))
  {
     fprintf(stderr, "Failed in MQPathNameToFormatName, error = 0x%x\n",hr);
     return -1;
  }

  //////////////////////////////////////////////////////////
  // Set queue property.
  //////////////////////////////////////////////////////////

  hr = MQSetQueueProperties(wszFormatNameBuffer, &qprops);
  if (FAILED(hr))
  {
     fprintf(stderr, "Failed in MQGetQueueProperties, error = 0x%x\n",hr);
     return -1;
  }

  //////////////////////////////////////////////////////////
  // Review new value. This example prints
  // out the new label of the queue.
  //////////////////////////////////////////////////////////

  printf("The new queue label is :");
  wprintf(L" %s.\n",aQueuePropVar[0].pwszVal);

  return 0;

}


Setting PROPID_Q_PRIV_LEVEL

The queue's privacy level (PROPID_Q_PRIV_LEVEL) specifies how the queue handles private (encrypted) messages. By default, a queue can accept private or non-private messages.

Note In most cases, any application can set a queue's properties. However, if MQ_ERROR_ACCESS_DENIED is returned by MQSetQueueProperties, the queue's access control is blocking the application from setting the properties of the queue. For information about access rights, see Access Control.

To set PROPID_Q_PRIV_LEVEL

  1. Define the structures needed to set queue properties.
  2. Specify PROPID_Q_PRIV_LEVEL, indicating the new privacy level of the queue.
  3. Optional. Add additional properties as needed. This example only sets the privacy level of the queue.
  4. Initialize the MQQUEUEPROPS structure.
  5. Call MQPathNameToFormatName to retrieve a format name for the queue. Note the pathname of the queue indicates a local public queue whose name is "testqueue".
  6. Call MQSetQueueProperties to set the privacy level of the queue.
For a code example using | See
C++ | C/C++ Code Example


C/C++ Code Example: Setting PROPID_Q_PRIV_LEVEL

The following example sets the PROPID_Q_PRIV_LEVEL property for a known queue and then prints the new value to the screen.

#include <windows.h>
#include <stdio.h>
#include <mq.h>                   // Message Queuing header file

int main(int arg, char *argv[])

{
  //////////////////////////////////////////////////////////
  //  Define the required structures.
  //////////////////////////////////////////////////////////

  #define NUMBEROFPROPERTIES 1
  DWORD cPropId = 0;

  MQQUEUEPROPS qprops;
  PROPVARIANT aQueuePropVar[NUMBEROFPROPERTIES];
  QUEUEPROPID aQueuePropId[NUMBEROFPROPERTIES];
  HRESULT aQueueStatus[NUMBEROFPROPERTIES];

  HRESULT hr;
  DWORD dwFormatNameBufferLength = 256;
  WCHAR wszFormatNameBuffer[256];

  //////////////////////////////////////////////////////////
  // Specify PROPID_Q_PRIV_LEVEL.
  //////////////////////////////////////////////////////////

  aQueuePropId[cPropId] = PROPID_Q_PRIV_LEVEL;  // Property ID
  aQueuePropVar[cPropId].vt = VT_UI4;           // Type indicator
  aQueuePropVar[cPropId].ulVal = MQ_PRIV_LEVEL_BODY;
  cPropId++;

  ////////////////////////////////////////////////////////
  // Add additional queue properties here. When adding
  // properties, increment cProp to
  // reflect total number of properties.
  //////////////////////////////////////////////////////////

  //////////////////////////////////////////////////////////
  // Initialize the MQQUEUEPROPS structure.
  //////////////////////////////////////////////////////////

  qprops.cProp = cPropId;           // Number of properties
  qprops.aPropID = aQueuePropId;        // Ids of properties
  qprops.aPropVar = aQueuePropVar;      // Values of properties
  qprops.aStatus = aQueueStatus;        // Error reports

  //////////////////////////////////////////////////////////
  //Get format name of queue.
  //////////////////////////////////////////////////////////

  hr = MQPathNameToFormatName(L".\\testqueue",
                              wszFormatNameBuffer,
                                  &dwFormatNameBufferLength);
  if (FAILED(hr))
  {
     fprintf(stderr, "Failed in MQPathNameToFormatName, error = 0x%x\n",hr);
     return -1;
  }

  //////////////////////////////////////////////////////////
  // Set queue property.
  //////////////////////////////////////////////////////////

  hr = MQSetQueueProperties(wszFormatNameBuffer, &qprops);
  if (FAILED(hr))
  {
     fprintf(stderr, "Failed in MQGetQueueProperties, error = 0x%x\n",hr);
     return -1;
  }

  //////////////////////////////////////////////////////////
  // Review new value. This example prints
  // out the privacy level of the queue.
  //////////////////////////////////////////////////////////

  printf("The new privacy level of the queue is ");

  if (aQueuePropVar[0].ulVal == MQ_PRIV_LEVEL_NONE)
     printf("MQ_PRIV_LEVEL_NONE. \n");
  else
  {
     if (aQueuePropVar[0].ulVal == MQ_PRIV_LEVEL_BODY)
        printf("MQ_PRIV_LEVEL_BODY. \n");
     else
        printf("MQ_PRIV_LEVEL_OPTIONAL. \n");
  }

  return 0;

}


Setting PROPID_Q_QUOTA

The queue's quota (PROPID_Q_QUOTA) is the maximum size of the queue. By default, a queue's maximum size is set to INFINITE.

Note In most cases, any application can set a queue's properties. However, if MQ_ERROR_ACCESS_DENIED is returned by MQSetQueueProperties, the queue's access control is blocking the application from setting the properties of the queue. For information about access rights, see Access Control.

To set PROPID_Q_QUOTA

  1. Define the structures needed to set queue properties.
  2. Specify PROPID_Q_QUOTA, indicating the new maximum size (in kilobytes) of the queue.
  3. Optional. Add additional properties as needed. This example only sets the maximum size of the queue.
  4. Initialize the MQQUEUEPROPS structure.
  5. Call MQPathNameToFormatName to retrieve a format name for the queue. Note the pathname of the queue indicates a local public queue whose name is "testqueue".
  6. Call MQSetQueueProperties to set the maximum size of the queue.
For a code example using | See
C++ | C/C++ Code Example


C/C++ Code Example: Setting PROPID_Q_QUOTA

The following example sets the PROPID_Q_QUOTA property for a known queue and then prints the new value to the screen.

#include <windows.h>
#include <stdio.h>
#include <mq.h>                   // Message Queuing header file

int main(int arg, char *argv[])

{
  //////////////////////////////////////////////////////////
  //  Define the required structures.
  //////////////////////////////////////////////////////////

  #define NUMBEROFPROPERTIES 1
  DWORD cPropId = 0;

  MQQUEUEPROPS qprops;
  PROPVARIANT aQueuePropVar[NUMBEROFPROPERTIES];
  QUEUEPROPID aQueuePropId[NUMBEROFPROPERTIES];
  HRESULT aQueueStatus[NUMBEROFPROPERTIES];

  HRESULT hr;
  DWORD dwFormatNameBufferLength = 256;
  WCHAR wszFormatNameBuffer[256];

  //////////////////////////////////////////////////////////
  // Specify PROPID_Q_QUOTA.
  //////////////////////////////////////////////////////////

  aQueuePropId[cPropId] = PROPID_Q_QUOTA;     // Property ID
  aQueuePropVar[cPropId].vt = VT_I4;          // Type indicator
  aQueuePropVar[cPropId].ulVal = 1000;        // New setting
  cPropId++;

  ////////////////////////////////////////////////////////
  // Add additional queue properties here. When adding
  // properties, increment cProp to
  // reflect total number of properties.
  //////////////////////////////////////////////////////////

  //////////////////////////////////////////////////////////
  // Initialize the MQQUEUEPROPS structure.
  //////////////////////////////////////////////////////////

  qprops.cProp = cPropId;           // Number of properties
  qprops.aPropID = aQueuePropId;        // Ids of properties
  qprops.aPropVar = aQueuePropVar;      // Values of properties
  qprops.aStatus = aQueueStatus;        // Error reports

  //////////////////////////////////////////////////////////
  //Get format name of queue.
  //////////////////////////////////////////////////////////

  hr = MQPathNameToFormatName(L".\\testqueue",
                              wszFormatNameBuffer,
                                  &dwFormatNameBufferLength);
  if (FAILED(hr))
  {
     fprintf(stderr, "Failed in MQPathNameToFormatName, error = 0x%x\n",hr);
     return -1;
  }

  //////////////////////////////////////////////////////////
  // Set queue property.
  //////////////////////////////////////////////////////////

  hr = MQSetQueueProperties(wszFormatNameBuffer, &qprops);
  if (FAILED(hr))
  {
     fprintf(stderr, "Failed in MQGetQueueProperties, error = 0x%x\n",hr);
     return -1;
  }

  //////////////////////////////////////////////////////////
  // Review new value. This example prints
  // out the maximum size of the queue.
  //////////////////////////////////////////////////////////

  printf("PROPID_Q_QUOTA is set to ");
  printf("%d.\n", aQueuePropVar[0].ulVal);

  return 0;

}


Setting PROPID_Q_TYPE

The queue's type (PROPID_Q_TYPE) identifies the type of service provided by the queue. Some queue types are defined by Message Queuing. However, applications can define their own queue types so that they can later locate a set of queues by the type of service the queue provides.

Note In most cases, any application can set a queue's properties. However, if MQ_ERROR_ACCESS_DENIED is returned by MQSetQueueProperties, the queue's access control is blocking the application from setting the properties of the queue. For information about access rights, see Access Control.

To set PROPID_Q_TYPE

  1. Define the structures needed to set queue properties.
  2. Specify PROPID_Q_TYPE, indicating the new type of service of the queue.
  3. Optional. Add additional properties as needed. This example only sets the queue type.
  4. Initialize the MQQUEUEPROPS structure.
  5. Call MQPathNameToFormatName to retrieve a format name for the queue. Note the pathname of the queue indicates a local public queue whose name is "testqueue".
  6. Call MQSetQueueProperties to set the service type of the queue.
For a code example using | See
C++ | C/C++ Code Example


C/C++ Code Example: Setting PROPID_Q_TYPE

The following example sets the PROPID_Q_TYPE property for a known queue and then prints the new value to the screen. This example uses the RPC function UuidToString to display the type GUID of the queue. The library and header files for this function are rpcrt4.lib and rpc.h respectively.

#include <windows.h>
#include <stdio.h>
#include <mq.h>                   // Message Queuing header file
#include <rpc.h>

int main(int arg, char *argv[])

{
  //////////////////////////////////////////////////////////
  //  Define the required structures.
  //////////////////////////////////////////////////////////

  #define NUMBEROFPROPERTIES 1
  DWORD cPropId = 0;

  MQQUEUEPROPS qprops;
  PROPVARIANT aQueuePropVar[NUMBEROFPROPERTIES];
  QUEUEPROPID aQueuePropId[NUMBEROFPROPERTIES];
  HRESULT aQueueStatus[NUMBEROFPROPERTIES];

  HRESULT hr;
  DWORD dwFormatNameBufferLength = 256;
  WCHAR wszFormatNameBuffer[256];

  //Define service type GUID;
  static CLSID guidServiceType =
  { 0xb856ab1, 0x16b6, 0x11d0, { 0x80, 0x48, 0x0, 0xa0, 0x24, 0x53, 0xc1, 0x6f } };

  //////////////////////////////////////////////////////////
  // Specify PROPID_Q_TYPE.
  //////////////////////////////////////////////////////////

  aQueuePropId[cPropId] = PROPID_Q_TYPE;     // Property ID
  aQueuePropVar[cPropId].vt = VT_CLSID;      // Type indicator
  aQueuePropVar[cPropId].puuid = &guidServiceType;
  cPropId++;

  ////////////////////////////////////////////////////////
  // Add additional queue properties here. When adding
  // properties, increment cProp to
  // reflect total number of properties.
  //////////////////////////////////////////////////////////

  //////////////////////////////////////////////////////////
  // Initialize the MQQUEUEPROPS structure.
  //////////////////////////////////////////////////////////

  qprops.cProp = cPropId;           // Number of properties
  qprops.aPropID = aQueuePropId;        // Ids of properties
  qprops.aPropVar = aQueuePropVar;      // Values of properties
  qprops.aStatus = aQueueStatus;        // Error reports

  //////////////////////////////////////////////////////////
  //Get format name of queue.
  //////////////////////////////////////////////////////////

  hr = MQPathNameToFormatName(L".\\testqueue",
                              wszFormatNameBuffer,
                                  &dwFormatNameBufferLength);
  if (FAILED(hr))
  {
     fprintf(stderr, "Failed in MQPathNameToFormatName, error = 0x%x\n",hr);
     return -1;
  }

  //////////////////////////////////////////////////////////
  // Set queue property.
  //////////////////////////////////////////////////////////

  hr = MQSetQueueProperties(wszFormatNameBuffer, &qprops);
  if (FAILED(hr))
  {
     fprintf(stderr, "Failed in MQGetQueueProperties, error = 0x%x\n",hr);
     return -1;
  }

  //////////////////////////////////////////////////////////
  // Review new value. This example prints
  // out the maximum size of the queue journal.
  //////////////////////////////////////////////////////////

  UCHAR *pszTypeGuid;
  if (UuidToString(aQueuePropVar[0].puuid, &pszTypeGuid) == RPC_S_OK)
  {
     printf("  PROPID_Q_TYPE: %s\n", pszTypeGuid);
     RpcStringFree(&pszTypeGuid);
  }

  return 0;

}


Setting Access Control Security for a Queue

The access control of a queue is first set when the queue is created (see Creating a Queue). However, Message Queuing also provides two functions for managing access control after the queue is created: MQGetQueueSecurity and MQSetQueueSecurity.

Access control determines who can perform specific operations on the queue. Operations that can be set include creating, deleting, and opening the queue; sending messages to and reading messages from the queue; getting and setting the queue's properties; and getting and setting the queue's security descriptor. These operations can be restricted to a specific user or group of users.

For information on how Message Queuing uses these settings, see Access Control.


Using Transactions

Message Queuing provides several types of transactions. The following examples include creating a transactional queue and sending messages using the different types of transactions.

For an Example of | See
Creating a transactional queue | Creating a Transactional Queue
Using an external MS DTC transaction to send a message | Sending Messages Using an MS DTC External Transaction
Using the current MTS context to send a message | Sending Messages Using an MTS Transaction
Using an internal transaction to send a message | Sending Messages Using an Internal Transaction
Using a single-message transaction to send a message | Sending a Single-message Transaction

For Information on | See
Message Queuing functions and properties used in transactions | Functions and Properties within a Transaction
The different types of transaction provided by Message Queuing | Message Queuing Transactions


Functions and Properties within a Transaction

The following table lists the elements of Message Queuing that require special attention when used within a transaction.

Elements | Description
MQCreateQueue | To create a transactional queue, PROPID_Q_TRANSACTION must be specified in the MQQUEUEPROPS structure before MQCreateQueue is called.
MQSendMessage | To send a message within a transaction, the pTransaction parameter of MQSendMessage must be set to a transaction object, a constant, or NULL.
MQReceiveMessage | To read a message within a transaction, the pTransaction parameter of MQReceiveMessage must be set to a transaction object, a constant, or NULL.
PROPID_M_PRIORITY | The priority level of all transactional messages is set to 0. Message Queuing sets the value of PROPID_M_PRIORITY to "0" regardless of what the sending application may specify.
PROPID_M_TIME_TO_BE_RECEIVED | When sending multiple messages, Message Queuing sets the time-to-be-received property of all messages to the PROPID_M_TIME_TO_BE_RECEIVED value specified by the first transactional message sent within the transaction.
PROPID_M_TIME_TO_REACH_QUEUE | When sending multiple messages, Message Queuing sets the time-to-reach-queue property of all messages to the PROPID_M_TIME_TO_REACH_QUEUE value specified by the first transactional message sent within the transaction.


Sending Messages Using an MS DTC External Transaction

To send a message using a Microsoft® Distributed Transaction Coordinator (MS DTC) external transaction, the application must work with all the resource managers that are needed to complete the transaction. In the example below, the only resource manager used is Message Queuing.

Note Each Message Queuing message can have no more than 4 MB of data.

To send a message using an MS DTC external transaction

  1. Call DtcGetTransactionManager to get a transaction dispenser.
  2. Initiate the transaction.
  3. Call MQSendMessage to send message.
  4. Commit or abort the transaction.
  5. Release the transaction object.
For a code example using | See
C++ | C/C++ Code Example


C/C++ Code Example: Sending a Message Using an MS DTC External Transaction

This example sends a single message within an MS DTC external transaction.

ITransactionDispenser   *g_pTransactionDispenser;

BOOL InitCoordinatedTransactions()
{

   //////////////////////////////
   // Get transaction dispenser.
   //////////////////////////////

   // Obtain an interface pointer from MS DTC proxy
   hr = DtcGetTransactionManager(
         NULL,                              // pszHost
         NULL,                              // pszTmName
         IID_ITransactionDispenser,         // IID of interface
         0,                                 // Reserved: must be null
         0,                                 // Reserved: must be null
         0,                                 // Reserved: must be null
         (void **)&g_pTransactionDispenser  // pointer to pointer to
                                            // requested interface
                                 );

   if (FAILED(hr))
   {
     //
     // No Connection to DTC.
     //
   return(FALSE);
   }

   return(TRUE);

}

void TransactSend(QUEUEHANDLE h, MQMSGPROPS * pmsgprops)
{

  ITransaction            *pTransaction;
  printf ("\nStarting transaction...\n\n");

  ////////////////////////////
  // Initiate a transaction.
  ///////////////////////////

  hr = g_pTransactionDispenser->BeginTransaction (
        0,                         // Must be null
        ISOLATIONLEVEL_ISOLATED,   // Isolation level
        ISOFLAG_RETAIN_DONTCARE,   // Isolation flags
        0,                         // Pointer to transaction
                                   // options object
        &pTransaction);            // Pointer to a pointer to
                                   // transaction object

      if (FAILED(hr))
      {
         Error ("BeginTransaction",hr);
      }

      // Default is to commit transaction
      BOOL fCommit = TRUE;

      /////////////////////////////////////////////
      // Call MQSendMessage to send message to
      // the receiver side within the transaction.
      /////////////////////////////////////////////
      hr = MQSendMessage(h,           // Handle to destination queue
                         pMsgprops,   // Pointer to MQMSGPROPS
                                      // structure
                         pTransaction); // Pointer to transaction
                                        // Object

      if (FAILED(hr))
      {
         printf("\nFailed in MQSendMessage(). hresult- %lxh\n", (DWORD) hr) ;
         fCommit = FALSE;     // Abort if MQSend failed
      }

      ///////////////////////////////////////////////////
      // Here the application can call other resource
      // managers (such as SQL server) and enlist their
      // actions in the transaction pTransaction.  If
      // atomicity is required, set fCommit to FALSE.

      // Commit the transaction or abort it
      if (fCommit)
      {
         printf ("Committing the transaction...   ");

         hr = pTransaction->Commit(0, 0, 0);

         if (FAILED(hr))
            printf ("Failed... Transaction aborted.\n\n");
         else
            printf ("Transaction committed successfully.\n\n");

      }
      else
      {
         printf ("Aborting the transaction...   ");

         hr = pTransaction->Abort(0, 0, 0);

         if (FAILED(hr))
            Error("Transaction Abort",hr);
         else
            printf ("Transaction aborted.\n\n");
      }

      // Release the transaction
      pTransaction->Release();

  }

void CleanupTransaction()
{
   ///////////////////////////////////////////////
   // Cleanup and release the transaction object.
   ///////////////////////////////////////////////

   g_pTransactionDispenser->Release();
}


Sending Messages Using an MTS Transaction

Message Queuing provides a way to use the current MTS object to send messages if the object is available. The MTS object can then be used to either commit to or abort the operation.

Note As in all send transactions, messages are not actually sent until the transaction commits and the destination queue of the transaction must be transactional.

When using MTS transactions, your application must call IsInTransaction to verify that the current MTS context is transactional (Message Queuing does not guarantee that the MTS object is transactional) before the message is sent.

If the current context is not transactional, your application must explicitly create its own transaction for the messages. In the following example, a single-message transaction is used if the MTS object is not transactional.

Note Several of the functions and methods noted in the following procedure are provided by MTS and COM+ (Component Services).

When using Microsoft® Windows NT® 4.0 or earlier, use the functions and methods provided by MTS.

When using Microsoft Windows® 2000 or later, use the functions and methods provided by COM+ (Component Services).

To send a message within an MTS Transaction

  1. Call GetObjectContext to get the current MTS context. Note that the GetObjectContext function is provided by MTS or COM+ (Component Services), depending on which operating system you are running.
  2. Call IsInTransaction to verify that the current context is transactional. Note that the IsInTransaction method is provided by MTS or COM+ (Component Services), depending on which operating system you are running.
  3. Set the pTransaction variable to MTS_TRANSACTION or MQ_SINGLE_MESSAGE, depending on the returned value of IsInTransaction.
  4. Call MQSendMessage to send the message.
  5. Call SetAbort or SetComplete to abort or commit to the transaction. Note that the SetAbort and SetComplete methods are provided by MTS or COM+ (Component Services), depending on which operating system you are running.
For a code example using | See
C++ | Message Queuing Function Example: Sending a Message Using an MTS Transaction


Message Queuing Function Example: Sending a Message Using an MTS Transaction

The following example shows how to get the current MTS object, check the transactional status of the current MTS context, set the pTransaction parameter, and then send a message.

Note this example uses functions and methods provided by COM+ (Component Services). This code will only work on computers running Microsoft Windows® 2000 or later

...
#include <comsvcs.h>     // Specifies COM+ methods and functions.
#include <mq.h>
....

  HRESULT hr;

  /////////////////////////////////////////////////////////////////
  // Get MTS context
  /////////////////////////////////////////////////////////////////
  IObjectContext *pContext = NULL;
  hr = GetObjectContext (&pContext);
  if (FAILED (hr))
  {
    fprintf(stderr, "Failed in GetObjectContext, error = 0x%x\n",hr);
  }

  /////////////////////////////////////////////////////////////////
  // Specify type of transaction. Use MQ_MTS_TRANSACTION if
  // current MTS context is transactional, Use MQ_SINGLE_MESSAGE
  // if current MTS context is not transactional.
  /////////////////////////////////////////////////////////////////
  ITransaction *pTransaction;
  pTransaction = MQ_MTS_TRANSACTION;
  if(!pContext->IsInTransaction())
  {
    pTransaction = MQ_SINGLE_MESSAGE;
  }

  /////////////////////////////////////////////////////////////////
  // Send message.
  /////////////////////////////////////////////////////////////////

  hr = MQSendMessage(hQueue,
                     &MsgProps,
                     pTransaction);
  if (FAILED (hr))
  {
    fprintf(stderr, "Failed in MQOSendMessage, error = 0x%x\n",hr);
     pContext->SetAbort();
  }
  else
  {
     pContext->SetComplete();
  }

  pContext->Release();

...


Sending Messages Using an Internal Transaction

Sending messages to a transactional queue within an internal transaction is very similar to sending non-transactional messages to a non-transactional queue. The only differences are including another header file (transact.h) to obtain a transaction object, calling MQBeginTransaction to initiate the transaction, and adding code to commit or abort the transaction based on the results of calling MQSendMessage.

Note Each Message Queuing message can have no more than 4 MB of data.

To send a message using an internal transaction

  1. Include the transact.h header file before mq.h.
  2. Specify the structures needed to send the message within the transaction.
  3. Specify the properties of the message to be sent.
  4. Initialize the MQMSGPROPS structure.
  5. Obtain a format name for the queue. The example code below uses MQPathNameToFormatName to generate a format name for the queue.
  6. Call MQOpenQueue to open the transactional queue with send access.
  7. Call MQBeginTransaction to initiate the internal transaction.
  8. Call MQSendMessage to send the message. Specify the transaction object pointer returned by MQBeginTransaction in the function's pTransaction parameter.
  9. Commit or abort the transaction.
  10. Release the transaction object and close the queue.
For a code example using | See
C++ | C/C++ Code Example


C/C++ Code Example: Sending a Message Using an Internal Transaction

This example sends a single message within an explicit internal transaction. It opens a known transactional queue, begins the transaction, sends the message, then commits or aborts the transaction based on the results of MQSendMessage.

#include <windows.h>
#include <stdio.h>
#include <transact.h>                                 // Provides transaction object
#include <mq.h>                                       // Message Queuing header file

int main(int arg, char *argv[])

{
  ////////////////////////////////////////////////////////////
  //  Define the required structures.
  ////////////////////////////////////////////////////////////

  #define NUMBEROFPROPERTIES 2                        // Number of properties
  DWORD cPropId = 0;                              // Property counter

  //Define MQMSGPROPS structure.
  MQMSGPROPS msgprops;
  MSGPROPID aMsgPropId[NUMBEROFPROPERTIES];
  PROPVARIANT aMsgPropVar[NUMBEROFPROPERTIES];
  HRESULT aMsgStatus[NUMBEROFPROPERTIES];

  HANDLE hQueue;                                      // Queue handle
  HRESULT hr;                                         // Define results
  DWORD dwAccess = MQ_SEND_ACCESS;                    // Access mode of queue
  DWORD dwShareMode = MQ_DENY_NONE;                   // Share Mode of queue
  ITransaction *pTransaction;                         // Pointer to transaction object

  //Transactional queue format name buffer
  DWORD dwDestFormatNameBufferLength = 256;
  WCHAR szDestFormatNameBuffer[256];

  //Body of message
  WCHAR wszMessageBody[] = L"Message sent in internal transaction.";

  /////////////////////////////////////////////////////////////////
  // Specify PROPID_M_BODY.
  /////////////////////////////////////////////////////////////////

  aMsgPropId[cPropId] = PROPID_M_BODY;
  aMsgPropVar[cPropId].vt = VT_VECTOR | VT_UI1;
  aMsgPropVar[cPropId].caub.pElems = (LPBYTE)wszMessageBody;
  aMsgPropVar[cPropId].caub.cElems = sizeof(wszMessageBody);
  cPropId++;

  /////////////////////////////////////////////////////////////////
  // Add additional message properties here. When adding
  // properties, increment NUMBEROFPROPERTIES to reflect total
  // number of message properties specified.
  /////////////////////////////////////////////////////////////////

  aMsgPropId[cPropId] = PROPID_M_LABEL;
  aMsgPropVar[cPropId].vt = VT_LPWSTR;
  aMsgPropVar[cPropId].pwszVal = L"Transaction test message";
  cPropId++;

  /////////////////////////////////////////////////////////////////
  // Initialize the MQMSGPROPS structure.
  /////////////////////////////////////////////////////////////////

  msgprops.cProp = cPropId;                       // Number of message properties
  msgprops.aPropID = aMsgPropId;                      // Ids of message properties
  msgprops.aPropVar = aMsgPropVar;                    // Values of message properties
  msgprops.aStatus  = aMsgStatus;                     // Error reports

  /////////////////////////////////////////////////////////////////
  // Convert transactional queue pathname to a format name.
  /////////////////////////////////////////////////////////////////

  hr = MQPathNameToFormatName(L".\\TransactionTestQueue",
                              szDestFormatNameBuffer,
                              &dwDestFormatNameBufferLength
                              );
  if (FAILED(hr))
  {
     fprintf(stderr, "Failed in MQPathNameToFormatName for destination queue, error = 0x%x\n",hr);
     return -1;
  }

  /////////////////////////////////////////////////////////////////
  // Open the transactional queue to send the message.
  /////////////////////////////////////////////////////////////////

  hr = MQOpenQueue(szDestFormatNameBuffer,            // Format name of queue
                   dwAccess,                          // Access mode
                   dwShareMode,                       // Share mode
                   &hQueue                            // OUT: Handle to queue
                   );

  if (FAILED(hr))
  {
     fprintf(stderr, "Failed opening destination queue, error = 0x%x\n",hr);
     return -1;
  }

  /////////////////////////////////////////////////////////////////
  // Initiate internal transaction.
  /////////////////////////////////////////////////////////////////

  hr = MQBeginTransaction (&pTransaction);

  if (FAILED(hr))
  {
     fprintf(stderr, "Failed starting transaction, error = 0x%x\n",hr);
  }

  /////////////////////////////////////////////////////////////////
  // Send message to the destination queue.
  /////////////////////////////////////////////////////////////////

  hr = MQSendMessage(hQueue,
                     &msgprops,
                     pTransaction                     // Pointer to transaction object
                     );

  if (FAILED(hr))
  {
     fprintf(stderr, "Failed sending message, error = 0x%x\n",hr);
     pTransaction->Release();
     return 0;
  }

  /////////////////////////////////////////////////////////////////
  // Commit transaction
  /////////////////////////////////////////////////////////////////

  hr = pTransaction->Commit(0,0,0);
  if (FAILED(hr))
     printf("Failed trying to commit transaction.\n");
  else
     printf("Transaction committed successfully.\n");

  /////////////////////////////////////////////////////////////////
  // Release transaction object and close the queue.
  /////////////////////////////////////////////////////////////////

  pTransaction->Release();
  hr = MQCloseQueue(hQueue);

  if (FAILED(hr))
  {
     fprintf(stderr, "Failed closing transactional queue, error = 0x%x\n",hr);
     return -1;
  }

  puts("The message is sent and the queue is closed.");
  return 0;

}


Sending a Single-message Transaction

Message Queuing provides a single-message transaction that implicitly uses the internal transaction support provided by Message Queuing. The benefits of this type of transaction include:

  • Greater speed, compared to using an external transaction coordinator.
  • Simplified application code (MQBeginTransaction does not have to be called).
  • Exactly once delivery without the need to coordinate other activities within a single transaction.

The only difference between sending a non-transactional message and using a single-message transaction is that the destination queue must be a transactional queue, and the pTransaction parameter of MQSendMessage must be set to MQ_SINGLE_MESSAGE.

Note Each Message Queuing message can have no more than 4 MB of data.

To send a single-message transaction

  1. Define the structures needed to send the message.
  2. Specify the properties of the message. This example sets the body and label of the message. Add additional message properties as needed.
  3. Initialize the MQMSGPROPS structure.
  4. Generate a format name for the transactional queue. This example calls MQPathNameToFormatName to convert a known pathname to a format name.
  5. Call MQOpenQueue to open the transactional queue with send access.
  6. Call MQSendMessage to send the message to the destination queue. Make sure the pTransaction parameter is set to MQ_SINGLE_MESSAGE.
  7. Call MQCloseQueue to close the destination queue.
For a code example using | See
C++ | C/C++ Code Example


C/C++ Code Example: Sending a Message Using a Single Message Transaction

This example sends a single message to a known transactional queue. It uses the pathname of the queue to generate a format name, opens the queue with send access, sends the message to the queue, and then closes the queue.

#include <windows.h>
#include <stdio.h>
#include <mq.h>                                       // Message Queuing header file

int main(int arg, char *argv[])

{
  ////////////////////////////////////////////////////////////
  //  Define the required structures.
  ////////////////////////////////////////////////////////////

  #define NUMBEROFPROPERTIES 2                        // Number of properties
  DWORD cPropId = 0;                              // Property counter

  //Define MQMSGPROPS structure.
  MQMSGPROPS msgprops;
  MSGPROPID aMsgPropId[NUMBEROFPROPERTIES];
  PROPVARIANT aMsgPropVar[NUMBEROFPROPERTIES];
  HRESULT aMsgStatus[NUMBEROFPROPERTIES];

  HANDLE hQueue;                                      // Queue handle
  HRESULT hr;                                         // Define results
  DWORD dwAccess = MQ_SEND_ACCESS;                    // Access mode of queue
  DWORD dwShareMode = MQ_DENY_NONE;                   // Share Mode of queue

  //Destination queue format name buffer
  DWORD dwDestFormatNameBufferLength = 256;
  WCHAR szDestFormatNameBuffer[256];

  //Body of message
  WCHAR wszMessageBody[] = L"Message sent in internal transaction.";

  /////////////////////////////////////////////////////////////////
  // Specify PROPID_M_BODY.
  /////////////////////////////////////////////////////////////////

  aMsgPropId[cPropId] = PROPID_M_BODY;
  aMsgPropVar[cPropId].vt = VT_VECTOR | VT_UI1;
  aMsgPropVar[cPropId].caub.pElems = (LPBYTE)wszMessageBody;
  aMsgPropVar[cPropId].caub.cElems = sizeof(wszMessageBody);
  cPropId++;

  ////////////////////////////////////////////////////////////////
  // Add message properties here. When adding properties,
  // increment NUMBEROFPROPERTIES to reflect total
  // number of message properties specified.
  /////////////////////////////////////////////////////////////////

  aMsgPropId[cPropId] = PROPID_M_LABEL;
  aMsgPropVar[cPropId].vt = VT_LPWSTR;
  aMsgPropVar[cPropId].pwszVal = L"Transaction test message";
  cPropId++;

  /////////////////////////////////////////////////////////////////
  // Initialize the MQMSGPROPS structure.
  /////////////////////////////////////////////////////////////////

  msgprops.cProp = cPropId;                       // Number of message properties
    msgprops.aPropID = aMsgPropId;                    // Ids of message properties
    msgprops.aPropVar = aMsgPropVar;                  // Values of message properties
    msgprops.aStatus  = aMsgStatus;                   // Error reports

  /////////////////////////////////////////////////////////////////
  //Convert destination queue pathname to a format name.
  /////////////////////////////////////////////////////////////////

  hr = MQPathNameToFormatName(L".\\TransactionTestQueue",
                              szDestFormatNameBuffer,
                              &dwDestFormatNameBufferLength
                              );
  if (FAILED(hr))
  {
     fprintf(stderr, "Failed in MQPathNameToFormatName for destination queue, error = 0x%x\n",hr);
     return -1;
  }

  /////////////////////////////////////////////////////////////////
  // Open the transactional queue to send message.
  /////////////////////////////////////////////////////////////////

  hr = MQOpenQueue(szDestFormatNameBuffer,            // Format name of queue
                   dwAccess,                          // Access mode
                   dwShareMode,                       // Share mode
                   &hQueue                            // OUT: Handle to queue
                   );
  if (FAILED(hr))
  {
     fprintf(stderr, "Failed opening destination queue, error = 0x%x\n",hr);
     return -1;
  }

  /////////////////////////////////////////////////////////////////
  // Send message to the destination queue.
  /////////////////////////////////////////////////////////////////

  hr = MQSendMessage(hQueue,
                     &msgprops,
                     MQ_SINGLE_MESSAGE
                     );

  if (FAILED(hr))
  {
     fprintf(stderr, "Failed sending message, error = 0x%x\n",hr);
     return -1;
  }

  /////////////////////////////////////////////////////////////////
  // Close the queue.
  /////////////////////////////////////////////////////////////////

  hr = MQCloseQueue(hQueue);

  if (FAILED(hr))
  {
     fprintf(stderr, "Failed closing transactional queue, error = 0x%x\n",hr);
     return -1;
  }

  puts("The message is sent and the queue is closed.");
  return 0;

}


Checking Transaction Boundaries

MSMQ 2.0 provides message properties that the receiving application can use to check the transaction boundaries between groups of the transactional messages in a queue.

To check transaction boundaries

  1. Define the structures needed to retrieve messages.
  2. Specify the properties of the message to be retrieved. (This example retrieves the message body and the three transaction boundary properties.)
  3. Initialize the MQMSGPROPS structure.
  4. Generate a format name for the queue. (This example calls MQPathNameToFormatName to convert a known pathname to a format name.)
  5. Call MQOpenQueue to open the transactional queue with receive access.
  6. Call MQReceiveMessage to retrieve the messages from the queue. For each message retrieved, its transaction boundary properties are checked to see if the boundaries of the transactions are not valid.
  7. Call MQCloseQueue to close the destination queue.
For a code example using | See
C++ | C/C++ Code Example

For information on | See
The message properties used to check transaction boundaries | Checking for Transaction Boundaries when Receiving Messages


C/C++ Code Example: Checking Transaction Boundaries

This example checks the transaction boundaries of all the transactional messages in a known queue.

#include <windows.h>
#include <stdio.h>
#include <mq.h>                              // Message Queuing header file

int main(int arg, char *argv[])
{

  #define NUMBER_OF_PROPERTIES  5        // Number of msg properties
  DWORD cPropId = 0;                     // Property counter

  //Define MQMSGPROPS structure.
  MQMSGPROPS msgprops;
  MSGPROPID aMsgPropId[NUMBER_OF_PROPERTIES];
  PROPVARIANT aMsgPropVar[NUMBER_OF_PROPERTIES];
  HRESULT aMsgStatus[NUMBER_OF_PROPERTIES];

  HANDLE hQueue;                 // Queue handle
  HRESULT hr;                    // Define results.
  DWORD dwAccess;                // Access mode of queue
  DWORD dwShareMode;             // Share mode of queue
  DWORD dwRecAction;             // Receive action

  // Destination queue format name buffer
  DWORD dwDestFormatNameBufferLength = 256;
  WCHAR wszDestFormatNameBuffer[256];

  // Message body and label buffer
  DWORD dwBodyBufferSize = 1024;
  UCHAR *pucBodyBuffer = (UCHAR *)malloc(dwBodyBufferSize);

  // Transaction ID buffer
  OBJECTID xid;

  /////////////////////////////////////////////////////////////
  // Specify message body.
  /////////////////////////////////////////////////////////////

  aMsgPropId[cPropId] = PROPID_M_BODY_SIZE;       // 0: body size
  aMsgPropVar[cPropId].vt = VT_UI4;
  cPropId++;

  aMsgPropId[cPropId] = PROPID_M_BODY;            // 1: body
  aMsgPropVar[cPropId].vt = VT_VECTOR|VT_UI1;
  aMsgPropVar[cPropId].caub.pElems = (UCHAR*)pucBodyBuffer;
  aMsgPropVar[cPropId].caub.cElems = dwBodyBufferSize;
  cPropId++;

  aMsgPropId[cPropId] = PROPID_M_FIRST_IN_XACT;   // 2: First
  aMsgPropVar[cPropId].vt = VT_UI1;
  cPropId++;

  aMsgPropId[cPropId] = PROPID_M_LAST_IN_XACT;    // 3: Last
  aMsgPropVar[cPropId].vt = VT_UI1;
  cPropId++;

  aMsgPropId[cPropId] = PROPID_M_XACTID;      // 4: Xact Index
  aMsgPropVar[cPropId].vt = VT_UI1 | VT_VECTOR;
  aMsgPropVar[cPropId].caub.pElems = (PUCHAR)&xid;
  aMsgPropVar[cPropId].caub.cElems = sizeof(OBJECTID);
  cPropId++;

  /////////////////////////////////////////////////////////////
  // Initialize the MQMSGPROPS structure.
  /////////////////////////////////////////////////////////////

  msgprops.cProp = cPropId;          // Number of message properties
  msgprops.aPropID = aMsgPropId;     // Ids of message properties
  msgprops.aPropVar = aMsgPropVar;   // Values of message properties
  msgprops.aStatus  = aMsgStatus;    // Error reports

  /////////////////////////////////////////////////////////////////
  //Convert destination queue pathname to a format name.
  /////////////////////////////////////////////////////////////////

  hr = MQPathNameToFormatName(L".\\TestQueue",
                              wszDestFormatNameBuffer,
                              &dwDestFormatNameBufferLength);
  if (FAILED(hr))
  {
     fprintf(stderr, "Failed in MQPathNameToFormatName, error = 0x%x\n",hr);
     return -1;
  }

  /////////////////////////////////////////////////////////////////
  // Open the destination queue to retrieve the message.
  /////////////////////////////////////////////////////////////////

  dwAccess = MQ_RECEIVE_ACCESS;             // Access mode of queue
  dwShareMode = MQ_DENY_RECEIVE_SHARE;      // Share mode of queue

  hr = MQOpenQueue(wszDestFormatNameBuffer, // Format name of queue
                   dwAccess,                // Access mode
                   dwShareMode,             // Share mode
                   &hQueue                  // OUT: Handle to queue
                   );
  if (FAILED(hr))
  {
     fprintf(stderr, "Failed opening destination queue, error = 0x%x\n",hr);
     return -1;
  }

  // We assume that all the messages come from the same machine
  GUID guidMachine;

  // These variables will control the processing
  OBJECTID oidCurrentXID;
  ZeroMemory(&oidCurrentXID, sizeof(OBJECTID));
  BOOL  fInsideXact = FALSE;

  /////////////////////////////////////////////////////////////////
  // Test transaction boundaries and process messages if no      //
  // messages are lost.                                          //
  /////////////////////////////////////////////////////////////////

  while(1)
  {
     // Retrieve message
     dwRecAction = MQ_ACTION_RECEIVE;        // Receive action

     hr = MQReceiveMessage(hQueue,           // Queue handle
                           0,                // Max time (msec)
                           dwRecAction,      // Receive action
                           &msgprops,        // Msg property structure
                           NULL,             // No overlapped structure
                           NULL,             // No callback function
                           NULL,             // No cursor
                           NULL              // No transaction
                           );

     if (FAILED(hr))
     {
         if ( hr != MQ_ERROR_IO_TIMEOUT)
         {
            fprintf(stderr, "Failed retrieving message, error = 0x%x\n",hr);
         }

         if (fInsideXact)
         {
            fprintf(stderr, "***Absent last message(s) in transaction %x \n", oidCurrentXID.Uniquifier);
         }

         break;
     }

     // Verify the case of first message in a transaction.
     if (aMsgPropVar[2].bVal == MQMSG_FIRST_IN_XACT)
     {
        if (!fInsideXact)
        {
           // OK - starting new transaction
           fInsideXact = TRUE;
           oidCurrentXID = xid;
           fprintf(stderr, "First message from transaction %x\n", xid.Uniquifier);
        }
        else
        {
           // Error condition: starting new transaction before
           // previous transaction has been closed
           fprintf(stderr, "***Absent last message(s) of the transaction %x \n", oidCurrentXID.Uniquifier);
        }
      }

     // Verify the case of last message in a transaction.
     if (aMsgPropVar[3].bVal == MQMSG_LAST_IN_XACT)
     {
        if (fInsideXact && xid.Uniquifier==oidCurrentXID.Uniquifier)
        {
           // OK - we are inside of the same transaction
           fInsideXact = FALSE;
           fprintf(stderr, "Last message from transaction %x\n", xid.Uniquifier);

           // At this point we have a full data of one
           // transaction. Process this information as
           // needed by your application.
        }
        else
        {
           // Error condition: we've got last message of transaction X
           // while inside of transaction Y
           if (xid.Uniquifier!=oidCurrentXID.Uniquifier && oidCurrentXID.Uniquifier!=0)
           {
               fprintf(stderr, "***Absent last message(s)of the transaction %x\n", oidCurrentXID.Uniquifier);
           }
           if (!fInsideXact)
           {
               fprintf(stderr, "***Absent first message(s) of the transaction %x \n", xid.Uniquifier);
           }
        }
      }

     // Verify the case if inside message of a current transaction
     if (aMsgPropVar[2].bVal == MQMSG_NOT_FIRST_IN_XACT &&
         aMsgPropVar[3].bVal == MQMSG_NOT_LAST_IN_XACT)
     {
        if (xid.Uniquifier==oidCurrentXID.Uniquifier)
        {
           // OK - just inner message
           fprintf(stderr, "Message from transaction %x\n", xid.Uniquifier);
        }
        else
        {
           // Error condition: we've got inner message of
           // transaction X while inside of transaction Y
           if (oidCurrentXID.Uniquifier!=0)
           {
               fprintf(stderr, "***Absent last message(s)of the transaction %x\n", oidCurrentXID.Uniquifier);
           }
           if (!fInsideXact)
           {
               fprintf(stderr, "***Absent first message(s) of the transaction %x \n", xid.Uniquifier);
           }

           oidCurrentXID = xid;
           fInsideXact = TRUE;
        }
     }
  }

  //////////////////////////////////////////////////////////////
  // Close queue.
  //////////////////////////////////////////////////////////////

  hr = MQCloseQueue(hQueue);

  return 0;

}


Verifying Workgroup Installation

You can verify that the computer running Message Queuing is part of a workgroup by testing to see if Message Queuing is using the directory service.

This example looks at the directory service – enabled property of the local Message Queuing installation to check if it is using the directory service. If the directory service is not being used, the local computer must be a member of a workgroup.

To verify that the directory service is enabled.

  1. Define the structures needed to retrieve private computer properties.
  2. Specify PROPID_PC_DS_ENABLED in the MQPRIVATEPROPS structure.
  3. Initialize the MQPRIVATEPROPS structure.
  4. Call MQGetPrivateComputerInformation to retrieve the directory service – enabled property.


C/C++ Code Example: Verifying Workgroup Installation

This example checks the PROPID_PC_DS_ENABLED property of the local computer to verify that the computer is part of a workgroup.

#include <windows.h>
#include <stdio.h>
#include <mq.h>                              // Message Queuing header file

int main(int arg, char *argv[])

{

  #define NUMBER_OF_PROPERTIES  1        // Number of QM properties
  DWORD cPropId = 0;                     // Property counter

  /////////////////////////////////////////////////////////////
  // Define private property structure.
  /////////////////////////////////////////////////////////////

  MQPRIVATEPROPS qmprops;
  QMPROPID aQMPropId[NUMBER_OF_PROPERTIES];
  PROPVARIANT aQMPropVar[NUMBER_OF_PROPERTIES];
  HRESULT aQMStatus[NUMBER_OF_PROPERTIES];

  HRESULT hr;                    // Define results.

  /////////////////////////////////////////////////////////////
  // Specify private properties.
  /////////////////////////////////////////////////////////////

  // DS enabled property (0)
  aQMPropId[cPropId] = PROPID_PC_DS_ENABLED;
  aQMPropVar[cPropId].vt = VT_BOOL;
  cPropId++;

  /////////////////////////////////////////////////////////////
  // Initialize the MQMSGPROPS structure.
  /////////////////////////////////////////////////////////////

  qmprops.cProp = cPropId;          // Number of message properties
  qmprops.aPropID = aQMPropId;     // IDs of message properties
  qmprops.aPropVar = aQMPropVar;   // Values of message properties
  qmprops.aStatus  = aQMStatus;     // Error reports

  /////////////////////////////////////////////////////////////
  // Call MQGetPrivateComputerInformation to retrieve the
  // directory-service-enabled property.
  /////////////////////////////////////////////////////////////

  hr=MQGetPrivateComputerInformation(NULL, &qmprops);

  if(qmprops.aPropVar[0].boolVal)
    printf ("Message Queuing is using the directory service.\n");

  if(!qmprops.aPropVar[0].boolVal)
    printf ("Message Queuing is not using the directory service.\n");

  return 0;

}


Using the COM Components

This section contains several topics on programming considerations, and complete examples of the basic tasks your application may need to perform.

Note For information on a specific Message Queuing COM component method, property, or event, see the specific reference page in the Message Queuing Reference.

For programming considerations when | See
Programming in Visual C++ and C | Using Message Queuing COM Components in Visual C++ and C
Programming in Visual Basic | Using Message Queuing COM Components in Microsoft Visual Basic
Programming in server and client-side scripting languages | Using Message Queuing COM Components in Server and Client-side Scripting
Programming in Visual J++ | Using Message Queuing COM Components in Microsoft Visual J++

For an example of | See
Creating queues | Creating a Queue (COM)
Locating public queues | Locating a Public Queue (COM)
Opening queues | Opening a Queue (COM)
Deleting queues | Deleting a Queue (COM)
Sending messages to a queue | Sending Messages to a Queue (COM)
Reading messages from a queue | Reading Messages in a Queue (COM)
Purging messages from a queue | Purging Messages in a Queue (COM)
Requesting target and source journaling | Requesting Journaling (COM)
Filtering messages using message properties | Filtering Messages (COM)
Retrieving the properties of an existing queue | Retrieving Queue Properties (COM)
Setting the properties of an existing queue | Setting Queue Properties (COM)
Sending an retrieving messages within transactions | Using Transactions (COM)


Programming Considerations when using COM Components

Message Queuing provides a set of COM objects for developing Message Queuing applications using any COM development tool, including Microsoft® Visual Basic® (version 4.0 or later), Microsoft Visual C++, C/C++, VBScript, and Java. The following topics describe information that you may find helpful when programming in one of these languages.

For information on | See
Programming in Visual C++ and C | Using Message Queuing COM Components in Visual C++ and C
Programming in Visual Basic | Using Message Queuing COM Components in Microsoft Visual Basic
Programming in server and client-side scripting languages | Using Message Queuing COM Components in Server and Client-side Scripting
Programming in Visual J++ | Using Message Queuing COM Components in Microsoft Visual J++


Using Message Queuing COM Components in Visual C++ and C

Message Queuing COM objects can be invoked using Visual C++ and C/C++. Although both languages can be used, the examples in the Message Queuing SDK use Visual C++ because of its Visual Basic like syntax.

Note Visual C++ code uses #import to reference mqoa.dll, providing an easy-to-use syntax that is similar to the syntax provided by Visual Basic. This syntax provides:

  • HRESULT to exception mapping. A VC5/COM application can use try and catch to handle errors instead of testing for return values.
  • Support for optional parameters (not available in C/C++ implementations).
  • Reference counting and Query Interface support so there is no need for explicit AddRef/QueryInterface.

Here are two code fragments that illustrate some of the differences between Visual C++ and C/C++ code. Both fragments create a public queue.

Visual C++

#import "mqoa.dll;

   try {
       IMSMQQueueInfoPtr pqinfo ("MSMQ.MSMQQueueInfo");
       pqinfo->PutPathName (L".\\queuename");
       //
       // Create non-transactional, non-world-readable queue.
       //
       pqinfo->Create();
       }
   catch (_com_error &e) {
        // UNDONE: handle error.
       }

Using C/C++

    IMSMQQueueInfo *pqinfo;

    HRESULT hresult;
    VARIANT varIsTransactional;
    VARIANT varIsWorldReadable;
    //
    // Create MSMQQueueInfo object
    //
    hresult = CoCreateInstance(
                   CLSID_MSMQQueueInfo,
                   NULL,                    // punkOuter
                   CLSCTX_SERVER,
                   IID_IMSMQQueueInfo,
                   (LPVOID *)&pqinfo
                   );
    if (SUCCEEDED(hresult)) {
      // Set the PathName.
      pqinfo->put_PathName(L".\queuename");
      //
      // specify if transactional
      //
      VariantInit(&varIsTransactional);
      varIsTransactional.vt = VT_BOOL;
      varIsTransactional.boolVal = MQ_TRANSACTIONAL_NONE;
      VariantInit(&varIsWorldReadable);
      varIsWorldReadable.vt = VT_BOOL;
      varIsWorldReadable.boolVal = FALSE;
      //
      // create the queue
      //
      hresult = pqinfo->Create(&varIsTransactional,
                               &varIsWorldReadable);
      //
      // UNDONE: need to handle failure...
      //
    }


Using Message Queuing COM Components in Microsoft Visual Basic

The following programming tips are provided for those new to writing Message Queuing or Microsoft® Visual Basic® applications. They highlight several issues that may make writing your Message Queuing application easier.

Declaring Objects
When declaring object variables, the New keyword can be added to the Dim statement to enable implicit creation of the object. This means that each time the variable is referenced, a new instance of the object is implicitly created if the current value of the variable is Nothing.

In contrast, when the New keyword is not used, an instance of the object is only created when the Set command is called or some other mechanism (such as a call to a method that returns an object reference) is used to obtain an object instance. The Set command can be used as well for variables that were declared with the New keyword.

The example below shows when the New keyword should be used and when it should not be.

Dim qDest As MSMQQueue                'Set command needed.
Dim msgSent As New MSMQMessage
Dim msgDest As MSMQMessage            'Peek method returns
                                      'MSMQMessage instance.

Set qDest = qinfoDest.Open(MQ_SEND_ACCESS, MQ_DENY_NONE)
msgSent.Send qDest
Set qDest = qinfoDest.Open(MQ_PEEK_ACCESS, MQ_DENY_NONE)
Set msgDest = qDest.Peek(ReceiveTimeout:=100)
Calling Functions and Subroutines Using the Call Keyword
When functions and subroutines are called, parentheses are not always required.

When functions or subroutines are called explicitly using the Call keyword, parentheses are required whenever there is one or more arguments. In this case the return value of a function is discarded. For example.

Call Foo(x)
Call Foo(1, 2)

When a function is called and the return value is used, parentheses are always required whenever there is one or more arguments.

y = Foo(x, z)              ' Result of Foo used to assign to y.
Call Bar(Foo(1))           ' Result of Foo used as argument to Bar.
Calling Functions and Subroutines Without Using the Call Keyword
When a function or subroutine is called without using the Call keyword, its return value is ignored.

Parentheses cannot be used for functions or subroutines that take more than one argument.

If parentheses are used for functions or subroutines that take a single argument, that argument is effectively passed 'by value' since the argument is in effect an expression whose result is returned in a temporary variable.

For example:

Foo x       'Parentheses cannot be used: x is passed by reference.
Foo (x)     'x is effectively passed by value.
Use Named Arguments
Use named arguments to make your code easier to read. Using non-named arguments forces the reader to remember the argument's name and the order of the arguments. For example, the following two lines of code are functionally identical, yet the first is much easier to understand:
Create IsWorldReadable:=True, IsTransactional:=False
Create False, True
Variants Containing Arrays
A Variant containing an array can be used like an array. For example, ubound(msg.Id) or msg.CorrelationId(10).
Use Early-Binding
When declaring object's specify the object class in the Dim statement (early-binding). Using early-binding whenever possible will make your application run faster. For example, the following examples are both functionally equal, yet the first example executes faster due to early-binding of the object.
dim qinfo as MSMQQueueInfo
set qinfo = New MSMQQueueInfo
qinfo.PathName = ".\PRIVATE$\CreateTest"
qinfo.Create

dim qinfo as Object
set qinfo = New MSMQQueueInfo
qinfo.PathName = ".\PRIVATE$\CreateTest"
qinfo.Create
Using the Microsoft® Visual Basic® 5.0
The Microsoft® Visual Basic® 5.0 debugger can be used on Message Queuing application executable and DLL files generated by Visual Basic 5.0. You can set breakpoints as well as disassemble and see the generated VBA code and look at local variables.


Using Message Queuing COM Components in Server and Client-Side Scripting

Message Queuing provides COM components that can be used to create Web-based applications using server and client-side scripting.

Server-Side Scripting

Message Queuing COM components can be used in Active Server Pages (ASP) scripts using VBScript. When using this type of scripting, Message Queuing must be installed on the server where the ASP pages are stored, not on the client machines where the browser is running.

The following programming considerations should be kept in mind when developing your application

  • Only local queues can be created when using ASP pages. Queues cannot be created on a remote computer.
  • Your script must be in a text file that has an .asp suffix (for example, mq.asp). It can be stored in the InetPub\Scripts folder on your web server or any other folder that has execute script privileges.

For more information about using server-side scripting with ASP, see http://msdn.microsoft.com/workshop/server/asp/aspover.asp.

Client-Side Scripting

Message Queuing COM components can be used in any HTML page using the <OBJECT> tag in VBScript. When using this type of scripting, Message Queuing must be installed on an all client machines.

For more information on client-side scripting, see the Internet Explorer/VBScript documentation.


Using Message Queuing COM Components in Microsoft Visual J++

Message Queuing COM components can be used to create Java applications, DLLs, controls, and applets. Note that Java COM components are most useful when installed on a server (such as an MTS component) where only the server needs to have Message Queuing. When deployed on a client computers, each client needs to run Message Queuing.

Note When you use this type of scripting to create applets, you must have Message Queuing installed on an all machines running the browser. To properly download and run a Java applet, you will need to create and sign a CAB file, including any supporting classes, on the client machine.

Using the Message Queuing COM components is similar to using any ActiveX® object in the Microsoft® Visual J++® development environment. This similarity includes specifying the object library you want to use and adding the appropriate import statements at the top of your source file.

Object Libraries

Message Queuing provides the following object libraries:

  • Microsoft Message Queue 1.0 Object Library: Provides the basic message queuing functionality of MSMQ 1.0. Applications and applets designed with this object library can work on computers running MSMQ 1.0 or MSMQ 2.0.
  • Microsoft Message Queue 2.0 Object Library: Provides the basic message queuing functionality of MSMQ 2.0. Applications and applets designed with this object library may not work on computers running MSMQ 1.0.
  • When using MSMQ 2.0 use the latest JActiveX.exe file from the Microsoft SDK for Java 3.2 (manually copy over any older versions of the file that are in your Visual J++ directory).
  • Microsoft Message Queue Mail Object Library: Provides MSMQ Exchange Connector functionality.

Note When using Microsoft Visual J++ 6.0, select ADD COM Wrappers command from the Project menu to display the list of registered libraries. Select one of the libraries listed above and click OK.

Import Statements

At the top of your application, add the following two import statements.

import mqoa.*;
import com.ms.com.Variant;


Creating a Queue (COM)

Queues are created by calling MSMQQueueInfo.Create. These include public queues registered in the directory service, private queues registered on the local computer.

Before creating a queue, you must decide where the messages of the queue will be stored, where the queue will be registered, and what the name for the queue will be. All this information is included as part of the MSMQQueueInfo.PathName property of the queue. MSMQQueueInfo.PathName is the only required property needed to create a queue.

Additional queue properties, such as the label of the queue, the privacy level of the queue, and if the queue is transactional can also be set when creating the queue. For a list of all the queue properties, see MSMQQueueInfo.

Once the queue is created, the MSMQQueueInfo object can be used to open the queue for sending or receiving messages.

For an example of | See
Creating public queues | Creating a Public Queue (COM)
Creating private queues | Creating a Private Queue (COM)
Creating transactional queues | Creating a Transactional Queue (COM)
Creating a queue that accepts only private (encrypted) messages | Creating a Private Message Only Queue (COM)


Creating a Public Queue (COM)

To create a public queue, you must provide the pathname for the queue, plus any additional queue properties needed by your application.

The pathname of a public queue contains the name of the computer where the messages sent to the queue will be stored and the name of the queue.

When providing the name of the computer, you can use the NetBIOS machine name, full DNS machine name, or a period(".") to designate the local computer.

When providing a name for the queue, you can use any character except "\", ";" and "$" as the last character of the name (Message Queuing reserves names ending with "$", for example, the token "PRIVATE$" is used to specify a private queue).The name of the queue is case-insensitive (for example, "MyQueue" and "myQueue" are treated as the same name) and can be up to 124 Unicode characters.

Note Queue names greater than 64 Unicode characters may cause a slight reduction in performance, plus they are not easily displayed in Active Directory.

To create a public queue

  1. Declare the MSMQQueueInfo variable for the queue.
  2. Create a new MSMQQueueInfo object and assign it to the variable.
  3. Specify the pathname of the queue. In these examples, "." is used to indicate the local computer.

    Note For Message Queuing servers and independent clients, the local machine is the local computer. However, for Message Queuing–dependent clients, the local machine is the client's Message Queuing server.

  4. Optional. Add any additional queue properties you need. The following examples also specify the label of the queue.
  5. Call MSMQQueueInfo.Create to create the queue.
For a code example using | See
Microsoft Visual Basic | Visual Basic Code Example
C++ COM | C++ COM Code Example
Microsoft VBScript using an ASP file | VBScript Code Example
Microsoft Visual J++ | Visual J++ Code Example


Visual Basic Code Example: Creating a Public Queue

The following example creates a public queue on the local machine. If a queue with the same pathname already exists, an error message is displayed and no queue is created.

To try this example in Microsoft® Visual Basic® (version 5.0), paste the code into the Declaration section of a form, press F5, and click on the form.

Dim qinfo As MSMQQueueInfo

Private Sub Form_Click()

  ' Create a new QueueInfo object.
  Set qinfo = New MSMQQueueInfo

  ' Set the pathname of the queue.
  qinfo.PathName = ".\TestQueue"

  ' Set additional queue properties
  qinfo.Label = "Test Queue"

  ' Create the queue.
  On Error GoTo ErrorHandler
  qinfo.Create
  MsgBox "Queue is created."

  Exit Sub

ErrorHandler:

  Select Case Err.Number
    Case Is = MQ_ERROR_QUEUE_EXISTS
      MsgBox "A queue with the same pathname is already registered."
    Case Else
      MsgBox "Error creating queue!" + Chr(13) + Chr(13) + _
             "Error: " + Hex(ErrorCode)
  End Select

End Sub


C++ COM Code Example: Creating a Public Queue

The following example creates a public queue on the local machine. If a queue with the same pathname already exists, an error message is displayed, and no queue is created.

#include <windows.h>
#include <stdio.h>      // for printf
#import "mqoa.dll" no_namespace

int main()
{
  ///////////////////////////////////////////////////////////
  // Initialize OLE.
  ///////////////////////////////////////////////////////////
  OleInitialize(NULL);

  ///////////////////////////////////////////////////////////
  // Create public queue.
  ///////////////////////////////////////////////////////////
  try
  {
    IMSMQQueueInfoPtr qinfo("MSMQ.MSMQQueueInfo");

    qinfo->PathName = ".\\TestQueue";
    qinfo->Label = "Test Queue";
    try
    {
      qinfo->Create();
    }
    catch (_com_error comerr)
    {
      HRESULT hr = comerr.Error();
      if (hr == MQ_ERROR_QUEUE_EXISTS)
      {
        printf("Queue already exists.\n");
        return -1;
      }
      else
      {
        throw comerr;
      }
    }

    printf("Public queue created.\n");
    return 0;
  }
  catch (_com_error comerr)
  {
    HRESULT hr = comerr.Error();
    printf("unexpected error: %x\n", hr);
    exit (-1);
  }

}


VBScript Code Example: Creating a Public Queue

The following example creates a public queue on the server machine using Active Server Pages and VBSript.

Note When using ASP pages, you can create only local queues. You cannot create queues on a remote computer.

To run this example, paste the following code into a text file that has an .asp suffix (for example, mq.asp), and then place the file in the InetPub\Scripts folder on your web server. (If you use another folder, make sure that folder has execute script privileges.) You can then run this script from your Internet browser by referring to the address: http://<webservername>/scripts.mq.asp.

<HTML>
<BODY>
Create an MSMQ public queue on the web server
<%
    set iq = Server.CreateObject ("MSMQ.MSMQQueueInfo")
    iq.PathName = ".\TestQueue"
    iq.Label = "Test Queue"

    iq.Create
%>
</BODY>
</HTML>


Visual J++ Code Example: Creating a Public Queue

The following example creates a public queue on the local computer.

This example uses the Microsoft Message Queue 2.0 Object Library to create COM wrappers for the Message Queuing COM components. It was created with Microsoft Visual J++ 6.0, using the Java SDK 3.2 provided by Microsoft Visual Studio 6.0 (service pack 3).

import com.ms.com.Variant;
import mqoa. *;
public class Class1
{
  public static void main (String[] args)
  {
     Variant isTransactional;
     Variant isWorldReadable;
     try
     {
       IMSMQQueueInfo qinfo = (IMSMQQueueInfo) new MSMQQueueInfo();
       qinfo.setPathName(".\\javaTestQueue");
       isTransactional = new Variant();
       isTransactional.putBoolean(false);
       isWorldReadable = new Variant();
       isWorldReadable.putBoolean(false);
       qinfo.Create (isWorldReadable, isTransactional);
     }
     catch (Exception e)
     {
        System.out.println("Error: " + e.getMessage());
     }

  }
}


Creating a Private Queue (COM)

To create a private queue, you must provide the pathname for the queue, plus any additional queue properties needed by your application.

The pathname for a private queue contains the name of the local computer where the messages sent to the queue will be stored, the "PRIVATE$" keyword, and the name of the queue.

When providing the name of local computer, you can use the NetBIOS machine name, full DNS machine name, or a period (".") to designate the computer.

When providing a name for the queue, you can use any character except "\", ";" and "$" as the last character of the name (Message Queuing reserves names ending with "$", for example, the token "PRIVATE$" is used to specify a private queue).The name of the queue is case-insensitive (for example, "MyQueue" and "myQueue" are treated as the same name)and can be up to 124 Unicode characters.

Note Queue names greater than 64 Unicode characters may cause a slight reduction in performance, plus they are not easily displayed in Active Directory.

To create a private queue

  1. Declare the MSMQQueueInfo variable for the queue.
  2. Create a new MSMQQueueInfo object and assign it to the variable.
  3. Specify the pathname of the queue. In these examples, "." is used to indicate the local computer.

    Note For Message Queuing servers and independent clients, the local machine is the local computer. However, for Message Queuing–dependent clients, the local machine is the client's Message Queuing server.

  4. Optional. Add any additional queue properties that might be needed. The following examples also specify the label of the queue.
  5. Call MSMQQueueInfo.Create to create the queue.
For a code example using | See
Microsoft Visual Basic | Visual Basic Code Example
C++ COM | C++ COM Code Example
Microsoft VBScript using an ASP file | VBScript Code Example


Visual Basic Code Example: Creating a Private Queue

The following example creates a private queue. If a queue with the same pathname already exists, an error message is displayed, and no queue is created.

To try this example in Microsoft® Visual Basic® (version 5.0), paste the code into the Declaration section of a form, press F5, and click on the form.

Dim qinfo As MSMQQueueInfo

Private Sub Form_Click()

  ' Create a new QueueInfo object.
  Set qinfo = New MSMQQueueInfo

  ' Set the pathname of the queue.
  qinfo.PathName = ".\PRIVATE$\TestQueue"

  ' Set additional queue properties
  qinfo.Label = "Test Queue"

  ' Create the queue.
  On Error GoTo ErrorHandler
  qinfo.Create
  MsgBox "Queue is created."

  Exit Sub

ErrorHandler:

  Select Case Err.Number
    Case Is = MQ_ERROR_QUEUE_EXISTS
      MsgBox "A queue with the same pathname is already registered."
    Case Else
      MsgBox "Error creating queue!" + Chr(13) + Chr(13) + _
             "Error: " + Hex(ErrorCode)
  End Select

End Sub


C++ COM Code Example: Creating a Private Queue

The following example creates a private queue on the local machine. If a queue with the same pathname already exists, an error message is displayed and no queue is created.

#include <windows.h>
#include <stdio.h>      // for printf
#import "mqoa.dll" no_namespace

int main()
{
  ///////////////////////////////////////////////////////////
  // Initialize OLE.
  ///////////////////////////////////////////////////////////
  OleInitialize(NULL);

  ///////////////////////////////////////////////////////////
  // Create the public queue.
  ///////////////////////////////////////////////////////////
  try
  {
    IMSMQQueueInfoPtr qinfo("MSMQ.MSMQQueueInfo");

    qinfo->PathName = ".\\PRIVATE$\\TestQueue";
    qinfo->Label = "Test Queue";
    try
    {
      qinfo->Create();
    }
    catch (_com_error comerr)
    {
      HRESULT hr = comerr.Error();
      if (hr == MQ_ERROR_QUEUE_EXISTS)
      {
        printf("Queue already exists.\n");
        return -1;
      }
      else
      {
        throw comerr;
      }
    }

  printf("Private queue created.\n");
  return 0;
  }
  catch (_com_error comerr)
  {
    HRESULT hr = comerr.Error();
    printf("unexpected error: %x\n", hr);
    exit (-1);
  }

}


VBScript Code Example: Creating a Private Queue

The following example creates a private queue on the server machine using Active Server Pages and VBSript.

Note When using ASP pages, you can create only local queues. You cannot create queues on a remote computer.

To run this example, paste the following code into a text file that has an .asp suffix (for example, mq.asp), and then place the file in the InetPub\Scripts folder on your web server. (If you use another folder, make sure that folder has execute script privileges.) You can then run this script from your Internet browser by referring to the address: http://<webservername>/scripts.mq.asp.

<HTML>
<BODY>
Create an Message Queuing private queue on the web server
<%
    set iq = Server.CreateObject ("MSMQ.MSMQQueueInfo")
    iq.PathName = ".\PRIVATE$\TestQueue"
    iq.Label = "Test Queue"

    iq.Create
%>
</BODY>
</HTML>


Creating a Transactional Queue (COM)

To create a transactional queue, you must set the IsTransactional parameter of MSMQQueueInfo.Create to True.

This example creates a transactional public queue. You can also use this code to create a transactional private queue by adding the PRIVATE$ keyword to the pathname of the queue.

To create a transactional queue

  1. Declare the MSMQQueueInfo variable for the queue.
  2. Create a new MSMQQueueInfo object and assign it to the variable.
  3. Specify the pathname of the queue. In these examples, "." is used to indicate the local computer.

    Note For Message Queuing servers and independent clients, the local machine is the local computer. However, for Message Queuing–dependent clients, the local machine is the client's Message Queuing server.

  4. Optional. Add any additional queue properties that might be needed.
  5. Call MSMQQueueInfo.Create to create the transactional queue. Make sure the IsTransactional parameter is set to True.
For a code example using | See
Microsoft Visual Basic | Visual Basic Code Example
C++ COM | C++ COM Code Example
Microsoft VBScript using an ASP file | VBScript Code Example


Visual Basic Code Example: Creating a Transactional Queue

The following example creates a transactional public queue. If a queue with the same pathname already exists, an error message is displayed and no queue is created.

To try this example in Microsoft® Visual Basic® (version 5.0), paste the code into the Declaration section of a form, press F5, and click on the form.

Dim qinfo As MSMQQueueInfo

Private Sub Form_Click()

  ' Create a new QueueInfo object.
  Set qinfo = New MSMQQueueInfo

  ' Set the pathname of the queue.
  qinfo.PathName = ".\TestQueue"

  ' Set additional queue properties
  qinfo.Label = "Test Queue"

  ' Create the queue.
  On Error GoTo ErrorHandler
  qinfo.Create IsTransactional:=True
  MsgBox "Queue is created."

  Exit Sub

ErrorHandler:

  Select Case Err.Number
    Case Is = MQ_ERROR_QUEUE_EXISTS
      MsgBox "A queue with the same pathname is already registered."
    Case Else
      MsgBox "Error creating queue!" + Chr(13) + Chr(13) + _
             "Error: " + Hex(ErrorCode)
  End Select

End Sub


C++ COM Code Example: Creating a Transactional Queue

The following example creates a transactional public queue on the local machine. If a queue with the same pathname already exists, an error message is displayed and no queue is created.

#include <windows.h>
#include <stdio.h>      // for printf
#import "mqoa.dll" no_namespace

int main()
{
  ///////////////////////////////////////////////////////////
  // Initialize OLE.
  ///////////////////////////////////////////////////////////
  OleInitialize(NULL);
  _variant_t varXact((bool)TRUE);                     // Needed to set IsTransactional parameter

  ///////////////////////////////////////////////////////////
  // Create transactional queue.
  ///////////////////////////////////////////////////////////
  try
  {
    IMSMQQueueInfoPtr qinfo("MSMQ.MSMQQueueInfo");

    qinfo->PathName = ".\\TransactionTestQueue";

  try
  {
    qinfo->Create(&varXact);
    }
    catch (_com_error comerr)
    {
      HRESULT hr = comerr.Error();
      if (hr == MQ_ERROR_QUEUE_EXISTS)
      {
          printf("Queue already exists.\n");
          return -1;
      }
      else
      {
        throw comerr;
      }
    }
    printf("Public transactional queue created.\n");
    return 0;
  }
  catch (_com_error comerr)
  {
    HRESULT hr = comerr.Error();
    printf("unexpected error: %x\n", hr);
    exit (-1);
  }
}


VBScript Code Example: Creating a Transactional Queue

The following example creates a transactional public queue on the server machine using Active Server Pages and VBSript.

Note When using ASP pages, you can create only local queues. You cannot create queues on a remote computer.

To run this example, paste the following code into a text file that has an .asp suffix (for example, mq.asp), and then place the file in the InetPub\Scripts folder on your web server. (If you use another folder, make sure that folder has execute script privileges.) You can then run this script from your Internet browser by referring to the address: http://<webservername>/scripts.mq.asp.

<HTML>
<BODY>
Create an MSMQ public queue on the web server
<%
    set iq = Server.CreateObject ("MSMQ.MSMQQueueInfo")
    iq.PathName = ".\TransactionalTestQueue"
    iq.Label = "Test Queue"

    iq.Create (true, false)
%>
</BODY>
</HTML>


Creating a Private-message Only Queue (COM)

Platform SDK: Message Queuing

Creating a Private Message Only Queue (COM)

To create a queue that only accepts private messages, MSMQQueueInfo.PrivLevel must be set to MQ_PRIV_LEVEL_BODY. (Both private and public queues can be created to accept only private messages.)

This example creates a public queue that excepts private messages. You can also use this code to create a private queue that excepts private messages by adding the PRIVATE$ keyword to the pathname of the queue.

To create a private message queue

  1. Declare the MSMQQueueInfo variable for the queue.
  2. Create a new MSMQQueueInfo object and assign it to the variable.
  3. Specify the pathname of the queue. In these examples, "." is used to indicate the local computer.

    Note For Message Queuing servers and independent clients, the local machine is the local computer. However, for Message Queuing–dependent clients, the local machine is the client's Message Queuing server.

  4. Set MSMQQueueInfo.PrivLevel to MQ_PRIV_LEVEL_BODY.
  5. Optional. Add additional queue properties as needed.
  6. Call MSMQQueueInfo.Create to create the queue.
For a code example using | See
Microsoft Visual Basic | Visual Basic Code Example
C++ COM | C++ COM Code Example


Visual Basic Code Example: Creating a Private-Message Only Queue

The following example creates a public queue that only accepts private messages. If a queue with the same pathname already exists, an error message is displayed and no queue is created.

To try this example in Microsoft® Visual Basic® (version 5.0), paste the code into the Declaration section of a form, press F5, and click on the form.

Dim qinfo As MSMQQueueInfo

Private Sub Form_Click()

  ' Create a new QueueInfo object.
  Set qinfo = New MSMQQueueInfo

  ' Set the pathname of the queue.
  qinfo.PathName = ".\88TestQueue"

  ' Set privacy level of queue
  qinfo.PrivLevel = MQ_PRIV_LEVEL_BODY

  ' Set additional queue properties
  qinfo.Label = "Test Queue"

  ' Create the queue.
  On Error GoTo ErrorHandler
  qinfo.Create
  MsgBox "Queue is created."

  Exit Sub

ErrorHandler:

  Select Case Err.Number
    Case Is = MQ_ERROR_QUEUE_EXISTS
      MsgBox "A queue with the same pathname is already registered."
    Case Else
      MsgBox "Error creating queue!" + Chr(13) + Chr(13) + _
             "Error: " + Hex(ErrorCode)
  End Select

End Sub


C++ COM Code Example: Creating a Private-Message Only Queue

The following example creates a public queue that only accepts private messages. If a queue with the same pathname already exists, an error message is displayed and no queue is created.

#include <windows.h>
#include <stdio.h>      // for printf
#import "mqoa.dll" no_namespace

int main()
{
  ///////////////////////////////////////////////////////////
  // Initialize OLE
  ///////////////////////////////////////////////////////////
  OleInitialize(NULL);

  ///////////////////////////////////////////////////////////
  // Create private message queue.
  ///////////////////////////////////////////////////////////
  try
  {
    IMSMQQueueInfoPtr qinfo("MSMQ.MSMQQueueInfo");

    qinfo->PathName = ".\\PrivateMessageTestQueue";
    qinfo->Label = "Test Queue";
    qinfo->PrivLevel = MQ_PRIV_LEVEL_BODY;
    try
    {
      qinfo->Create();
    }
    catch (_com_error comerr)
    {
      HRESULT hr = comerr.Error();
      if (hr == MQ_ERROR_QUEUE_EXISTS)
      {
          printf("Queue already exists.\n");
          return -1;
      }
      else
      {
        throw comerr;
      }
    }
    printf("Private message queue created.\n");
    return 0;
  }
  catch (_com_error comerr)
  {
    HRESULT hr = comerr.Error();
    printf("unexpected error: %x\n", hr);
    exit (-1);
  }
}


Locating a Public Queue (COM)

Public queues can be located by running a query on the queues registered in the directory service. A query can be based on the identifier of the queue, its label, the type of service it provides, when it was created, or the last time the properties of the queue were modified.

The query is started by calling MSMQQuery.LookupQueue. When the query is finished, the returned MSMQQueueInfos object provides an enumeration mechanism for locating the queues found by the query.

For an example of | See
Locating queues based in their label | Label Query (COM)
Locating queues based on when they were created | Create Time Query (COM)


Label Query (COM)

The following example locates all the public queues that have a specific label.

Note Queries can be based on the identifier of the queue, its label, the type of service it provides, when it was created, or the last time the properties of the queue were modified.

To run a query based on the label of the queue

  1. Declare an MSMQQuery, MSMQQueueInfos, and MSMQQueueInfo variable for the query.
  2. Call MSMQQuery.LookupQueue to locate the queues. The following examples set the Label parameter to "Test Queue".
  3. Call MSMQQueueInfos.Next to retrieve the first MSMQQueueInfo object found. If more than one queue is returned, continue to call MSMQQueueInfos.Next until all the MSMQQueueInfo objects are retrieved.

    Note While retrieving multiple queues, you can always return to the front of the query results by calling MSMQQueueInfos.Reset. After calling Reset, you will still have to call MSMQQueueInfos.Next to retrieve the first MSMQQueueInfo object in the query results.

For a code example using | See
Microsoft Visual Basic | Visual Basic Code Example
C++ COM | C++ COM Code Example


Visual Basic Code Example: Label Query

This example locates all the public queues with the label Test Queue. It runs a query on the directory service, displaying the pathname of each queue it finds.

To try this example in Microsoft® Visual Basic® (version 5.0), paste the code into the Declaration section of a form, press F5, and click on the form.

Option Explicit
Dim query As New MSMQQuery
Dim qinfos As MSMQQueueInfos
Dim qinfo As MSMQQueueInfo

Private Sub Form_Click()
  On Error GoTo ErrorHandler

  'Locate existing public queue or create one.
  Set qinfos = query.LookupQueue(Label:="Test Queue")
  Set qinfo = qinfos.Next

  'Exit if no queues are found.
  If qinfo Is Nothing Then
     MsgBox ("There are no test queues.")
     Exit Sub
  End If

  'Display the pathname of all test queues.
  While Not qinfo Is Nothing
    MsgBox ("Located test queue: " + qinfo.PathName)
    Set qinfo = qinfos.Next
  Wend

  Exit Sub

ErrorHandler:
MsgBox "Unexpected error." + Chr(13) + "Reason: " + Err.Description + Chr(13) + "Error: " + Hex(Err.Number)

End Sub


C++ COM Code Example: Label Query

This example locates all the public queues with the label Test Queue. It runs a query on the directory service, displaying the pathname of each queue it finds.

#include <windows.h>
#include <stdio.h>      // for printf
#import "mqoa.dll" no_namespace

int main()
{
  OleInitialize(NULL);

  IMSMQQueryPtr query("MSMQ.MSMQQuery");
  IMSMQQueueInfosPtr qinfos;
  IMSMQQueueInfoPtr qinfo;
  _variant_t vtLabel;

  vtLabel = "Test Queue";

  ////////////////////////////////////////////////////////////////////
  // Run query to retrieve MSMQQueueInfos object.
  ////////////////////////////////////////////////////////////////////
  qinfos = query->LookupQueue(&vtMissing, &vtMissing, &vtLabel);

  ////////////////////////////////////////////////////////////////////
  // Retrieve first MSMQQueueInfo object and exit if no queues found.
  ////////////////////////////////////////////////////////////////////

  qinfo = qinfos->Next();

  if (qinfo == NULL)
  {
     puts("No test queues were found.\n");
     return 0;
  }

  ////////////////////////////////////////////////////////////////////
  // Retrieve all MSMQQueueInfo objects, displaying pathname of each
  // queue found.
  ////////////////////////////////////////////////////////////////////
  while (qinfo != NULL)
  {
    wprintf(L"Found queue: %s.\n", (WCHAR *)qinfo->PathName);
    qinfo = qinfos->Next();
  }

  puts("Found no more Test queues in Active Directory!\n");

  return 0;

}


Create Time Query (COM)

The following example locates all the public queues that were created within the last 24 hours.

Note Queries can be based on the identifier of the queue, its label, the type of service it provides, when it was created, or the last time the properties of the queue were modified.

To run a query based on when it was created

  1. Declare an MSMQQuery, MSMQQueueInfos, and MSMQQueueInfo variable for the query.
  2. Call MSMQQuery.LookupQueue to locate the queues. The following examples sets the CreateTime and RelCreateTime parameter.
  3. Call MSMQQueueInfos.Next to retrieve the first MSMQQueueInfo object found. If more than one queue is returned, continue to call MSMQQueueInfos.Next until all the MSMQQueueInfo objects are retrieved.

    Note While retrieving multiple queues, you can always return to the front of the query results by calling MSMQQueueInfos.Reset. After calling Reset, you will still have to call MSMQQueueInfos.Next to retrieve the first MSMQQueueInfo object in the query results.

For a code example using | See
Microsoft Visual Basic | Visual Basic Code Example


Visual Basic Code Example: Create Time Query

This example locates all the public queues that were created within the last 24 hours. It runs a query on the directory service, displaying the time the queue was created for each queue it finds.

To try this example in Microsoft® Visual Basic® (version 5.0), paste the code into the Declaration section of a form, press F5, and click on the form.

Option Explicit
Dim query As New MSMQQuery
Dim qinfos As MSMQQueueInfos
Dim qinfo As MSMQQueueInfo
Dim Today

Private Sub Form_Click()

  On Error GoTo ErrorHandler

  Today = DateAdd("d", -1, Now)
  Set qinfos = query.LookupQueue(CreateTime:=Today, RelCreateTime:=REL_GT)
  Set qinfo = qinfos.Next

  If qinfo Is Nothing Then
    MsgBox ("No queues were created in the last 24 hours.")
    Exit Sub
  End If

  'Display the pathname of all test queues.
  While Not qinfo Is Nothing
    MsgBox ("Queue " + qinfo.PathName + " was created on: " + CStr(qinfo.CreateTime))
    Set qinfo = qinfos.Next
  Wend

  Exit Sub

ErrorHandler:
   MsgBox "Unexpected error." + Chr(13) + "Reason: " + Err.Description + Chr(13) + "Error: " + Hex(Err.Number)
End Sub


Opening a Queue (COM)

To open a queue, the application must specify the access mode and share mode of the queue when it calls MSMQQueueInfo.Open. The Open method returns an MSMQQueue object that can be used for:

  • Sending messages to the queue (MSMQMessage.Send).
  • Reading messages in the queue (MSMQQueue.Peek, MSMQQueue.PeekNext, MSMQQueue.Receive).
  • Enabling notification for reading messages asynchronously (MSMQQueue.EnableNotification).
  • Closing the queue (MSMQQueue.Close).

Note The MSMQQueue object exposes a queue handle that can be used to call Message Queuing functions directly. For example, in Microsoft® Visual Basic®, Message Queuing functions can be called directly using the Declare Function facility.

When a queue is opened, its properties are based on the properties of the MSMQQueueInfo object when the queue was opened. Later, while the queue is opened, the application can always see the properties of the queue by calling the MSMQQueue object's QueueInfo property.

The following examples show several ways to open queues.

For examples of | See
Opening a queue to send messages | Opening a Queue to Send Messages (COM)
Opening a queue to peek at or retrieve messages | Opening a Queue to Read Messages (COM)


Opening a Queue to Send Messages (COM)

When opening a queue to send messages, the receiving application must specify that it intends to send messages to the queue and who else can access the queue when it is open.

To open a queue when sending messages, the queue's access mode must be set to MQ_SEND_ACCESS, and the queue's share mode must be set to MQ_DENY_NONE. Both these modes are set when calling MSMQQueueInfo.Open.

Note Before opening a queue, Message Queuing verifies that the access mode requested by the application does not conflict with the access rights of the queue. If MQ_ERROR_ACCESS_DENIED is returned to the MSMQQueueInfo.Open call, the queue's access control is blocking the application from opening the queue.

For a discussion of queue access rights, see Access Control.

To open a queue for sending messages

  1. Declare a MSMQQueueInfo and MSMQQueue object.
  2. Obtain a MSMQQueueInfo object. The following examples try to create a new MSMQQueueInfo object, ignoring any errors if a queue with the same pathname already exists. (QueueInfo objects for public queues can also be obtained from doing a query on the directory service.)
  3. Call MSMQQueueInfo.Open to open the queue with send access. The following examples open the queue with send access and deny none share mode.
  4. Optional. Add code for sending messages to the queue.
  5. Call MSMQQueue.Close to close the queue.
For a code example using | See
Microsoft Visual Basic | Visual Basic Code Example
C++ COM | C++ COM Code Example
Microsoft VBScript using an ASP file | VBScript Code Example


Visual Basic Code Example: Opening a Queue to Send Messages

This example opens a known public queue (creating a new queue if the queue is not found) with send access.

To try this example in Microsoft® Visual Basic® (version 5.0), paste the code into the Declaration section of a form, press F5, and click on the form.

Option Explicit

'*************************************************************
' Declare the required objects.
'*************************************************************
Dim qinfo As New MSMQQueueInfo
Dim q As MSMQQueue

Private Sub Form_Click()

  '***********************************************************
  ' Create a destination queue, ignoring error if queue
  ' already exists.
  '***********************************************************
  qinfo.PathName = ".\TestQueue"
  qinfo.Label = "Test Queue"
  On Error Resume Next          'Ignore if queue already exists.
  qinfo.Create

  '***********************************************************
  ' Open destination queue for sending messages.
  '***********************************************************
  On Error GoTo ErrorHandler
  Set q = qinfo.Open(MQ_SEND_ACCESS, MQ_DENY_NONE)

  If q.IsOpen = 1 Then
    MsgBox "The queue is open for sending messages."
  Else
    MsgBox "The queue is not open!"
  End If

 '************************************************************
 ' Add code for sending messages.
 '************************************************************

 '************************************************************
 'Close destination queue.
 '************************************************************
 q.Close

 Exit Sub

ErrorHandler:
   MsgBox "Couldn't open queue." + Chr(13) + "Reason: " + Err.Description + Chr(13) + "Error: " + Hex(Err.Number)

End Sub


C++ COM Code Example: Opening a Queue to Send Messages

This example opens a known public queue (creating a new queue if the queue is not found) with send access.

#include <windows.h>
#include <stdio.h>      // for printf
#import "mqoa.dll" no_namespace

int main()
{

  ///////////////////////////////////////////////////////////
  // Initialize OLE
  ///////////////////////////////////////////////////////////
  OleInitialize(NULL);

  try
  {
    IMSMQQueueInfoPtr qinfo("MSMQ.MSMQQueueInfo");
    IMSMQQueuePtr qSend;

    qinfo->PathName = ".\\testqueue";
    try
  {
      qinfo->Create();
    }
    catch (_com_error comerr)
  {
      HRESULT hr = comerr.Error();
      if (hr == MQ_ERROR_QUEUE_EXISTS)
    {
        printf("Opening existing queue.\n");
      }
      else
    {
        throw comerr;
      }
    };

  ////////////////////////////////////////////////////////////
  // Open queue to send message.
  ////////////////////////////////////////////////////////////
  qSend = qinfo->Open(MQ_SEND_ACCESS, MQ_DENY_NONE);

  ////////////////////////////////////////////////////////////
  // Add code for sending message.
  ////////////////////////////////////////////////////////////

  ////////////////////////////////////////////////////////////
  // Close queue.
  ////////////////////////////////////////////////////////////
  qSend->Close();
  return 0;

  }

  catch (_com_error comerr)
  {
    HRESULT hr = comerr.Error();
    printf("unexpected error: %x\n", hr);
    exit(-1);       // failure
  }
}


VBScript Code Example: Opening a Queue to Send Messages

The following example opens a public queue with send access. The queue is opened on the server machine using Active Server Pages and VBSript.

To run this example, paste the following code into a text file that has an .asp suffix (for example, mq.asp), and then place the file in the InetPub\Scripts folder on your web server. (If you use another folder, make sure that folder has execute script privileges.) You can then run this script from your Internet browser by referring to the address: http://<webservername>/scripts.mq.asp.

<HTML>
<BODY>
Create an Message Queuing public queue on the web server
<%
    set iq = Server.CreateObject ("MSMQ.MSMQQueueInfo")
    iq.PathName = ".\TestQueue"
    iq.Label = "Test Queue"
    On Error Resume Next      'Disregard error if queue exists
    iq.Create
    On Error Goto 0
    set myq = iq.Open (2, 0)

%>
</BODY>
</HTML>


Opening a Queue to Read Messages (COM)

When opening a queue to read messages, the receiving application must specify how the messages are read from the queue and who else can access the queue when it is open.

The queue's access mode can be set to MQ_PEEK_ACCESS or MQ_RECEIVE_ACCESS. Use MQ_PEEK_ACCESS when you want to peek at messages without removing them. Use MQ_RECEIVE_ACCESS when you want to peek or retrieve the messages in the queue.

The queue's share mode can be set to MQ_DENY_NONE or MQ_DENY_SHARE_RECEIVE. When peeking at the messages in the queue, MQ_DENY_NONE must be specified. When retrieving messages, either setting can be used.

Both these modes are set when calling MSMQQueueInfo.Open.

Note Before opening a queue, Message Queuing verifies that the access mode requested by the application does not conflict with the access rights of the queue. If MQ_ERROR_ACCESS_DENIED is returned to the Open call, the queue's access control is blocking the application from opening the queue.

For a discussion of queue access rights, see Access Control.

To open a queue to read messages

  1. Declare a MSMQQueueInfo and MSMQQueue object.
  2. Obtain a MSMQQueueInfo object. The following examples try to create a new MSMQQueueInfo object, ignoring any errors if a queue with the same pathname already exists. (QueueInfo objects for public queues can also be obtained from doing a query on the directory service.)
  3. Call MSMQQueueInfo.Open to open the queue with receive or peek access. The following examples open the queue with receive access and deny none share mode.
  4. Optional. Add code for retrieving messages from the queue.
  5. Call MSMQQueue.Close to close the queue.
For a code example using | See
Microsoft Visual Basic | Visual Basic Code Example
C++ COM | C++ COM Code Example
Microsoft VBScript using an ASP file | VBScript Code Example


Visual Basic Code Example: Opening a Queue to Read Messages

This example opens a known public queue (creating a new queue if the queue is not found) with receive access.

To try this example in Microsoft® Visual Basic® (version 5.0), paste the code into the Declaration section of a form, press F5, and click on the form.

Option Explicit

'*************************************************************
' Declare the required objects.
'*************************************************************
Dim qinfo As New MSMQQueueInfo
Dim q As MSMQQueue

Private Sub Form_Click()

  '***********************************************************
  ' Create a destination queue, ignoring error if queue
  ' already exists.
  '***********************************************************
  qinfo.PathName = ".\testqueue"
  qinfo.Label = "Test Queue"
  On Error Resume Next          'Ignore if queue already exists.
  qinfo.Create

  '***********************************************************
  ' Open destination queue for reading messages.
  '***********************************************************
  On Error GoTo ErrorHandler
  Set q = qinfo.Open(MQ_RECEIVE_ACCESS, MQ_DENY_NONE)
  If q.IsOpen = 1 Then
     MsgBox "The queue is open for receiving messages."
  Else
     MsgBox "The queue is not open!"
  End If

  '************************************************************
  ' Add code for reading messages.
  '************************************************************

  '************************************************************
  ' Close destination queue.
  '************************************************************
  q.Close

  Exit Sub

ErrorHandler:
  MsgBox "Couldn't open queue." + Chr(13) + "Reason: " + Err.Description + Chr(13) + "Error: " + Hex(Err.Number)

End Sub


C++ COM Code Example: Opening a Queue to Read Messages

This example opens a known public queue (creating a new queue if the queue is not found) with receive access.

#include <windows.h>
#include <stdio.h>      // for printf
#import "mqoa.dll" no_namespace

int main()
{

  ///////////////////////////////////////////////////////////
  // Initialize OLE
  ///////////////////////////////////////////////////////////
  OleInitialize(NULL);

  try
  {
    IMSMQQueueInfoPtr qinfo("MSMQ.MSMQQueueInfo");
    IMSMQQueuePtr qRec;

    qinfo->PathName = ".\\testqueue";
    try
    {
      qinfo->Create();
    }
    catch (_com_error comerr)
    {
      HRESULT hr = comerr.Error();
      if (hr == MQ_ERROR_QUEUE_EXISTS)
      {
        printf("Opening existing queue.\n");
      }
      else
      {
        throw comerr;
      }
    };

  ////////////////////////////////////////////////////////////
  // Open queue to retrieve message.
  ////////////////////////////////////////////////////////////
  qRec = qinfo->Open(MQ_RECEIVE_ACCESS, MQ_DENY_NONE);

  ////////////////////////////////////////////////////////////
  // Add code for retrieving message.
  ////////////////////////////////////////////////////////////

  ////////////////////////////////////////////////////////////
  // Close queue.
  ////////////////////////////////////////////////////////////
  qRec->Close();
  return 0;

  }

  catch (_com_error comerr)
  {
    HRESULT hr = comerr.Error();
    printf("unexpected error: %x\n", hr);
    exit(-1);       // failure
  }
}


VBScript Code Example: Opening a Queue to Read Messages

The following example opens a public queue with receive access. The queue is opened on the server machine using Active Server Pages and VBSript.

To run this example, paste the following code into a text file that has an .asp suffix (for example, mq.asp), and then place the file in the InetPub\Scripts folder on your web server. (If you use another folder, make sure that folder has execute script privileges.) You can then run this script from your Internet browser by referring to the address: http://<webservername>/scripts.mq.asp.

<HTML>
<BODY>
Create an Message Queuing public queue on the web server
<%
    set iq = Server.CreateObject ("MSMQ.MSMQQueueInfo")
    iq.PathName = ".\testqueue"
    iq.Label = "Test Queue"
    On Error Resume Next      'Disregard error if queue exists
    iq.Create
    On Error Goto 0
    set myq = iq.Open (1, 0)

%>
</BODY>
</HTML>


Deleting a Queue (COM)

Both public and local private queues can be deleted by a single call to MSMQQueueInfo.Delete.

Note Deleting the queue does not delete the MSMQQueueInfo object, only the existing reference to the queue in the directory service (for public queues) or the local computer (for private queues). Because the MSMQQueueInfo object still exists, you can still create a new queue based on its current properties.

To delete a queue

  1. Declare the objects needed to obtain the MSMQQueueInfo object. This example uses an MSMQQuery, MSMQQueueInfos, and MSMQQueueInfo, object.
  2. Obtain the MSMQQueueInfo object of the queue(s) you want to delete. This example uses MSMQQuery.LookupQueue to retrieve several MSMQQueueInfo objects.
  3. Call MSMQQueueInfo.Delete to delete the queue.
For a code example using | See
Microsoft Visual Basic | Visual Basic Code Example


Visual Basic Code Example: Deleting a Queue

The following example locates all the public test queues registered in Active Directory and deletes them as needed.

To try this example in Microsoft® Visual Basic® (version 5.0), paste the code into the Declaration section of a form, press F5, and click on the form.

Option Explicit

Dim query As New MSMQQuery
Dim qinfos As MSMQQueueInfos
Dim qinfo As MSMQQueueInfo
Dim Response As String

Private Sub Form_Click()

  '*************************************************************
  ' Obtain MSMQQueueInfo objects. Locate all queues with
  ' "Test Queue" label.
  '*************************************************************
  Set qinfos = query.LookupQueue(Label:="Test Queue")
  Set qinfo = qinfos.Next                            'Retrieve first MSMQQueueInfo object.

  ' Exit sub if no test queues are found.
  If qinfo Is Nothing Then
     MsgBox ("No test queues found.")
     Exit Sub
  End If

  '*************************************************************
  ' Delete test queues as needed.
  '*************************************************************
  While Not qinfo Is Nothing
    Response = MsgBox("Delete test queue: " + qinfo.PathName + ".", vbYesNo)
    If Response = vbYes Then
         qinfo.Delete
    End If
    Set qinfo = qinfos.Next
  Wend

  MsgBox ("All requested test queues are deleted.")

End Sub


Sending Messages to a Queue (COM)

Sending messages is an asynchronous operation that requires opening the destination queue and sending the message.

The body of an Message Queuing message can be any intrinsic Variant, including string, date, currency, any number type, an array of bytes, as well as any persistent COM object that supports IDispatch and IPersist (IPersistStream or IPersistStorage).

For examples on | See
Sending a string | Sending a String in a Message (COM)
Sending a date | Sending a Date in a Message (COM)
Sending a currency | Sending a Currency in a Message (COM)
Sending a number | Sending a Number in a Message (COM)
Sending an array of bytes | Sending an Array of Bytes in a Message (COM)
Sending a persistent object in a message | Sending a Persistent Object (COM)
Sending a data recordset in a message | Sending a Data Recordset in a Message (COM)
Sending private (encrypted) messages | Sending Private Messages (COM)
Sending messages that return Message Queuing acknowledgment messages | Requesting Acknowledgment Messages (COM)
Sending messages that request an application-defined response message | Requesting Response Messages (COM)
Sending an application-defined response message | Sending Response Messages (COM)
Sending a single message within an implicit internal transaction | Sending a Single-message Transaction (COM)
Sending a file as a message | Sending a File as a Message (COM)


Sending a String in a Message (COM)

The process of sending a message consists of opening a queue with send access, calling the MSMQMessage.Send method, and then closing the queue. The following procedure and example code show how this is done when sending a message whose body contains a string.

To send a string in a message

  1. Declare the objects needed to send a message. These examples use an MSMQQueueInfo, MSMQQueue, and MSMQMessage object.
  2. Open the destination queue with send access. (This example creates a public queue on the local computer if the specified queue does not exist.)
  3. Call Send to send the string message.
  4. Call MSMQQueue.Close to close the queue.
For a code example using | See
Microsoft Visual Basic | Visual Basic Code Example
C++ COM | C++ COM Code Example
Microsoft VBScript using an ASP file | VBScript Code Example
Java | JavaScript Code Example


Visual Basic Code Example: Sending a String

This example sends a message whose body is a string to a known public queue (creating a new queue if the queue is not found).

To try this example in Microsoft® Visual Basic® (version 5.0), paste the code into the Declaration section of a form, press F5, and click on the form.

Option Explicit

'*************************************************************
' Declare the required objects.
'*************************************************************
Dim qinfo As New MSMQQueueInfo
Dim q As MSMQQueue
Dim m As New MSMQMessage

Private Sub Form_Click()

  '*************************************************************
  ' Create a destination queue and open it with SEND access.
  '*************************************************************
  qinfo.PathName = ".\TestQueue"
  qinfo.Label = "Test Queue"
  On Error Resume Next          'Ignore if queue already exists.
  qinfo.Create
  On Error GoTo ErrorHandler
  Set q = qinfo.Open(MQ_SEND_ACCESS, MQ_DENY_NONE)

  '*************************************************************
  ' Send message with a String body type.
  '*************************************************************
  m.Label = "Test Message"
  m.Body = "Body as String"
  m.Send q

  '*************************************************************
  ' Close queue.
  '*************************************************************
  q.Close

  Exit Sub

ErrorHandler:
  MsgBox "Couldn't open queue." + Chr(13) + "Reason: " + Err.Description + Chr(13) + "Error: " + Hex(Err.Number)

End Sub


C++ COM Code Example: Sending a String

This example sends a message whose body is a string to a known public queue (creating a new queue if the queue is not found).

#include <windows.h>
#include <stdio.h>      // for printf
#import "mqoa.dll" no_namespace

int main()
{

  ///////////////////////////////////////////////////////////
  // Initialize OLE
  ///////////////////////////////////////////////////////////
  OleInitialize(NULL);

  try
  {
    IMSMQQueueInfoPtr qinfo("MSMQ.MSMQQueueInfo");
    IMSMQQueuePtr qSend;
    IMSMQMessagePtr m("MSMQ.MSMQMessage");

    qinfo->PathName = ".\\testqueue";
    try
    {
      qinfo->Create();
    }
    catch (_com_error comerr)
    {
      HRESULT hr = comerr.Error();
      if (hr == MQ_ERROR_QUEUE_EXISTS)
      {
        printf("Opening existing queue.\n");
      }
      else
      {
        throw comerr;
      }
    };

  ////////////////////////////////////////////////////////////
  // Open queue to send message.
  ////////////////////////////////////////////////////////////
  qSend = qinfo->Open(MQ_SEND_ACCESS, MQ_DENY_NONE);

  ////////////////////////////////////////////////////////////
  // Send message.
  ////////////////////////////////////////////////////////////
  m->Body = "String message body.";
  m->Label = "Test Message";
  m->Send(qSend);
  printf("Message was sent.\n");

  ////////////////////////////////////////////////////////////
  // Close queue.
  ////////////////////////////////////////////////////////////
  qSend->Close();
  return 0;

  }

  catch (_com_error comerr)
  {
    HRESULT hr = comerr.Error();
    printf("unexpected error: %x\n", hr);
    exit(-1);       // failure
  }
}


VBScript Code Example: Sending a String

The following example sends a message whose body is a string to a known public queue. The message is sent to a queue on the server machine using Active Server Pages (ASP) and VBSript.

Note When using ASP pages, you can send messages only to local queues. You cannot send messages to a remote queue.

To run this example, paste the following code into a text file that has an .asp suffix (for example, mq.asp), and then place the file in the InetPub\Scripts folder on your web server. (If you use another folder, make sure that folder has execute script privileges.) You can then run this script from your Internet browser by referring to the address: http://<webservername>/scripts.mq.asp.

<HTML>
<BODY>
Create an MSMQ public queue on the web server
<%
    set iq = Server.CreateObject ("MSMQ.MSMQQueueInfo")
    iq.PathName = ".\testqueue"
    iq.Label = "Test Queue"
    On Error Resume Next      'Disregard error if queue exists
    iq.Create
    On Error Goto 0
    set myq = iq.Open (2, 0)
    If myq.IsOpen = 1 Then
       Set m = Server.CreateObject("MSMQ.MSMQMessage")
       m.Body = "String message body."
       m.Label = "Test Message"
       m.Send myq
    End If

    myq.Close

%>
</BODY>
</HTML>


JavaScript Code Example: Sending a String

The following code sends a string message to a public destination queue. This code works only with MSMQ 1.0 and Java SDK 2.0.

import java.applet.*;
import java.awt.*;
import mqoa.*;
import com.ms.com.*;

public class msmqjavapp extends Applet implements _DMSMQEvenEvents
{
  IMSMQQueueInfo qInfo=(IMSMQQueueInfo) new MSMQQueueInfo();
  IMSMQQueue qDest;

public void start()
{
  try
  {
     // Open queue with send access.
     IMSMQQueueInfo qinfo = (IMSMQQueueInfo) new MSMQQueueInfo();
     qinfo.setPathName(".\\testqueue");
     IMSMQQueue qDest=qInfo.Open ( MQACCESS.MQ_SEND_ACCESS,
                                   MQSHARE.MQ_DENY_N0NE);

     // Send message.
    IMSMMessage msg=(IMSMQMessage) new MSMQMessage();
    Variant msgbody=new VARIANT();
    msgbody.putString ("test message");
    msg.setBody (msgbody);
    msg.Send (qDest, new Variant());
  }
  catch (Exception e)
  {
     // Add exception handling.
  }
}


Sending a Date in a Message (COM)

The process of sending a message consists of opening a queue with send access, creating the message, calling the Send method, and then closing the queue. The following procedure and example code show how this is done when sending a message whose body contains a Date type.

To send a Date in a message

  1. Declare MSMQQueueInfo, MSMQQueue, and MSMQMessage objects. This example uses one set of MSMQQueue and MSMQMessage objects for sending the message and another set of MSMQQueue and MSMQMessage objects for receiving the message.
  2. Create a destination queue and open it with send access. This example creates a public queue on the local computer.
  3. Send the message with a Date body type.
  4. Close the queue.
For a code example using | See
Microsoft Visual Basic | Visual Basic Code Example


Visual Basic Code Example: Sending a Date

The following example creates a destination queue, sends a message whose body contains a Date, retrieves the message, and tests the retrieved message body to see if it is a Date type.

To try this example in Microsoft® Visual Basic® (version 5.0), paste the code into the Declaration section of a form, press F5, and click on the form.

Option Explicit

'*************************************************************
' Declare the required objects.
'*************************************************************
Dim qinfo As New MSMQQueueInfo
Dim qSend As MSMQQueue
Dim qReceive As MSMQQueue
Dim mSend As New MSMQMessage
Dim mReceive As MSMQMessage

Private Sub Form_Click()

  '*************************************************************
  ' Create a destination queue and open it with SEND access.
  '*************************************************************
  qinfo.PathName = ".\SendTest"
  qinfo.Label = "Send Message Test"
  On Error Resume Next          'Ignore if queue already exists.
  qinfo.Create
  On Error GoTo 0
  Set qSend = qinfo.Open(MQ_SEND_ACCESS, MQ_DENY_NONE)

  '*************************************************************
  ' Send message with Date body type.
  '*************************************************************
  mSend.Label = "Date Message"
  mSend.Body = Date
  mSend.Send qSend
  qSend.Close

End Sub


Sending a Currency in a Message (COM)

The process of sending a message consists of opening a queue with send access, creating the message, calling the MSMQMessage.Send method, and then closing the queue. The following procedure and example code show how this is done when sending a message whose body contains a Currency type.

To send a Currency in a message

  1. Declare MSMQQueueInfo, MSMQQueue, and MSMQMessage objects.
  2. Create a destination queue and open it with send access. This example creates a public queue on the local computer.
  3. Call Send to send the message with a Currency body type.
  4. Call MSMQQueue.Close to close the queue.
For a code example using | See
Microsoft Visual Basic | Visual Basic Code Example


Visual Basic Code Example: Sending a Currency

The following example creates a destination queue, sends a message whose body contains a Currency type, retrieves the message, and tests the retrieved message body to see if it is a Currency type.

To try this example in Microsoft® Visual Basic® (version 5.0), paste the code into the Declaration section of a form, press F5, and click on the form.

Option Explicit

'*************************************************************
' Declare the required objects.
'*************************************************************
Dim qinfo As New MSMQQueueInfo
Dim qSend As MSMQQueue
Dim qReceive As MSMQQueue
Dim mSend As New MSMQMessage
Dim mReceive As MSMQMessage

Private Sub Form_Click()

  '*************************************************************
  ' Create a destination queue and open it with SEND access.
  '*************************************************************
  qinfo.PathName = ".\SendTest"
  qinfo.Label = "Send Message Test"
  On Error Resume Next          'Ignore if queue already exists.
  qinfo.Create
  On Error GoTo 0
  Set qSend = qinfo.Open(MQ_SEND_ACCESS, MQ_DENY_NONE)

  '*************************************************************
  ' Send message with Currency body type.
  '*************************************************************
  mSend.Label = "Currency Message"
  mSend.Body = CCur(100)
  mSend.Send qSend
  qSend.Close

  '*************************************************************
  ' Open the destination queue with RECEIVE access, and
  ' retrieve the message. The retrieved message body is tested
  ' to verify it is a Currency type.
  '*************************************************************
  Set qReceive = qinfo.Open(MQ_RECEIVE_ACCESS, MQ_DENY_NONE)
  Set mReceive = qReceive.Receive
  qReceive.Close

  If TypeName(mReceive.Body) = "Currency" Then
     MsgBox "The retrieved message body is a Currency type."
     Else
     MsgBox "The retrieved message body is not a Currency type."
  End If

End Sub


Sending a Number in a Message (COM)

The process of sending a message consists of opening a queue with send access, creating the message, calling the MSMQMessage.Send method, and then closing the queue. The following procedure and example code show how this is done when sending a message whose body contains a number.

To send a number in a message

  1. Declare MSMQQueueInfo, MSMQQueue, and MSMQMessage objects. This example uses one set of MSMQQueue and MSMQMessage objects for sending the message and another set of MSMQQueue and MSMQMessage objects for receiving the message.
  2. Create a destination queue and open it with send access. This example creates a public queue on the local computer.
  3. Send the message with a number body type. This example sends an Integer type.
  4. Open the destination queue with receive access and retrieve the message. This example removes the message from the queue.
  5. Verify that the body of the retrieved message is an Integer type.
For a code example using | See
Microsoft Visual Basic | Visual Basic Code Example


Visual Basic Code Example: Sending a Number

The following example creates a destination queue, sends a message whose body contains an Integer, retrieves the message, and tests the retrieved message body to see if it is an Integer type.

To try this example in Microsoft® Visual Basic® (version 5.0), paste the code into the Declaration section of a form, press F5, and click on the form.

Option Explicit

'*************************************************************
' Declare the required objects.
'*************************************************************
Dim qinfo As New MSMQQueueInfo
Dim qSend As MSMQQueue
Dim qReceive As MSMQQueue
Dim mSend As New MSMQMessage
Dim mReceive As MSMQMessage

Private Sub Form_Click()

  '*************************************************************
  ' Create a destination queue and open it with SEND access.
  '*************************************************************
  qinfo.PathName = ".\SendTest"
  qinfo.Label = "Send Message Test"
  On Error Resume Next          'Ignore if queue already exists.
  qinfo.Create
  On Error GoTo 0
  Set qSend = qinfo.Open(MQ_SEND_ACCESS, MQ_DENY_NONE)

  '*************************************************************
  ' Send message with Integer body type.
  '*************************************************************
  mSend.Label = "Integer Message"
  mSend.Body = CInt(100)
  mSend.Send qSend
  qSend.Close

  '*************************************************************
  ' Open the destination queue with Receive access and
  ' retrieve the message. The retrieved message body is tested
  ' to verify it is an Integer type.
  '*************************************************************
  Set qReceive = qinfo.Open(MQ_RECEIVE_ACCESS, MQ_DENY_NONE)
  Set mReceive = qReceive.Receive
  qReceive.Close

  If TypeName(mReceive.Body) = "Integer" Then
     MsgBox "The retrieved message body is a Integer type."
     Else
     MsgBox "The retrieved message body is not an Integer type."
  End If

End Sub


Sending an Array of Bytes in a Message (COM)

The process of sending a message consists of opening a queue with send access, creating the message, calling the MSMQMessage.Send method, and then closing the queue. The following procedure and example code show how this is done when sending a message whose body contains an array of bytes.

To send an array of bytes in a message body

  1. Declare MSMQQueueInfo, MSMQQueue, and MSMQMessage objects. This example uses one set of MSMQQueue and MSMQMessage objects for sending the message and another set of MSMQQueue and MSMQMessage objects for receiving the message.
  2. Create a destination queue and open it with send access. This example creates a public queue on the local computer.
  3. Send the message with an array of bytes in the message body.
  4. Open the destination queue with receive access and retrieve the message. This example removes the message from the queue.
  5. Verify that the body of the retrieved message body is an array of bytes.
For a code example using | See
Microsoft Visual Basic | Visual Basic Code Example


Visual Basic Code Example: Sending an Array of Bytes

The following example creates a destination queue, sends a message whose body contains a byte array, retrieves the message, and tests the retrieved message body to see if it is an array of bytes.

To try this example in Microsoft® Visual Basic® (version 5.0), paste the code into the Declaration section of a form, press F5, and click on the form.

Option Explicit

'*************************************************************
' Declare the required objects.
'*************************************************************
Dim qinfo As New MSMQQueueInfo
Dim qSend As MSMQQueue
Dim qReceive As MSMQQueue
Dim mSend As New MSMQMessage
Dim mReceive As MSMQMessage

Private Sub Form_Click()

  '*************************************************************
  ' Create a destination queue and open it with SEND access.
  '*************************************************************
  qinfo.PathName = ".\SendTest"
  qinfo.Label = "Send Message Test"
  On Error Resume Next          'Ignore if queue already exists.
  qinfo.Create
  On Error GoTo 0
  Set qSend = qinfo.Open(MQ_SEND_ACCESS, MQ_DENY_NONE)

  '*************************************************************
  ' Send message with an array of bytes.
  '*************************************************************
  Dim aByte(5) As Byte
  Dim Counter As Integer

  'Populate the array
  For Counter = LBound(aByte) To UBound(aByte)
      aByte(Counter) = CByte(Counter)
  Next

  mSend.Label = "Array of Bytes Message"
  mSend.Body = aByte
  mSend.Send qSend
  qSend.Close

  '*************************************************************
  ' Open the destination queue with RECEIVE access, and
  ' retrieve the message. The retrieved message body is tested
  ' to verify it is an array of bytes.
  '*************************************************************
  Set qReceive = qinfo.Open(MQ_RECEIVE_ACCESS, MQ_DENY_NONE)
  Set mReceive = qReceive.Receive
  qReceive.Close

  If TypeName(mReceive.Body) = "Byte()" Then
     MsgBox "The retrieved message body is an array of bytes."

     Dim aBtyeReceive() As Byte
     ReDim aByteReceive(UBound(mReceive.Body))
     aByteReceive = mReceive.Body
     For Counter = LBound(aByteReceive) To UBound(aByteReceive)
         Debug.Print Counter, aByteReceive(Counter)
     Next

  Else
     MsgBox "The retrieved message body is not an array of bytes."
  End If

End Sub


Sending a Persistent Object (COM)

Message Queuing supports sending and receiving serialized objects that support IPersistStream and IPersistStorage. Many persistent objects, such as all Microsoft Office documents, can be sent as the body of an Message Queuing message.

When sending an object as the body of a message, Message Queuing seamlessly invokes the object's IPersist interface. In this way, when the message is sent, the persistent state of the object is serialized into the message body using the object's supplied IPersist interface. At the receiving end, an implementation of the object's interface must be installed to use the object when it is removed from the queue.

The example below sends a Microsoft® Word 8.0 document to a destination queue. This code could be modified to send any persistent object.

To send a Microsoft Word 8.0 document

  1. Make sure that Microsoft Word 8.0 is installed on your computer.
  2. Add a reference to Microsoft Word 8.0 in your Microsoft Visual Basic project. This example was tested with the following library referenced: Microsoft Word (8.0) Object Library.
  3. Create a destination queue and open it with send access.
  4. Create the Microsoft Word document object.
  5. Create and send a message. Set the body of the message to the document object.
  6. Open the queue with receive access and retrieve the message.
  7. Create a new object using the body of the retrieved message. The example below then tests the new object to verify that it is a Microsoft Word document object.
For a code example using | See
Microsoft Visual Basic | Visual Basic Code Example


Visual Basic Code Example: Sending a Persistent Object

The following example creates a Microsoft Word document object, sends the object as an Message Queuing message to a destination queue, retrieves the message from the queue, and then creates a new object using the body of the retrieved message. The new object is tested to see if it is a Word document object.

To try this example in Microsoft® Visual Basic® (version 5.0), paste the code into the Declaration section of a form, press F5, and click on the form.

Option Explicit

Dim msWordApp As New Word.Application
Dim msWordDoc As Word.Document
Dim objReceive As Object

Dim qinfo As New MSMQQueueInfo
Dim qSend As MSMQQueue
Dim qReceive As MSMQQueue
Dim mSend As New MSMQMessage
Dim mReceive As MSMQMessage

Private Sub Form_Click()

  '*******************************************************************
  ' Create a destination queue and open it with SEND access.
  '*******************************************************************
  qinfo.PathName = ".\ObjectTest"
  qinfo.Label = "My Object Test Queue"
  On Error Resume Next           'Ignore if queue already exists.
  qinfo.Create
  On Error GoTo 0
  Set qSend = qinfo.Open(MQ_SEND_ACCESS, MQ_DENY_NONE)

  '*******************************************************************
  ' Create document object.
  '*******************************************************************
    Set msWordDoc = msWordApp.Documents.Open(FileName:="pathname\filename", ConfirmConversions:=False, ReadOnly:=True)

  '*******************************************************************
  ' Create a message and send it to the destination queue. Set the
  ' body of the message to the document object.
  '*******************************************************************
  mSend.Label = "Testing Object Message"
  mSend.Body = msWordDoc
  mSend.Send qSend
  qSend.Close

  MsgBox "Document object sent as body of message."

  '*******************************************************************
  ' Open the destination queue with Receive access, and retrieve the
  ' message.
  '*******************************************************************
  Set qReceive = qinfo.Open(MQ_RECEIVE_ACCESS, MQ_DENY_NONE)
  Set mReceive = qReceive.Receive
  qReceive.Close

  '*******************************************************************
  ' Retrieve the message from the queue and create new document
  ' object. Test the object to verify it is a Microsoft Word document.
  '*******************************************************************
  Set objReceive = mReceive.Body
  If TypeOf objReceive Is Word.Document Then
     MsgBox "Received message body is a Microsoft Word document."
  Else
     MsgBox "Received message body is unknown object."
  End If

End Sub


Sending a Data Recordset in a Message (COM)

Data recordsets can be sent and retrieved using a combination of Message Queuing and Microsoft Remote Data Service (RDS).

Note RDS is used to transport Active Data Object recordsets from a server to a client computer. The resulting recordset is cached on the client computer and disconnected from the server.

To send a data recordset in a message

  1. Make sure RDS and Microsoft SQL Server are installed on your computer. (This example was tested using RDS 1.5 and SQL 6.5.)
  2. Make sure SQL Server services has been stated.
  3. Add references to the appropriate object libraries in your Microsoft Visual Basic project. This example was tested with the following libraries referenced: Microsoft Message Queue 1.0 Object Library, Microsoft ActiveX Data Objects 1.5 Object Library, and Microsoft Remote Data Services Server 1.5 Object Library.
  4. Create a destination queue and open it with send access.
  5. Create the recordset.
  6. Create and send a message. Set the body of the message to the ADO recordset.
  7. Open the queue with receive access and retrieve the message.
  8. Create a new recordset using the body of the retrieved message. The example below prints out the content of the recordset to confirm that the data was sent and retrieved.
For a code example using | See
Microsoft Visual Basic | Visual Basic Code Example


Visual Basic Code Example: Sending a Data Recordset

The following example creates an ADO recordset, sends the message to a destination queue, and retrieves the message and places it in a new recordset.

To try this example in Microsoft® Visual Basic® (version 5.0), paste the code into the Declaration section of a form, press F5, and click on the form.

Option Explicit

Dim rsSend As ADODB.Recordset
Dim rsReceive As ADODB.Recordset
Dim dataFactory As New RDSServer.DataFactory
Dim sql As String

Dim qinfo As New MSMQQueueInfo
Dim qSend As MSMQQueue
Dim qReceive As MSMQQueue
Dim mSend As New MSMQMessage
Dim mReceive As MSMQMessage

Private Sub Form_Click()

  '*******************************************************************
  ' Create a destination queue and open it with SEND access.
  '*******************************************************************
  qinfo.PathName = ".\RecordsetQueue2"
  qinfo.Label = "My Recordset Queue"
  On Error Resume Next                'Ignore if queue already exists
  qinfo.Create
  On Error Goto 0                     'Reset error handler
  Set qSend = qinfo.Open(MQ_SEND_ACCESS, MQ_DENY_NONE)

  '*******************************************************************
  ' Create an ADO recordset.
  '*******************************************************************
  sql = "select * from authors"
  Set rsSend = dataFactory.Query("driver={SQL Server};server=.;database=pubs;uid=sa;pwd=", sql)

  '*******************************************************************
  ' Create a message and send it to the destination queue. Set the
  ' body of the message to the ADO recordset.
  '*******************************************************************
  mSend.Label = "Testing Recordset"
  mSend.Body = rsSend
  mSend.Send qSend
  qSend.Close

  '*******************************************************************
  ' Open the destination queue with RECEIVE access, and retrieve the
  ' message.
  '*******************************************************************
  Set qReceive = qinfo.Open(MQ_RECEIVE_ACCESS, MQ_DENY_NONE)
  Set mReceive = qReceive.Receive

  '*******************************************************************
  ' Create a new recordset using the body of the retrieved message.
  '*******************************************************************
  Dim obj As Object
  Set obj = mReceive.Body
  If TypeOf obj Is ADODB.Recordset Then
     Set rsReceive = mReceive.Body
     Debug.Print rsReceive(0)                   ' Print column 1
     Debug.Print rsReceive(1)                   ' Print column 2
     Debug.Print rsReceive(2)                   ' Print column 3

     rsReceive.MoveNext
     Debug.Print rsReceive(0)                   ' Print column 1
     Debug.Print rsReceive(1)                   ' Print column 2
     Debug.Print rsReceive(2)                   ' Print column 3
  End If
End Sub


Requesting Acknowledgment Messages (COM)

To request acknowledgment messages, the sending application must indicate the acknowledgment level of the message and the administration queue where the acknowledgment message will be placed.

Acknowledgment messages are returned to the administration queue specified by MSMQMessage.AdminQueueInfo. This queue is maintained by the sending application. It is the sending application's responsibility to create the queue, to read the messages in the queue, and to perform whatever actions are required as a result of the type of acknowledgment message returned by Message Queuing.

Note Each Message Queuing message can have no more than 4 MB of data.

To request acknowledgment messages

  1. Declare two MSMQQueueInfo objects, an MSMQQueue object, and an MSMQMessage object. The following example also declares an MSMQQuery and an MSMQQueueInfos object for locating a known administration queue.
  2. Obtain an MSMQQueueInfo object for the administration queue. You can do this by creating a new queue, locating an existing queue, or by specifying the pathname of a known queue and calling MSMQQueueInfo.Refresh. This example calls MSMQQuery.LookupQueue to obtain the MSMQQueueInfo object of the administration queue.
  3. Call MSMQQueueInfo.Open to open the destination queue.
  4. Set the acknowledgment level and administration queue properties of the message.
  5. Optional. Set additional message properties.
  6. Call MSMQMessage.Send to send the message to the destination queue.
  7. Call MSMQQueue.Close to close the queue.
For a code example using | See
Microsoft Visual Basic | Visual Basic Code Example


Visual Basic Code Example: Requesting Acknowledgment Messages

This example opens a destination queue and sends messages that request positive and negative acknowledgment messages. It obtains the administration queue MSMQQueueInfo object by doing a query for a known administration queue.

To try this example in Microsoft® Visual Basic® (version 5.0), paste the code into the Declaration section of a form, press F5, and click on the form.

Option Explicit

'*************************************************************
' Declare the required objects.
'*************************************************************
Dim query As New MSMQQuery     'Query for locating admin queue
Dim qinfos As MSMQQueueInfos
Dim qinfoAdmin As New MSMQQueueInfo
Dim qinfo As New MSMQQueueInfo
Dim qSend As MSMQQueue
Dim mSend As New MSMQMessage

Private Sub Form_Click()

  '*************************************************************
  ' Locate known administration queue.
  '*************************************************************
  Set qinfos = query.LookupQueue(Label:="Administration Queue")
  Set qinfoAdmin = qinfos.Next
  If qinfoAdmin Is Nothing Then
     MsgBox "Could not locate an administration queue."
     Exit Sub
  End If

  '*************************************************************
  ' Open the destination queue with SEND access,
  ' creating one if it does not already exist. (Duplicate queue
  ' errors are ignored if the queue does already exists.)
  '*************************************************************
  qinfo.PathName = ".\testqueue"
  qinfo.Label = "Test Queue"
  On Error Resume Next          'Ignore if queue already exists.
  qinfo.Create
  On Error GoTo 0
  Set qSend = qinfo.Open(MQ_SEND_ACCESS, MQ_DENY_NONE)

  '*************************************************************
  ' Set the acknowledgment level and administration queue
  ' properties of the message.
  '*************************************************************
  mSend.Ack = MQMSG_ACKNOWLEDGMENT_FULL_REACH_QUEUE
  Set mSend.AdminQueueInfo = qinfoAdmin

  '*************************************************************
  ' Optional. Set additional message properties.
  '*************************************************************
  mSend.Body = "Message acknowledgment test."
  mSend.Label = "test message1"
  mSend.MaxTimeToReceive = 60 * 3

  '*************************************************************
  ' Send message to queue.
  '*************************************************************
  mSend.Send qSend

  MsgBox "The message has been sent to the queue."

  '*************************************************************
  ' Close queue.
  '*************************************************************
  qSend.Close

End Sub


Requesting Response Messages (COM)

By sending the MSMQQueueInfo object of a second queue along with a message, the sending application indicates that it expects a response message from the receiving application. The MSMQQueueInfo object is passed in the MSMQMessage.ResponseQueueInfo property of the message.

When the receiving application reads the message and sees that a response is requested (ResponseQueueInfo is not NULL), it should then return a response message to the queue specified by MSMQMessage.ResponseQueueInfo.

Note Each Message Queuing message can have no more than 4 MB of data.

To request a response

  1. Determine what type of response message is needed. Response messages are application-defined, consequently both the sending and receiving applications must be able to understand the message. For example, the response message could be a message that only indicates a message arrived, or it could include a message body with complete instructions on what to do.
  2. Locate the response queue, creating one if it doesn't exist.
  3. Locate the destination queue, creating one if it doesn't exist.
  4. Open the destination queue and send the message. The example below asks if a response message is wanted.
  5. Retrieve the MSMQMessage.ResponseQueueInfo property from the message, and return a response message if one is requested.
For a code example using | See
Microsoft Visual Basic | Visual Basic Code Example


Visual Basic Code Example: Requesting Response Messages

This example sends a message that includes the MSMQQueueInfo object for a response queue, indicating that a response is expected.

To try this example in Microsoft® Visual Basic® (version 5.0), paste the code into the Declaration section of a form, press F5, and click on the form.

Option Explicit

Dim qinfoDest As New MSMQQueueInfo
Dim qinfoResp As New MSMQQueueInfo
Dim qDest As MSMQQueue
Dim m As New MSMQMessage

Private Sub Form_Click()

  '*************************************************************
  ' Locate a known response queue by attempting to create
  ' the queue, ignoring any errors if the queue already
  ' exists.
  '*************************************************************
  qinfoResp.PathName = ".\responsequeue"
  qinfoResp.Label = "Response Queue"
  On Error Resume Next
  qinfoResp.Create
  On Error GoTo ErrorHandler
  qinfoResp.Refresh

  '*************************************************************
  ' Locate a known destination queue by attempting to create
  ' the queue, ignoring any errors if the queue already
  ' exists.
  '*************************************************************
  qinfoDest.PathName = ".\testqueue"
  qinfoDest.Label = "Test Queue"
  On Error Resume Next          'Ignore if queue already exists.
  qinfoDest.Create
  On Error GoTo ErrorHandler

  '*************************************************************
  ' Open destination queue with send access.
  '*************************************************************
  Set qDest = qinfoDest.Open(MQ_SEND_ACCESS, MQ_DENY_NONE)

  '*************************************************************
  ' Send message with response queue .
  '*************************************************************
  m.Label = "Test Message"
  m.Body = "Request response message"
  Set m.ResponseQueueInfo = qinfoResp
  m.Send qDest

  MsgBox ("The message was sent to the destination queue.")

  '*************************************************************
  ' Close queue.
  '*************************************************************
  qDest.Close

  Exit Sub

ErrorHandler:
MsgBox "Couldn't open queue." + Chr(13) + "Reason: " + Err.Description + Chr(13) + "Error: " + Hex(Err.Number)

End Sub


Sending Response Messages (COM)

Platform SDK: Message Queuing

Sending Response Messages(COM)

The receiving application can return response messages to the response queue provided by the sending application.

When the receiving application reads the message and sees that a response is requested (MSMQMessage.ResponseQueueInfo is not NULL), it should then return a response message to the queue specified by MSMQMessage.ResponseQueueInfo.

Note Each Message Queuing message can have no more than 4 MB of data.

To request a response

  1. Determine what type of response message is needed. Response messages are application-defined, consequently both the sending and receiving applications must be able to understand the message. In this example the response message includes the message identifier and destination of the original message.
  2. Specify the MSMQQueueInfo object of the destination queue that contains the messages sent by the sending application.
  3. Call MSMQQueueInfo.Open to open the destination queue with receive access. In this example, the WantDestinationQueue parameter is set to True so that the destination queue of the original message can be sent back with the response.
  4. Read the message in the queue. This example calls MSMQQueue.Receive to retrieve the first message in the queue.
  5. Verify that a response message was requested. This example inspects the MSMQMessage.ResponseQueueInfo property of the message and then uses MSMQMessage. ResponseQueueInfo to open the response queue if a response is requested.
  6. Create the response message as needed. This example sets the ResponseQueueInfo property of the response message to the DestinationQueueInfo property of the original message, and the correlation identifier of the response message to the message identifier of the original message.
  7. Call MSMQMessage.Send to send the response message to the response queue.
For a code example using | See
Microsoft Visual Basic | Visual Basic Code Example


Visual Basic Code Example: Sending Response Messages

This example retrieves the first message in the queue, looks at the MSMQMessage.ResponseQueueInfo property of the message, then returns a response message if the this property is not NULL.

To try this example in Microsoft® Visual Basic® (version 5.0), paste the code into the Declaration section of a form, press F5, and click on the form.

Option Explicit

Dim qinfoDest As New MSMQQueueInfo
Dim qDest As MSMQQueue
Dim qResp As MSMQQueue
Dim msgRec As MSMQMessage
Dim msgResp As New MSMQMessage

Private Sub Form_Click()

  '*************************************************************
  ' Specify a known destination queue.
  '*************************************************************
  qinfoDest.PathName = ".\testqueue"
  qinfoDest.Label = "Test Queue"

  '*************************************************************
  ' Open destination queue with receive access.
  '*************************************************************
  Set qDest = qinfoDest.Open(MQ_RECEIVE_ACCESS, MQ_DENY_RECEIVE_SHARE)

  '*************************************************************
  ' Retrieve message from destination queue.
  '*************************************************************
  Set msgRec = qDest.Receive(WantDestinationQueue:=True, ReceiveTimeout:=1000)
  qDest.Close

  If msgRec Is Nothing Then
     MsgBox ("There are no messages in the queue.")
     Exit Sub
  End If

  '*************************************************************
  ' Verify that response message is requested. Open response
  ' queue with send access if requested.
  '*************************************************************
  If msgRec.ResponseQueueInfo Is Nothing Then
     MsgBox ("No response was requested.")
     Exit Sub
  Else
     Set qResp = msgRec.ResponseQueueInfo.Open(MQ_SEND_ACCESS, MQ_DENY_NONE)
  End If

  '*************************************************************
  ' Create response message.
  '*************************************************************
  msgResp.Label = "Response Message"
  msgResp.Body = "Returned response message"
  Set msgResp.ResponseQueueInfo = msgRec.DestinationQueueInfo
  msgResp.CorrelationId = msgRec.Id

  '*************************************************************
  ' Send response message to response queue.
  '*************************************************************

  msgResp.Send qResp
  qResp.Close

  MsgBox ("The response message was sent back to the response queue.")
  Exit Sub

ErrorHandler:
MsgBox "Couldn't open queue." + Chr(13) + "Reason: " + Err.Description + Chr(13) + "Error: " + Hex(Err.Number)

End Sub


Requesting Report Messages (COM)

To request report messages, a report queue must be specified and tracing must be enabled. Once a message has been sent with tracing enabled, you can use Active Directory Manager to view the report messages Message Queuing sent to the report queue.

Report queues are typically specified by the MSMQ Administrator through Active Directory Manager. You can select a know report queue, or specify a new queue and Active Directory Manager will create the queue for you.

Note Report queues are typically created via Active Directory Manager. If you want to create a report queue using MSMQQueueInfo.Create, be sure to specify the following queue type (GUID) when creating the queue.

{55EE8F32-CCE9-11CF-B108-0020AFD61CE9}

To enable tracing

  1. Using Active Directory Manager, make sure a report queue has been specified.
  2. In your application, define the structures needed to send the message.
  3. Call MSMQQueueInfo.Open to open the destination queue with send access.
  4. Specify MSMQMessage.Trace, setting it to MQMSG_SEND_ROUTE_TO_REPORT_QUEUE.
  5. Optional. Specify other message properties as needed.
  6. Call MSMQMessage.Send to send the message.
  7. Call MSMQQueue.Close to close the destination queue.
For a code example using | See
Microsoft Visual Basic | Visual Basic Code Example


Visual Basic Code Example: Requesting Report Messages

The following example creates a public queue that only accepts private messages. If a queue with the same pathname already exists, an error message is displayed and no queue is created.

To try this example in Microsoft® Visual Basic® (version 5.0), paste the code into the Declaration section of a form, press F5, and click on the form.

Option Explicit

Dim qinfo As New MSMQQueueInfo
Dim q As MSMQQueue
Dim m As New MSMQMessage

Private Sub Form_Click()

  '*************************************************************
  ' Create a destination queue and open it with SEND access.
  '*************************************************************
  qinfo.PathName = ".\testqueue"
  qinfo.Label = "Test Queue"
  On Error Resume Next          'Ignore if queue already exists.
  qinfo.Create
  On Error GoTo ErrorHandler
  Set q = qinfo.Open(MQ_SEND_ACCESS, MQ_DENY_NONE)

  '*************************************************************
  ' Send message with a String body type.
  '*************************************************************
  m.Label = "Test Message"
  m.Body = "Body as String"
  m.Trace = MQMSG_SEND_ROUTE_TO_REPORT_QUEUE
  m.Send q

  MsgBox ("Message was sent to queue. Check the designated report queue to see report messages.")

  '*************************************************************
  ' Close queue.
  '*************************************************************
  q.Close

  Exit Sub

ErrorHandler:
  MsgBox "Couldn't open queue." + Chr(13) + "Reason: " + Err.Description + Chr(13) + "Error: " + Hex(Err.Number)

End Sub


Sending Private Messages (COM)

Sending private messages requires setting the privacy level of the message, and, as an option, setting the encryption algorithm used to encrypt the message.

Note The privacy level of the queue can also be set. A queue can accept only private messages, only non-private messages, or both. If the privacy level of the sent message does not correspond to the privacy level of the queue, the message is rejected by the queue, and, if the sending application requested a negative acknowledgment messages when it sent the message, an MQMSG_CLASS_BAD_ENCRYPTION class acknowledgment message is returned to the sending application. If no acknowledgments were requested, the sending application has no way to know if the queue rejected the message.

The actual call to send and read private messages is the same as the call to send and read non-private messages.

Note Each Message Queuing message can have no more than 4 MB of data.

To send private messages

  1. Optional. Verify the privacy level of the queue. A queue can be set to accept only private messages, only non-private messages, or both.
  2. Declare an MSMQQueueInfo, MSMQQueue, and MSMQMessage object.
  3. Call MSMQQueueInfo.Open to open the queue with Send access.
  4. Set the privacy level of the message to MQMSG_PRIV_LEVEL_BODY.
  5. Optional. Set the encryption algorithm used to encrypt the message.
  6. Call MSMQMessage.Send to send the private message to the queue.
  7. Call MSMQQueue.Close to free resource.
For a code example using | See
Microsoft Visual Basic | Visual Basic Code Example
C++ COM | C++ COM Code Example


Visual Basic Code Example: Sending a Private Message

This example sends a private message to a known queue. Note that the encryption algorithm used to encrypt the message is the default algorithm.

To try this example in Microsoft® Visual Basic® (version 5.0), paste the code into the Declaration section of a form, press F5, and click on the form.

Option Explicit

'*************************************************************
' Declare the required objects.
'*************************************************************
Dim qinfo As New MSMQQueueInfo
Dim qSend As MSMQQueue
Dim mSend As New MSMQMessage

Private Sub Form_Click()

  '*************************************************************
  ' Open the queue with SEND access, creating one it
  ' it does not already exist. (Duplicate queue errors are
  ' ignored if the queue does already exists.)
  '*************************************************************
  qinfo.PathName = ".\PrivateMessageTestQueue"
  qinfo.Label = "Test Queue"
  qinfo.PrivLevel = MQ_PRIV_LEVEL_BODY
  On Error Resume Next          'Ignore if queue already exists.
  qinfo.Create
  On Error GoTo 0
  Set qSend = qinfo.Open(MQ_SEND_ACCESS, MQ_DENY_NONE)

  '*************************************************************
  ' Set message properties and send to queue.
  '*************************************************************

  'Set message properties
  mSend.Body = "Private message test."
  mSend.Label = "Test Message"
  mSend.PrivLevel = MQMSG_PRIV_LEVEL_BODY

  'Send message
  mSend.Send qSend

  '*************************************************************
  ' Close queue.
  '*************************************************************
  qSend.Close

  MsgBox "The message has been sent to the queue."

End Sub


C++ COM Code Example: Sending a Private Message

This example sends a private message to a known queue. Note that the encryption algorithm used to encrypt the message is the default algorithm.

#include <windows.h>
#include <stdio.h>      // for printf
#import "mqoa.dll" no_namespace

int main()
{

  ///////////////////////////////////////////////////////////
  // Initialize OLE
  ///////////////////////////////////////////////////////////
  OleInitialize(NULL);

  try
  {
    IMSMQQueueInfoPtr qinfo("MSMQ.MSMQQueueInfo");
    IMSMQQueuePtr qSend;
    IMSMQMessagePtr m("MSMQ.MSMQMessage");

    qinfo->PathName = ".\\privatemessagetestqueue";
    qinfo->Label = "Test Queue";
    qinfo->PrivLevel = MQ_PRIV_LEVEL_BODY;
    try
    {
      qinfo->Create();
    }
    catch (_com_error comerr)
    {
      HRESULT hr = comerr.Error();
      if (hr == MQ_ERROR_QUEUE_EXISTS)
      {
        printf("Opening existing queue.\n");
      }
      else
      {
        throw comerr;
      }
    };

  ////////////////////////////////////////////////////////////
  // Open queue to send message.
  ////////////////////////////////////////////////////////////
  qSend = qinfo->Open(MQ_SEND_ACCESS, MQ_DENY_NONE);

  ////////////////////////////////////////////////////////////
  // Send message.
  ////////////////////////////////////////////////////////////
  m->Body = "String message body.";
  m->Label = "Test Message";
  m->PrivLevel = MQMSG_PRIV_LEVEL_BODY;
  m->Send(qSend);
  printf("Message was sent.\n");

  ////////////////////////////////////////////////////////////
  // Close queue.
  ////////////////////////////////////////////////////////////
  qSend->Close();
  return 0;

  }

  catch (_com_error comerr)
  {
    HRESULT hr = comerr.Error();
    printf("unexpected error: %x\n", hr);
    exit(-1);       // failure
  }
}


Sending a File as a Message (COM)

Files can be sent as messages by converting the file to an array of bytes, then sending the byte-array as the body of the message.

Note Each Message Queuing message can have no more than 4 MB of data.

To send a file as a message

  1. Declare an MSMQQueueInfo, MSMQQueue, and MSMQMessage object, plus a byte array for the file.
  2. Call MSMQQueueInfo.Open to open the destination queue with send access.
  3. Put the file in the body of the message.
  4. Optional. Set additional message properties.
  5. Call MSMQMessage.Send to send the message to the destination queue.
  6. Call MSMQQueue.Close to close the queue.
For a code example using | See
Microsoft Visual Basic | Visual Basic Code Example


Visual Basic Code Example: Sending a File

Platform SDK: Message Queuing

Visual Basic Code Example: Sending a Data File

This example sends an existing test file to a queue.

To try this example in Microsoft® Visual Basic® (version 5.0), paste the code into the Declaration section of a form (changing "TestFileName" to the name of any existing file), press F5, and click on the form.

Option Explicit
Dim qinfo As New MSMQQueueInfo
Dim qSend As MSMQQueue
Dim mSend As New MSMQMessage
Dim barray() As Byte
Dim strFileName As String

Private Sub Form_Click()

  '*************************************************************
  ' Open queue with SEND access. The queue is
  ' if no such queue exists
  '*************************************************************

  qinfo.PathName = ".\TestQueue"
  qinfo.Label = "Test Queue"
  On Error Resume Next           'Ignore if queue already exists.
  qinfo.Create
  On Error GoTo 0
  Set qSend = qinfo.Open(MQ_SEND_ACCESS, MQ_DENY_NONE)

  '*************************************************************
  ' Put file into message.
  '*************************************************************
  strFileName = "TestFileName"
  Open strFileName For Binary As #1
  ReDim barray(LOF(1))
  Get #1, , barray               'Read file into buffer
  Close 1

  mSend.Body = barray
  mSend.Label = "Test Message"

  '*************************************************************
  ' Send message to queue.
  '*************************************************************
  mSend.Send qSend

  '*************************************************************
  ' Close queue.
  '*************************************************************
  qSend.Close

  MsgBox "The file has been sent to the queue."

End Sub


Reading Messages in a Queue (COM)

Reading messages in a queue can be done synchronously or asynchronously. Your receiving application can read the messages at the front of the queue, or use cursors to navigate through a queue to a specific message.

For an example of | See
Synchronously reading messages from a queue | Reading Messages Synchronously (COM)
Asynchronously reading messages from a queue | Reading Messages Asynchronously (COM)
Using a cursor to peek at all the messages in a queue | Reading Messages Using a Cursor (COM)


Reading Messages Synchronously (COM)

To read messages synchronously, you must open the queue with receive or peek access, then call the appropriate peek or receive method to read the message in the queue. This example shows how to retrieve the first message in the queue.

Note You cannot read messages from remotes queue when performing a transaction or when operating offline.

When reading messages synchronously, execution is blocked until a message is available or the message time-out timer expires.

To read the first message synchronously

  1. Declare the objects needed to read a message. These examples use a MSMQQueueInfo, MSMQQueue, and MSMQMessage object.
  2. Open the queue with receive or peek access. (The following example opens the queue with receive access. This allows you to peek or retrieve the messages in the queue.)
  3. Call MSMQQueue.Receive to retrieve the message.
  4. Call MSMQQueue.Close to close the queue.
For a code example using | See
Microsoft Visual Basic | Visual Basic Code Example
C++ COM | C++ COM Code Example
Microsoft VBScript using an ASP file | VBScript Code Example


Visual Basic Code Example: Reading Messages Synchronously

This example synchronously retrieves the first messages from a known queue. Note that when the MSMQQueue.Receive call is made, if no message exists a NULL message object is returned when the ReceiveTimeout timer expires.

To try this example in Microsoft® Visual Basic® (version 5.0), paste the code into the Declaration section of a form, press F5, and click on the form.

Option Explicit

'*************************************************************
' Declare the required objects.
'*************************************************************
Dim qinfo As New MSMQQueueInfo
Dim q As MSMQQueue
Dim msgRec As MSMQMessage

Private Sub Form_Click()

  '***********************************************************
  ' Create a destination queue, ignoring error if queue
  ' already exists.
  '***********************************************************
  qinfo.PathName = ".\testqueue"
  qinfo.Label = "Test Queue"
  On Error Resume Next          'Ignore if queue already exists.
  qinfo.Create
  On Error GoTo ErrorHandler    'Reset error handler.

  '***********************************************************
  ' Open destination queue for retrieving messages.
  '***********************************************************
  Set q = qinfo.Open(MQ_RECEIVE_ACCESS, MQ_DENY_NONE)

  '************************************************************
  ' Retrieve messages from the queue.
  '************************************************************
  Set msgRec = q.Receive(ReceiveTimeout:=1000)

  If msgRec Is Nothing Then
    MsgBox "There are no messages in the queue"
  Else
    MsgBox "The first message in the queue was removed."
  End If

  '************************************************************
  'Close destination queue.
  '************************************************************
  q.Close

  Exit Sub

ErrorHandler:
MsgBox "Unexpected error!" + Chr(13) + "Reason: " + Err.Description + Chr(13) + "Error: " + Hex(Err.Number)

End Sub


C++ COM Code Example: Reading Messages Synchronously

This example synchronously retrieves the first messages from a known queue.

#include <windows.h>
#include <stdio.h>      // for printf
#import "mqoa.dll" no_namespace

int main()
{

  ///////////////////////////////////////////////////////////
  // Initialize OLE
  ///////////////////////////////////////////////////////////
  OleInitialize(NULL);

  // Set value of ReceiveTimout parameter.
  _variant_t vtReceiveTimeout;
  vtReceiveTimeout = (long)1000;

  try
  {
    IMSMQQueueInfoPtr qinfo("MSMQ.MSMQQueueInfo");
    IMSMQQueuePtr qRec;
    IMSMQMessagePtr msgRec("MSMQ.MSMQMessage");

    qinfo->PathName = ".\\testqueue";
    try
    {
      qinfo->Create();
    }
    catch (_com_error comerr)
    {
      HRESULT hr = comerr.Error();
      if (hr == MQ_ERROR_QUEUE_EXISTS)
    {
        printf("Opening existing queue.\n");
      }
      else
    {
        throw comerr;
      }
    };

  ////////////////////////////////////////////////////////////
  // Open queue to retrieve message.
  ////////////////////////////////////////////////////////////
  qRec = qinfo->Open(MQ_RECEIVE_ACCESS, MQ_DENY_NONE);

  ////////////////////////////////////////////////////////////
  // Retrieve messages from queue.
  ////////////////////////////////////////////////////////////
  msgRec = qRec->Receive(&vtMissing, &vtMissing, &vtMissing, &vtReceiveTimeout);
  if (msgRec == NULL)
  {
     printf("There are no messages in the queue.\n");
     return 0;
  }

  ////////////////////////////////////////////////////////////
  // Close queue.
  ////////////////////////////////////////////////////////////
  qRec->Close();
  return 0;

  }

  catch (_com_error comerr)
  {
    HRESULT hr = comerr.Error();
    printf("unexpected error: %x\n", hr);
    exit(-1);       // failure
  }
}


VBScript Code Example: Reading Messages Synchronously

This example synchronously retrieves the first messages from a known queue.

Note When using ASP pages, you can retrieve message only from local queues. You cannot retrieve messages from a remote queue.

To run this example, paste the following code into a text file that has an .asp suffix (for example, mq.asp), and then place the file in the InetPub\Scripts folder on your web server. (If you use another folder, make sure that folder has execute script privileges.) You can then run this script from your Internet browser by referring to the address: http://<webservername>/scripts.mq.asp.

<HTML>
<BODY>
Read messages from an Message Queuing public queue on the web server
<%
  set iQueueInfo = Server.CreateObject("MSMQ.MSMQQueueInfo")
  iQueueInfo.PathName = ".\TestQueue"
  set iQueue = iQueueInfo.Open(1,0)

  Set iMessageDest = iQueue.Receive(null, false, true, 1000)
  If iMessageDest Is Nothing Then
    MsgBox "There are no messages in the queue."
  Else
    MsgBox "The first message was removed from the queue."
  End If

%>
</BODY>
</HTML>


Reading Messages Asynchronously (COM)

The MSMQEvent object used to read messages asynchronously, is implemented in terms of callbacks, and is limited to 64 callbacks per process. Internally, Message Queuing uses the WaitForMultipleObjects API which is limited to 64 objects per process.

When reading messages asynchronously, MSMQQueue.EnableNotification must be called for each message that is read from the queue. Typically, EnableNotification is called for the first message to be read and then again in the arrived event handler to read another message. Notification returns a single Arrived event for each message found in the queue.

The following diagram shows the basic programming model used for reading messages asynchronously. It includes two calls to MSMQQueue.EnableNotification, plus a call to read the message from the queue.

The model in the diagram shows that there are many ways to combine the two calls to MSMQQueue.EnableNotification and the call to read the message in the queue. For example, to purge all the messages in a queue, you could call MSMQQueue.EnableNotification with its Cursor parameter set to MQMSG_CURRENT, call MSMQQueue.ReceiveCurrent to retrieve the message from the queue, and call MSMQQueue.EnableNotification with Cursor set to MQMSG_CURRENT.

However, not all combinations necessarily make good programming sense. For example, it is possible to write an event handler that would only read every other message in the queue.

The initial call to MSMQQueue.EnableNotification and the subsequent call from the event handler can tell Message Queuing to check if a message is in the queue at all (Cursor = MQMSG_FIRST), if a message is at the current cursor location (Cursor = MQMSG_CURRENT), or if a message is at the next position after the cursor (Cursor = MQMSG_NEXT). The default is to trigger the Arrived event when Message Queuing finds any message in the queue (Cursor = MQMSG_FIRST).

The calls to read the message in the queue include: MSMQQueue.Receive, MSMQQueue.ReceiveCurrent, MSMQQueue.Peek, MSMQQueue.PeekCurrent, or MSMQQueue.PeekNext.

Note Each call to MSMQQueue.EnableNotification, plus the calls to MSMQQueue.ReceiveCurrent, MSMQQueue.PeekCurrent, or MSMQQueue.PeekNext, provide numerous ways to navigate through the queue. Each call can affect how the cursor is moved through the queue.

To find a specific message asynchronously

  1. Obtain a valid MSMQQueueInfo object. The MSMQQueueInfo object in the following code example is obtained by creating a new queue if an existing queue does not exist.
  2. Call MSMQQueueInfo.Open to open queue with receive access and call MSMQQueue.EnableNotification to start notification.
  3. Write Arrived event handler. The event handler in the following code example calls MSMQQueue.PeekCurrent to look at the current message and then uses MSMQQueue.EnableNotification (Cursor = MQMSG_NEXT) to re-enable notification with the cursor pointing to the next location. (Note that if the message was removed from the queue, notification would be re-enabled with Cursor = MQMSG_CURRENT)
  4. Write Arrived Error event handler.
For a code example using | See
Microsoft Visual Basic | Visual Basic Code Example


Visual Basic Code Example: Reading Messages Asynchronously

The following example peeks at each message in the queue, displaying the label of each message.

To try this example in Microsoft® Visual Basic® (version 5.0), paste the code into the Declaration section of a form, press F5, and click on the form.

Option Explicit
Dim qinfo As New MSMQQueueInfo
Dim q As MSMQQueue
Dim msg As New MSMQMessage
Dim WithEvents msgEvent As MSMQEvent

Private Sub Form_Click()
  '***********************************************************
  ' Create a destination queue, ignoring the error if the queue
  ' already exists.
  '***********************************************************
  qinfo.PathName = ".\testqueue"
  qinfo.Label = "Test Queue"
  On Error Resume Next          'Ignore if queue already exists.
  qinfo.Create
  On Error GoTo ErrorHandler    'Reset error handler.

  '***********************************************************
  ' Open the destination queue for retrieving messages and enable
  ' notification.
  '***********************************************************
  Set q = qinfo.Open(MQ_RECEIVE_ACCESS, MQ_DENY_NONE)
  Set msgEvent = New MSMQEvent
  q.EnableNotification Event:=msgEvent, Cursor:=MQMSG_CURRENT, ReceiveTimeout:=1000
  Exit Sub

ErrorHandler:
MsgBox "Error opening queue or enabling notification." + _
       Chr(13) + Err.Description
End Sub

'*************************************************************
' Define the Arrived event handler.
'*************************************************************
Private Sub msgEvent_Arrived(ByVal queue As Object, _
                             ByVal Cursor As Long)
  On Error GoTo msgArrivedErrorHandler
  Set msg = queue.PeekCurrent(ReceiveTimeout:=0)
  MsgBox "Investigating message: " + msg.Label
  q.EnableNotification Event:=msgEvent, Cursor:=MQMSG_NEXT, ReceiveTimeout:=10000
  Exit Sub

msgArrivedErrorHandler:
MsgBox Err.Description + " in Arrived event"
End Sub

'*************************************************************
' Define the Arrived Error event handler.
'*************************************************************
Private Sub msgEvent_ArrivedError(ByVal queue As Object, _
                                  ByVal ErrorCode As Long, _
                                  ByVal Cursor As Long)
  Select Case ErrorCode
    Case Is = -1072824292
    MsgBox "Error event fired! An illegal cursor movement was requested." + _
            Chr(13) + Chr(13) + "Error: " + Hex(ErrorCode)
    Case Is = -1072824293
    MsgBox "Error event fired! Time-out error returned after waiting for new messages." + _
            Chr(13) + Chr(13) + "Error: " + Hex(ErrorCode)
    Case Else
    MsgBox "Error event fired!" + Chr(13) + Chr(13) + _
           "Error: " + Hex(ErrorCode)
  End Select
End Sub


Reading Messages Using a Cursor (COM)

When reading messages using a cursor, the receiving application can navigate to any number of messages in the queue. The following example navigates through the queue, displaying the label of each message it finds.

Note Cursors can be used when reading messages synchronously or asynchronously.

To read messages using a cursor

  1. Declare the objects needed to read the messages. This example uses a MSMQQueueInfo, MSMQQueue, and MSMQMessage object.
  2. Obtain a QueueInfo object. The following example obtains the QueueInfo object by creating a queue, ignoring errors if the queue already exists.
  3. Open the queue with receive or peek access.
  4. Call MSMQQueue.PeekCurrent to point the cursor to the first message in the queue.
  5. Using a loop structure, call MSMQQueue.PeekNext to move the cursor and read all the messages in the queue.
  6. Call MSMQQueue.Close to close the queue.
For a code example using | See
Microsoft Visual Basic | Visual Basic Code Example


Visual Basic Code Example: Reading Messages Using a Cursor

This example uses the cursor to display the label of each message in the queue. Note that you must call MSMQQueue.PeekCurrent to point the cursor to the first message in the queue before you call MSMQQueue.PeekNext to move the cursor.

To try this example in Microsoft® Visual Basic® (version 5.0), paste the code into the Declaration section of a form, press F5, and click on the form.

Option Explicit

Dim qinfo As New MSMQQueueInfo
Dim q As MSMQQueue
Dim msgRec As MSMQMessage

Private Sub Form_Click()

  '***********************************************************
  ' Obtain a QueueInfo object by trying to create a queue,
  ' ignoring errors if the queue already exists.
  '***********************************************************
  qinfo.PathName = ".\testqueue"
  qinfo.Label = "Test Queue"
  On Error Resume Next          'Ignore if queue already exists.
  qinfo.Create
  On Error GoTo ErrorHandler    'Reset error handler.

  '***********************************************************
  ' Open destination queue for reading messages.
  '***********************************************************
  Set q = qinfo.Open(MQ_RECEIVE_ACCESS, MQ_DENY_NONE)

  '************************************************************
  ' Point the cursor to the first message in the queue.
  '************************************************************
  Set msgRec = q.PeekCurrent(ReceiveTimeout:=1000)
  If msgRec Is Nothing Then
     MsgBox "There are no messages in the queue!"
     Exit Sub
  End If

  '************************************************************
  ' Look at each message in the queue and display its label.
  '************************************************************
  Do While True
    MsgBox "Investigating message: " + msgRec.Label
    Set msgRec = q.PeekNext(ReceiveTimeout:=1000)
    If msgRec Is Nothing Then Exit Do
  Loop
  MsgBox "No more messages are in the queue."

  '************************************************************
  'Close destination queue.
  '************************************************************
  q.Close

  Exit Sub

ErrorHandler:
MsgBox "Unexpected error!" + Chr(13) + "Reason: " + Err.Description + Chr(13) + "Error: " + Hex(Err.Number)

End Sub


Purging Messages in a Queue (COM)

Messages can be purged from the queue synchronously or asynchronously. The following examples show how to programmatically remove all the message from a queue. Note that cursors are not needed to remove all the messages from a queue.

For an example of | See
Purging a queue using synchronous calls | Purging a Queue Synchronously (COM)
Purging a queue using asynchronous calls | Purging a Queue Asynchronously (COM)


Purging a Queue Synchronously (COM)

To purge the messages from a queue, you must call MSMQQueue.Receive for each message in the queue.

When reading messages synchronously, execution is blocked until a message is available or the message time-out timer expires.

To purge a queue synchronously

  1. Declare the objects needed to retrieve a message. This example declares an MSMQQueueInfo, MSMQQueue, and MSMQMessage object.
  2. Call MSMQQueueInfo.Open and open the queue with receive access.
  3. Call MSMQQueue.Receive to retrieve each message in the queue. The following examples use MSMQQueue.Receive to retrieve the first message in the queue.
  4. Call MSMQQueue.Close to close the queue.
For a code example using | See
Microsoft Visual Basic | Visual Basic Code Example
C++ COM | C++ COM Code Example
Microsoft VBScript using an ASP file | VBScript Code Example


Visual Basic Code Example: Purging a Queue Synchronously

This example synchronously retrieves all the messages from a known queue. Note that when the last MSMQQueue.Receive call is made, a NULL message object is returned when the ReceiveTimeout timer expires.

To try this example in Microsoft® Visual Basic® (version 5.0), paste the code into the Declaration section of a form, press F5, and click on the form.

Option Explicit

'*************************************************************
' Declare the required objects.
'*************************************************************
Dim qinfo As New MSMQQueueInfo
Dim q As MSMQQueue
Dim msgRec As MSMQMessage

Private Sub Form_Click()

  '***********************************************************
  ' Create a destination queue, ignoring error if queue
  ' already exists.
  '***********************************************************
  qinfo.PathName = ".\testqueue"
  qinfo.Label = "Test Queue"
  On Error Resume Next          'Ignore if queue already exists.
  qinfo.Create
  On Error GoTo ErrorHandler    'Reset error handler.

  '***********************************************************
  ' Open destination queue for retrieving messages.
  '***********************************************************
  Set q = qinfo.Open(MQ_RECEIVE_ACCESS, MQ_DENY_NONE)

 '************************************************************
 ' Retrieve messages from the queue.
 '************************************************************
 Do While True
    Set msgRec = q.Receive(ReceiveTimeout:=1000)
    If msgRec Is Nothing Then Exit Do
    MsgBox msgRec.Label + "Message removed from queue."
 Loop
 MsgBox "All messages are removed from the queue."

 '************************************************************
 'Close destination queue.
 '************************************************************
 q.Close

 Exit Sub

ErrorHandler:
MsgBox "Unexpected error!" + Chr(13) + "Reason: " + Err.Description + Chr(13) + "Error: " + Hex(Err.Number)

End Sub


C++ COM Code Example: Purging a Queue Synchronously

This example synchronously retrieves all the messages from a known queue.

#include <windows.h>
#include <stdio.h>      // for printf
#import "mqoa.dll" no_namespace

int main()
{

  ///////////////////////////////////////////////////////////
  // Initialize OLE
  ///////////////////////////////////////////////////////////
  OleInitialize(NULL);

  // Set value of ReceiveTimout parameter.
  _variant_t vtReceiveTimeout;
  vtReceiveTimeout = (long)1000;

  try
  {
    IMSMQQueueInfoPtr qinfo("MSMQ.MSMQQueueInfo");
    IMSMQQueuePtr qRec;
    IMSMQMessagePtr msgRec("MSMQ.MSMQMessage");

    qinfo->PathName = ".\\testqueue";
    try
    {
      qinfo->Create();
    }
    catch (_com_error comerr)
    {
      HRESULT hr = comerr.Error();
      if (hr == MQ_ERROR_QUEUE_EXISTS)
    {
        printf("Opening existing queue.\n");
      }
      else
    {
        throw comerr;
      }
    };

  ////////////////////////////////////////////////////////////
  // Open queue to retrieve message.
  ////////////////////////////////////////////////////////////
  qRec = qinfo->Open(MQ_RECEIVE_ACCESS, MQ_DENY_NONE);

  ////////////////////////////////////////////////////////////
  // Retrieve messages from queue.
  ////////////////////////////////////////////////////////////
  msgRec = qRec->Receive(&vtMissing, &vtMissing, &vtMissing, &vtReceiveTimeout);
  if (msgRec == NULL)
  {
     printf("There are no messages in the queue.\n");
     return 0;
  }

  while (msgRec != NULL)
  {
     printf("Message removed from queue.\n");
     msgRec = qRec->Receive(&vtMissing, &vtMissing, &vtMissing, &vtReceiveTimeout);
  }
  printf("All messages are removed from the queue.\n");

  ////////////////////////////////////////////////////////////
  // Close queue.
  ////////////////////////////////////////////////////////////
  qRec->Close();
  return 0;

  }

  catch (_com_error comerr)
  {
    HRESULT hr = comerr.Error();
    printf("unexpected error: %x\n", hr);
    exit(-1);       // failure
  }
}


VBScript Code Example: Purging a Queue Synchronously

This example synchronously retrieves all the messages from a known queue.

Note When using ASP pages, you can retrieve message only from local queues. You cannot retrieve messages from a remote queue.

To run this example, paste the following code into a text file that has an .asp suffix (for example, mq.asp), and then place the file in the InetPub\Scripts folder on your web server. (If you use another folder, make sure that folder has execute script privileges.) You can then run this script from your Internet browser by referring to the address: http://<webservername>/scripts.mq.asp.

<HTML>
<BODY>
Read messages from an Message Queuing public queue on the web server
<%
  set iQueueInfo = Server.CreateObject("MSMQ.MSMQQueueInfo")
  iQueueInfo.PathName = ".\TestQueue"
  set iQueue = iQueueInfo.Open(1,0)

  Do While True
    Set iMessageDest = iQueue.Receive(null, false, true, 1000)
    If iMessageDest Is Nothing Then Exit Do
    MsgBox iMessageDest.Label + is removed from the queue."
  Loop

%>
</BODY>
</HTML>


Purging a Queue Asynchronously (COM)

When asynchronously retrieving messages from a queue, you must enable notification to read the first message, then re-enable notification after each message is read. The combination of how notification is enabled and how the message is retrieved determines when the arrived event is fired.

To asynchronously purge the messages from the queue, notification is enabled using the default cursor (Cursor = MQMSG_FIRST) setting. This setting causes an arrived event to be fired whenever there is a message in the first message location of the queue.

To purge the queue asynchronously

  1. Declare the objects needed to retrieve a message. This example declares an MSMQQueueInfo, MSMQQueue, MSMQMessage, and MSMQEvent object.
  2. Obtain a valid MSMQQueueInfo object. The MSMQQueueInfo object in the following code example is obtained by creating a new queue if an existing queue does not exist.
  3. Call MSMQQueueInfo.Open to open queue with receive access.
  4. Call MSMQQueue.EnableNotification to start notification. Note that the Cursor parameter for EnableNotification is not specified in the following code example.
  5. Write Arrived event handler. The event handler in the following code example calls MSMQQueue.Receive to remove the first message in the queue and then calls MSMQQueue.EnableNotification to re-enable notification without specifying its Cursor parameter.
  6. Write Arrived Error event handler.
For a code example using | See
Microsoft Visual Basic | Visual Basic Code Example


Visual Basic Code Example: Purging a Queue Asynchronously

The following example removes all the messages from a queue.

To try this example in Microsoft® Visual Basic® (version 5.0), paste the code into the Declaration section of a form, press F5, and click on the form.

Option Explicit
Dim qinfo As New MSMQQueueInfo
Dim q As MSMQQueue
Dim msg As New MSMQMessage
Dim WithEvents msgEvent As MSMQEvent

Private Sub Form_Click()
  '***********************************************************
  ' Create a destination queue, ignoring the error if the queue
  ' already exists.
  '***********************************************************
  qinfo.PathName = ".\testqueue"
  qinfo.Label = "Test Queue"
  On Error Resume Next          'Ignore if queue already exists.
  qinfo.Create
  On Error GoTo ErrorHandler    'Reset error handler.

  '***********************************************************
  ' Open the queue for retrieving messages and instantiate
  ' the MSMQEvent object.
  '***********************************************************
  Set q = qinfo.Open(MQ_RECEIVE_ACCESS, MQ_DENY_NONE)
  Set msgEvent = New MSMQEvent

  '***********************************************************
  ' Enable notification.
  '***********************************************************
  q.EnableNotification Event:=msgEvent, ReceiveTimeout:=1000
  Exit Sub

ErrorHandler:
MsgBox "Error opening queue or enabling notification." + _
       Chr(13) + Err.Description
End Sub

'*************************************************************
' Define the Arrived event handler.
'*************************************************************
Private Sub msgEvent_Arrived(ByVal queue As Object, _
                             ByVal Cursor As Long)
  On Error GoTo msgArrivedErrorHandler
  Set msg = q.Receive(ReceiveTimeout:=0)
  q.EnableNotification Event:=msgEvent, ReceiveTimeout:=10000
  Exit Sub

msgArrivedErrorHandler:
MsgBox Err.Description + " in Arrived event"
End Sub

'*************************************************************
' Define the Arrived Error event handler.
'*************************************************************
Private Sub msgEvent_ArrivedError(ByVal queue As Object, _
                                  ByVal ErrorCode As Long, _
                                  ByVal Cursor As Long)
  Select Case ErrorCode
    Case Is = -1072824292
    MsgBox "Error event fired! An illegal cursor movement was requested." + _
            Chr(13) + Chr(13) + "Error: " + Hex(ErrorCode)
    Case Is = -1072824293
    MsgBox "Error event fired! Time-out error returned after waiting for new messages." + _
            Chr(13) + Chr(13) + "Error: " + Hex(ErrorCode)
    Case Else
    MsgBox "Error event fired!" + Chr(13) + Chr(13) + _
           "Error: " + Hex(ErrorCode)
  End Select
End Sub


Requesting Journaling (COM)

Journaling can be requested both for queues (target journaling) and computers (source journaling).

The following examples show how to request queue and source journaling and how to read messages from the appropriate queue journal, computer journal, and dead-letter queue.

Note Applications cannot send messages to journal or dead-letter queues. When queue or source journaling is requested, Message Queuing sends a copy of message to the appropriate journal or dead-letter queue.

For an example of | See
Requesting target journaling when creating a queue | Requesting Target Journaling (COM)
Requesting source journaling when sending a message | Requesting Source Journaling (COM)
Reading messages from a queue journal | Reading Messages from a Queue Journal (COM)
Reading messages from a computer journal | Reading Messages from a Computer Journal (COM)
Reading messages from a dead-letter queue | Reading Messages from a Dead-Letter Queue (COM)


Requesting Target Journaling (COM)

Target journaling is requested by setting the journaling level (MSMQQueueInfo.Journal) of the queue. You can set the journaling level of the queue when you create the queue or later.

Note The following example sets the journaling level when creating a queue. To set the journaling level after the queue is created, use MSMQQueueInfo.Update.

To request target journaling

  1. Declare the MSMQQueueInfo variable for the queue.
  2. Create a new MSMQQueueInfo object and assign it to the variable.
  3. Specify the pathname of the queue. (In these examples, "." is used to indicate the local computer.)

    Note For Message Queuing servers and independent clients, the local machine is the local computer. However, for Message Queuing–dependent clients, the local machine is the client's Message Queuing server.

  4. Set MSMQQueueInfo.Journal to MQ_JOURNAL.
  5. Optional. Add any additional queue properties you need. The following example sets MSMQQueueInfo.JournalQuota to limit the size of the queue journal.
  6. Call MSMQQueueInfo.Create to create the queue.
For a code example using | See
Microsoft Visual Basic | Visual Basic Code Example


Visual Basic Code Example: Requesting Target Journaling

The following example requests target journaling while creating a public queue.

To try this example in Microsoft® Visual Basic® (version 5.0), paste the code into the Declaration section of a form, press F5, and click on the form.

Option Explicit
Dim qinfo As MSMQQueueInfo

Private Sub Form_Click()

  ' Create a new QueueInfo object.
  Set qinfo = New MSMQQueueInfo

  ' Set the pathname.
  qinfo.PathName = ".\TestQueue"

  ' Set journaling level of queue
  qinfo.Journal = MQ_JOURNAL

  ' Set additional optional properties
  qinfo.JournalQuota = 1000
  qinfo.Label = "Test Queue"

  ' Create the queue.
  On Error Resume Next
  qinfo.Create                  'Ignore error if queue already exists
  On Error GoTo 0               'Reset error handling
  MsgBox "Queue is created."

End Sub


Requesting Source Journaling (COM)

Source journaling is requested by setting the journaling property of a message to MQMSG_JOURNAL, MQMSG_DEADLETTER, or both.

To track messages that were successfully sent by the local computer, set the journaling property of the message to MQMSG_JOURNAL. This tells Message Queuing to always save a copy of each message that it successfully sent.

This means that when you send messages to remote computers, a copy of the message is placed in the source computer's journal queue if the message was sent successfully. Note that this does not mean the message has successfully reached its destination queue, only that the computer was able to send the message.

On the other hand, when you send messages to local queues, a copy of the message is saved to the computer's journal queue only after the message has been removed from the local destination queue.

Message Queuing never stores more than one copy of a message on a single computer at one time. Therefore, if the local destination queue has also enabled target journaling, a copy of the message is placed in that queue's journal when the message is removed from the queue; the message is not, however, saved to the computer's journal queue. If, on the other hand, the local destination queue has not enabled target journaling, a copy of the message is placed in the computer's journal when the message is removed from the destination queue.

To track messages that were not delivered, set the journaling property of the message to MQMSG_DEADLETTER. When you specify this type of source journaling, Message Queuing reacts differently depending on the type of message you send.

For non-transactional messages, a copy of the message is placed in the dead-letter queue of any computer that cannot deliver the message. This can be the source computer, or any routing server used to pass the message on to its destination.

For transactional messages, a copy of the message is placed in the transactional dead letter queue of the source computer only if Message Queuing does not confirm that the message was retrieved from its destination queue. Confirmation is not returned if the message is not delivered, was not received, or the receiving transaction was aborted. These messages may be used as a guaranteed negative acknowledgment.

Note For transactional messages, MSMQ 1.0 and MSMQ 2.0 act differently.

MSMQ 1.0 only allows you to choose if you want to save copies of messages sent successfully. MSMQ 1.0 always sends non-confirmed transactional message to the transactional dead-letter queue, regardless of whether MQMSG_DEADLETTER is or is not specified.

MSMQ 2.0 allows complete control over source journaling. (If you are running MSMQ 1.0 applications on an MSMQ 2.0 computer, you can force the computer to use the MSMQ 1.0 semantics by setting the XactDeadLetterAlways registry entry to 1.)

To request source journaling

The example code provided here sends a non-transactional message to a remote queue, setting the journaling property to MQMSG_JOURNAL, which means a copy of the message will be saved if the message is successfully sent.

  1. Declare the MSMQQueueInfo, MSMQQueue, and MSMQMessage variables for sending the message.
  2. Call MSMQQueueInfo.Open to open the destination queue with send access.
  3. Set MSMQMessage.Journal to MQMSG_JOURNAL. This example also sets the label of the message.
  4. Call MSMQMessage.Send to send the message.
  5. Call MSMQQueue.Close to close the queue.
For a code example using | See
Microsoft Visual Basic | Visual Basic Code Example


Visual Basic Code Example: Requesting Source Journaling

This example sends a message to a remote computer, requesting Message Queuing to keep a copy of the message if it is sent successfully.

To try this example in Microsoft® Visual Basic® (version 5.0), paste the code into the Declaration section of a form, press F5, and click on the form.

Option Explicit

Dim qinfo As New MSMQQueueInfo
Dim q As MSMQQueue
Dim m As New MSMQMessage

Private Sub Form_Click()

  ' Open queue with send access.
  qinfo.PathName = "remotecomputername\TestQueue"
  Set q = qinfo.Open(MQ_SEND_ACCESS, MQ_DENY_NONE)

  ' Set message properties.
  m.Journal = MQMSG_JOURNAL
  m.Label = "Test Message"

  ' Send message.
  m.Send q

  ' Close queue.
  q.Close

  MsgBox "The message was sent. Check journal queue for copy of message."

End Sub


Reading Messages from a Queue Journal (COM)

To read messages from a queue journal you must first obtain the format name of the destination queue it is associated with.

The format name of the destination queue is combined with the "JOURNAL keyword to create the format name of the queue journal. Here is the syntax of a queue journal for both a public and private destination queue.

PUBLIC=QueueGUID;JOURNAL
(where PUBLIC=QueueGUID is the format name of a public destination queue.)

PRIVATE=MachineGUID\QueueNumber;JOURNAL
(where PRIVATE=MachineGUID\QueueNumber is the format name of a private destination queue.)

To retrieve a message from a queue journal

  1. Declare the variables needed to retrieve the message.
  2. Obtain the MSMQQueueInfo and call MSMQQueueInfo.Refresh to update the local properties of the MSMQQueueInfo object.
  3. Construct the format name for the queue journal. The following example combines the format name of the destination queue (MSMQQueueInfo.FormatName) with ";JOURNAL".
  4. Call MSMQQueueInfo.Open to open the queue journal with receive access.
  5. Call MSMQQueue.Receive to retrieve the first message in the queue journal.
  6. Call MSMQQueue.Close to close the queue.
For a code example using | See
Microsoft Visual Basic | Visual Basic Code Example


Visual Basic Code Example: Reading Messages from a Queue Journal

This example retrieves the first message in a queue journal.

To try this example in Microsoft® Visual Basic® (version 5.0), paste the code into the Declaration section of a form, press F5, and click on the form.

Option Explicit

Dim qinfo As New MSMQQueueInfo
Dim qinfoJournal As New MSMQQueueInfo
Dim q As MSMQQueue
Dim m As MSMQMessage

Private Sub Form_Click()

  '***********************************************************
  ' Obtain MSMQQueueInfo object. MSMQQueueInfo.Refresh must
  ' be called to obtain registered format name of
  ' destination queue.
  '***********************************************************
  qinfo.PathName = ".\testqueue"
  qinfo.Refresh

  '***********************************************************
  ' Construct format name of queue journal.
  '***********************************************************
  qinfoJournal.FormatName = qinfo.FormatName + ";JOURNAL"

  '***********************************************************
  ' Open queue journal for retrieving messages.
  '***********************************************************
  Set q = qinfoJournal.Open(MQ_RECEIVE_ACCESS, MQ_DENY_NONE)

  '************************************************************
  ' Retrieve first messages from queue journal.
  '************************************************************
  Set m = q.Receive(ReceiveTimeout:=1000)
  If m Is Nothing Then
     q.Close
     Exit Sub
  End If

  MsgBox "The first message was removed from the queue journal."

  '************************************************************
  'Close queue journal.
  '************************************************************
  q.Close

End Sub


Reading Messages from a Computer Journal (COM)

To read messages from a computer journal you must first obtain the machine identifier (GUID) of the computer associated with the computer journal.

The machine identifier is combined with the "Machine" and "JOURNAL keywords to create the format name of the computer journal. Here is the syntax of format name for the computer journal.

Machine=MachineGUID;JOURNAL

To retrieve a message from a computer journal

  1. Declare the variables needed to retrieve the message.
  2. Call MSMQApplication.MachineIdOfMachineName to obtain the machine identifier.
  3. Construct the format name of the computer journal.
  4. Declare the variables needed to retrieve the message.
  5. Call MSMQQueueInfo.Open to open the computer journal with receive access.
  6. Call MSMQQueue.Receive to retrieve the first message in the computer journal.
  7. Call MSMQQueue.Close to close the computer journal.
For a code example using | See
Microsoft Visual Basic | Visual Basic Code Example


Visual Basic Code Example: Reading Messages from a Computer Journal

This example retrieves the first message in a computer journal.

To try this example in Microsoft® Visual Basic® (version 5.0), paste the code into the Declaration section of a form, press F5, and click on the form.

Option Explicit

Dim qinfoJournal As New MSMQQueueInfo
Dim q As MSMQQueue
Dim m As MSMQMessage
Dim strMachineId As String

Private Sub Form_Click()

  '***********************************************************
  ' Obtain machine GUID.
  '***********************************************************
  strMachineId = MachineIdOfMachineName("machinename")

  '***********************************************************
  ' Construct format name of queue journal.
  ' MSMQQueueInfo.Refresh must be called to obtain registered
  ' format name of destination queue.
  '***********************************************************
  qinfoJournal.FormatName = "MACHINE=" + strMachineId + ";JOURNAL"

  '***********************************************************
  ' Open queue journal for retrieving messages.
  '***********************************************************
  Set q = qinfoJournal.Open(MQ_RECEIVE_ACCESS, MQ_DENY_NONE)

  '************************************************************
  ' Retrieve first messages from queue journal.
  '************************************************************
  Set m = q.Receive(ReceiveTimeout:=1000)
  If m Is Nothing Then
     q.Close
     Exit Sub
  End If

  MsgBox "The first message was removed from the computer journal."

  '************************************************************
  'Close computer journal.
  '************************************************************
  q.Close

End Sub


Reading Messages from a Dead-Letter Queue (COM)

To read non-transactional messages from a dead-letter queue you must first obtain the machine identifier (GUID) of the computer associated with the DEADLETTER.

The machine identifier is combined with the "Machine" and "DEADLETTER" keywords to create the format name of the queue. Here is the syntax of format name for the dead-letter queue.

Machine=MachineGUID;DEADLETTER

To retrieve a message from a dead-letter queue

  1. Declare the variables needed to retrieve the message.
  2. Call MSMQApplication.MachineIdOfMachineName to obtain the machine identifier.
  3. Construct the format name of the dead-letter queue.
  4. Declare the variables needed to retrieve the message.
  5. Call MSMQQueueInfo.Open to open the queue with receive access.
  6. Call MSMQQueue.Receive to retrieve the first message in the queue.
  7. Call MSMQQueue.Close to close the dead-letter queue.
For a code example using | See
Microsoft Visual Basic | Visual Basic Code Example


Visual Basic Code Example: Reading Messages from a Dead-Letter Queue

This example retrieves the first message in a dead-letter queue.

To try this example in Microsoft® Visual Basic® (version 5.0), paste the code into the Declaration section of a form, press F5, and click on the form.

Option Explicit

Dim qinfoJournal As New MSMQQueueInfo
Dim q As MSMQQueue
Dim m As MSMQMessage
Dim strMachineId As String

Private Sub Form_Click()

  '***********************************************************
  ' Obtain machine GUID.
  '***********************************************************
  strMachineId = MachineIdOfMachineName("machinename")

  '***********************************************************
  ' Construct format name of dead-letter queue.
  ' MSMQQueueInfo.Refresh must be called to obtain registered
  ' format name of destination queue.
  '***********************************************************
  qinfoJournal.FormatName = "MACHINE=" + strMachineId + ";DEADLETTER"

  '***********************************************************
  ' Open queue for retrieving messages.
  '***********************************************************
  Set q = qinfoJournal.Open(MQ_RECEIVE_ACCESS, MQ_DENY_NONE)

  '************************************************************
  ' Retrieve first messages from the dead-letter queue.
  '************************************************************
  Set m = q.Receive(ReceiveTimeout:=1000)
  If m Is Nothing Then
     q.Close
     Exit Sub
  End If

  MsgBox "The first message was removed from the dead-letter queue."

  '************************************************************
  'Close dead-letter queue.
  '************************************************************
  q.Close

End Sub


Filtering Messages (COM)

Receiving applications can use any message property or combination of properties to filter out a set a messages from a queue. Filters can be constructed to remove the desired messages from the queue when they are found or leave them there.

The examples provided here show two general purpose message-property filters: one based on the application-specific information of a message and the other based on the message class. These examples could be easily modified to search for a specific message label, create time, or message identifier.

For an example based on | See
Application-specific information | Application-specific Filter (COM)
Message class | Message Class Filter (COM)


Application-Specific Filter (COM)

This filter retrieves all message with a specific value of application-specific information.

This filter removes messages from the queue. When a message with the desired application-specific information is found, MSMQQueue.ReceiveCurrent is called to remove the message, and MSMQQueue.PeekCurrent is called to look at the next message. When a message is removed from the queue, the cursor is automatically moved to the next message in the queue.

Note If you do not want to remove messages from the queue, use MSMQQueue.PeekCurrent to look at the current message, and use MSMQQueue.PeekNext to move the cursor and look at the next message.

To create an application-specific filter

  1. Declare the MSMQQueueInfo, MSMQQueue, and MSMQMessage object needed to create the filter.
  2. Call MSMQQueueInfo.Open to open the queue with receive access. Note receive access allows you to peek at and retrieve messages.
  3. Call MSMQQueue.PeekCurrent to peek at the first message in the queue. (You must point the cursor to the first message in the queue before using the cursor to navigate through the queue.
  4. Filter out the messages in the queue. Note that MSMQQueue.ReceiveCurrent and MSMQQueue.PeekCurrent are used if the message is removed, while MSMQQueue.PeekNext is used if the message is does not fit the search criteria.
  5. Call MSMQQueue.Close to close the queue.
For a code example using | See
Microsoft Visual Basic | Visual Basic Code Example


Visual Basic Code Example: Application-Specific Filter

The following example filters out all messages based on application-specific information. It opens a known queue that contains messages, and then navigates through the queue, removing all messages with an application-specific value of 4.

To try this example in Microsoft® Visual Basic® (version 5.0), paste the code into the Declaration section of a form, press F5, and click on the form.

Option Explicit

'*************************************************************
' Declare the required objects.
'*************************************************************
Dim qinfo As New MSMQQueueInfo
Dim qReceive As MSMQQueue
Dim mReceive As MSMQMessage

Private Sub Form_Click()

  '*************************************************************
  ' Open queue with RECEIVE access.
  '*************************************************************
  qinfo.PathName = ".\TestQueue"
  qinfo.Label = "Test Queue"
  On Error Resume Next          'Ignore if queue already exists.
  qinfo.Create
  On Error GoTo 0
  Set qReceive = qinfo.Open(MQ_RECEIVE_ACCESS, MQ_DENY_RECEIVE_SHARE)

  '*************************************************************
  ' Peek at the first message in the queue.
  '*************************************************************
  Set mReceive = qReceive.PeekCurrent(ReceiveTimeOut:=1000)

  '*************************************************************
  ' Filter messages based on value of application-specific
  ' information (in this case AppSpecfic = 4).
  '*************************************************************

  While Not mReceive Is Nothing
    If (mReceive.AppSpecific = 4) Then
       Set mReceive = qReceive.ReceiveCurrent(ReceiveTimeOut:=1000)
       MsgBox ("Message was retrieved from the queue")
       Set mReceive = qReceive.PeekCurrent(ReceiveTimeOut:=1000)
    Else
       Set mReceive = qReceive.PeekNext(ReceiveTimeOut:=1000)
    End If
  Wend

  '*************************************************************
  ' Close queue.
  '*************************************************************

  qReceive.Close

End Sub


Message Class Filter (COM)

This filter retrieves all message with a specific message class from a known administration queue.

This filter removes messages from the queue. When a message with the desired class is found, MSMQQueue.ReceiveCurrent is called to remove the message and MSMQQueue.PeekCurrent is called to look at the next message. When a message is removed from the queue, the cursor is automatically moved to the next message in the queue.

Note If you do not want to remove messages from the queue, use MSMQQueue.PeekCurrent to look at the current message, and use MSMQQueue.PeekNext to move the cursor and look at the next message.

To create a message class filter

  1. Declare the MSMQQueueInfo MSMQQueue, and MSMQMessage object needed to create the filter.
  2. Call MSMQQueueInfo.Open to open the queue with receive access. Note receive access allows you to peek at and retrieve messages.
  3. Call MSMQQueue.PeekCurrent to peek at the first message in the queue. (You must point the cursor to the first message in the queue before using the cursor to navigate through the queue.)
  4. Filter out the messages in the queue. Note that MSMQQueue.ReceiveCurrent and MSMQQueue.PeekCurrent are used if the message is removed, while MSMQQueue.PeekNext is used if the message is does not fit the search criteria.
  5. Call Close to close the queue.
For a code example using | See
Microsoft Visual Basic | Visual Basic Code Example


Visual Basic Code Example: Class Filter

The following example filters out all messages based on message class. It opens a known administration queue that contains acknowledgment messages returned by Message Queuing, then navigates through the queue, removing all messages with a negative receive class (the original messages were not retrieved from their queue before their time-to-be-received timer expired).

To try this example in Microsoft® Visual Basic® (version 5.0), paste the code into the Declaration section of a form, press F5, and click on the form.

Option Explicit

'*************************************************************
' Declare the required objects.
'*************************************************************
Dim qinfo As New MSMQQueueInfo
Dim qReceive As MSMQQueue
Dim mReceive As MSMQMessage

Private Sub Form_Click()

  '*************************************************************
  ' Open queue with RECEIVE access.
  '*************************************************************
  qinfo.PathName = ".\adminqueue"
  qinfo.Label = "Test Queue"
  On Error Resume Next          'Ignore if queue already exists.
  qinfo.Create
  On Error GoTo 0
  Set qReceive = qinfo.Open(MQ_RECEIVE_ACCESS, MQ_DENY_RECEIVE_SHARE)

  '*************************************************************
  ' Peek at the first message in the queue.
  '*************************************************************
  Set mReceive = qReceive.PeekCurrent(ReceiveTimeOut:=1000)

  '*************************************************************
  ' Filter messages based on the class of the message.
  '*************************************************************
  While Not mReceive Is Nothing
    If (mReceive.MsgClass = MQMSG_CLASS_NACK_RECEIVE_TIMEOUT) Then
       Set mReceive = qReceive.ReceiveCurrent(ReceiveTimeOut:=1000)
       MsgBox ("Negative receive message was retrieved from the queue.")
       Set mReceive = qReceive.PeekCurrent(ReceiveTimeOut:=1000)
    Else
       Set mReceive = qReceive.PeekNext(ReceiveTimeOut:=1000)
    End If

  Wend

  '*************************************************************
  ' Close queue.
  '*************************************************************
  qReceive.Close

End Sub


Retrieving Queue Properties (COM)

After a queue is created, the properties of the queue object can be retrieved at any time. However, these properties are only local properties of the registered properties.

For read-write properties such as MSMQQueueInfo.Label, call MSMQQueueInfo.Refresh (to retrieve the registered properties of the queue) if other applications may be changing the properties of the queue.

For read-only properties such as MSMQQueueInfo.FormatName, you must call MSMQQueueInfo.Refresh before the property can be retrieved. When Message Queuing sets a read-only property it sets the registered property, not the local property of the queue object.

Properties of public queues are register in the directory service. Properties of private queues are registered on the local machine. You can refresh the properties of private queues only if the queue is located on your local computer.

When MSMQQueueInfo.Refresh is called, it refreshes all the properties of the queue, not just those set by the application.

Note You can also retrieve the properties of public queues by doing a query on the directory service. For details, see Locating a Public Queue.

For an example of | See
Retrieving the authentication level of the queue | Retrieving MSMQQueueInfo.Authenticate
Retrieving the priority level of the queue | Retrieving MSMQQueueInfo.BasePriority
Retrieving the time the queue was created | Retrieving MSMQQueueInfo.CreateTime
Retrieving the format name of the queue | Retrieving MSMQQueueInfo.FormatName
Retrieving the transaction level of the queue | Retrieving MSMQQueueInfo.IsTransactional COM
Retrieving the read access level of the queue | Retrieving MSMQQueueInfo.IsWorldReadable
Retrieving the journaling level of the queue | Retrieving MSMQQueueInfo.Journal
Retrieving the maximum size of the queue journal | Retrieving MSMQQueueInfo.JournalQuota
Retrieving the label of the queue | Retrieving MSMQQueueInfo.Label
Retrieving the time the queue was last modified | Retrieving MSMQQueueInfo.ModifyTime
Retrieving the pathname of the queue | Retrieving MSMQQueueInfo.PathName
Retrieving the privacy level of the queue | Retrieving MSMQQueueInfo.PrivLevel
Retrieving the identifier of the queue | Retrieving MSMQQueueInfo.QueueGuid
Retrieving the maximum size of the queue | Retrieving MSMQQueueInfo.Quota
Retrieving the service type of the queue | Retrieving MSMQQueueInfo.ServiceTypeGuid


Retrieving MSMQQueueInfo.Authenticate

The authentication level of a queue (MSMQQueueInfo.Authenticate) determines whether the queue accepts only authenticated messages. By default, a queue accepts both authenticated and non-authenticated messages.

Note If your application does not have MQSEC_GET_QUEUE_PROPERTIES access rights for the queue, an MQ_ERROR_ACCESS_DENIED error is returned to MSMQQueueInfo.Refresh.

To retrieve MSMQQueueInfo.Authenticate

  1. Declare the MSMQQueueInfo variable for the queue.
  2. Obtain an MSMQQueueInfo object.
  3. Optional. Call MSMQQueueInfo.Refresh if other applications may have changed the authentication level of the queue.
  4. Use MSMQQueueInfo.Authenticate as needed. The following examples uses a Select Case statement to display the current setting.
For a code example using | See
Microsoft Visual Basic | Visual Basic Code Example


Visual Basic Code Example: Retrieving MSMQQueueInfo.Authenticate

This example retrieves the authentication level (MSMQQueueInfo.Authenticate) of a queue.

To try this example in Microsoft® Visual Basic® (version 5.0), paste the code into the Declaration section of a form, press F5, and click on the form.

Option Explicit
Dim qinfo As New MSMQQueueInfo

Private Sub Form_Click()

  '**********************************************************
  ' Obtain the MSMQQueueInfo object for the queue. (This
  ' example does so by trying to create the queue and
  ' ignoring errors if the queue already exists.)
  '**********************************************************
  qinfo.PathName = ".\TestQueue"
  On Error Resume Next
  qinfo.Create                  'Ignore error if queue already exists
  On Error GoTo 0               'Reset error handling

  '**********************************************************
  ' Refresh MSMQQueueInfo object with registered settings.
  '**********************************************************
  qinfo.Refresh                 'Retrieve registered property values

  Select Case qinfo.Authenticate
    Case MQ_AUTHENTICATE_NONE
      MsgBox "MSMQQueueInfo.Authenticate is set to MQ_AUTHETICATE_NONE."
    Case MQ_AUTHENTICATE
      MsgBox "MSMQQueueInfo.Authenticate is set to MQ_AUTHETICATE."
    Case Else
  End Select

End Sub


Retrieving MSMQQueueInfo.BasePriority

The priority level of a queue (MSMQQueueInfo.BasePriority) specifies a single base priority for all messages sent to a public queue. By default, the priority level of a queue is 0

Note If your application does not have MQSEC_GET_QUEUE_PROPERTIES access rights for the queue, an MQ_ERROR_ACCESS_DENIED error is returned to MSMQQueueInfo.Refresh.

To retrieve MSMQQueueInfo.BasePriority

  1. Declare the MSMQQueueInfo variable for the queue.
  2. Obtain an MSMQQueueInfo object.
  3. Optional. Call MSMQQueueInfo.Refresh if other applications may have changed the priority level of the queue.
  4. Use MSMQQueueInfo.BasePriority as needed. The following example converts the returned Long value to a String for display purposes.
For a code example using | See
Microsoft Visual Basic | Visual Basic Code Example


Visual Basic Code Example: Retrieving MSMQQueueInfo.BasePriority

This example retrieves the priority level (MSMQQueueInfo.BasePriority) of a queue.

To try this example in Microsoft® Visual Basic® (version 5.0), paste the code into the Declaration section of a form, press F5, and click on the form.

Option Explicit
Dim qinfo As New MSMQQueueInfo

Private Sub Form_Click()

  '**********************************************************
  ' Obtain the MSMQQueueInfo object for the queue. (This
  ' example does so by trying to create the queue and
  ' ignoring errors if the queue already exists.)
  '**********************************************************
  qinfo.PathName = ".\TestQueue"
  On Error Resume Next
  qinfo.Create                  'Ignore error if queue already exists
  On Error GoTo 0               'Reset error handling

  '**********************************************************
  ' Refresh MSMQQueueInfo object with registered settings.
  '**********************************************************
  qinfo.Refresh                 'Retrieve registered property values

  MsgBox "MSMQQueueInfo.BasePriority is set to: " + CStr(qinfo.BasePriority)

End Sub


Retrieving MSMQQueueInfo.CreateTime

The date and time when the queue was created (MSMQQueueInfo.CreateTime) are set by Message Queuing. You must call MSMQQueueInfo.Refresh before attempting to retrieve this property.

Note If your application does not have MQSEC_GET_QUEUE_PROPERTIES access rights for the queue, an MQ_ERROR_ACCESS_DENIED error is returned to MSMQQueueInfo.Refresh.

To retrieve MSMQQueueInfo.CreateTime

  1. Declare the MSMQQueueInfo variable for the queue.
  2. Obtain an MSMQQueueInfo object.
  3. Call MSMQQueueInfo.Refresh to update the local properties of the queue object. MSMQQueueInfo.CreateTime is a read-only property set when the queue is created.
  4. Use MSMQQueueInfo.CreateTime as needed. The following example converts the returned Date value to a String for display purposes.
For a code example using | See
Microsoft Visual Basic | Visual Basic Code Example


Visual Basic Code Example: Retrieving MSMQQueueInfo.CreateTime

This example retrieves the date and time when the queue was created (MSMQQueueInfo.CreateTime).

To try this example in Microsoft® Visual Basic® (version 5.0), paste the code into the Declaration section of a form, press F5, and click on the form.

Option Explicit
Dim qinfo As New MSMQQueueInfo

Private Sub Form_Click()

  '**********************************************************
  ' Obtain the MSMQQueueInfo object for the queue. (This
  ' example does so by trying to create the queue and
  ' ignoring errors if the queue already exists.)
  '**********************************************************
  qinfo.PathName = ".\TestQueue"
  On Error Resume Next
  qinfo.Create                  'Ignore error if queue already exists
  On Error GoTo 0               'Reset error handling

  '**********************************************************
  ' Refresh MSMQQueueInfo object with registered settings.
  '**********************************************************
  qinfo.Refresh                 'Retrieve registered property values

  MsgBox "MSMQQueueInfo.CreateTime is set to: " + CStr(qinfo.CreateTime)

End Sub


Retrieving MSMQQueueInfo.FormatName

The format name of the queue (MSMQQueueInfo.FormatName) is a string that is used to specify the queue.

Note If your application does not have MQSEC_GET_QUEUE_PROPERTIES access rights for the queue, an MQ_ERROR_ACCESS_DENIED error is returned to MSMQQueueInfo.Refresh.

To retrieve MSMQQueueInfo.FormatName

  1. Declare the MSMQQueueInfo variable for the queue.
  2. Obtain an MSMQQueueInfo object.
  3. Optional. Call MSMQQueueInfo.Refresh if other applications may have changed the format name of the queue.
  4. Use MSMQQueueInfo.FormatName as needed. The following example displays the returned values.
For a code example using | See
Microsoft Visual Basic | Visual Basic Code Example


Visual Basic Code Example: Retrieving MSMQQueueInfo.FormatName

This example retrieves the format name (MSMQQueueInfo.FormatName) of a queue.

To try this example in Microsoft® Visual Basic® (version 5.0), paste the code into the Declaration section of a form, press F5, and click on the form.

Option Explicit
Dim qinfo As New MSMQQueueInfo

Private Sub Form_Click()

  '**********************************************************
  ' Obtain the MSMQQueueInfo object for the queue. (This
  ' example does so by trying to create the queue and
  ' ignoring errors if the queue already exists.)
  '**********************************************************
  qinfo.PathName = ".\TestQueue"
  On Error Resume Next
  qinfo.Create                  'Ignore error if queue already exists
  On Error GoTo 0               'Reset error handling

  '**********************************************************
  ' Refresh MSMQQueueInfo object with registered settings.
  '**********************************************************
  qinfo.Refresh                 'Retrieve registered property values

  MsgBox "MSMQQueueInfo.FormatName is: " + qinfo.FormatName

End Sub


Retrieving MSMQQueueInfo.IsTransactional

The transaction level of a queue (MSMQQueueInfo.IsTransactional) indicates whether the queue accepts transactional or non-transactional messages. It is set when the queue is created. You must call MSMQQueueInfo.Refresh before attempting to retrieve this property.

Note If your application does not have MQSEC_GET_QUEUE_PROPERTIES access rights for the queue, an MQ_ERROR_ACCESS_DENIED error is returned to MSMQQueueInfo.Refresh.

To retrieve MSMQQueueInfo.IsTransactional

  1. Declare the MSMQQueueInfo variable for the queue.
  2. Obtain an MSMQQueueInfo object.
  3. Call MSMQQueueInfo.Refresh to update the local properties of the queue object. MSMQQueueInfo.IsTransactional is a read-only property set when the queue is created.
  4. Use MSMQQueueInfo.IsTransactional as needed. The following example displays the returned value.
For a code example using | See
Microsoft Visual Basic | Visual Basic Code Example


Visual Basic Code Example: Retrieving MSMQQueueInfo.IsTransactional

This example retrieves the transaction level (MSMQQueueInfo.IsTransactional) of a queue.

To try this example in Microsoft® Visual Basic® (version 5.0), paste the code into the Declaration section of a form, press F5, and click on the form.

Option Explicit
Dim qinfo As New MSMQQueueInfo

Private Sub Form_Click()

  '**********************************************************
  ' Obtain the MSMQQueueInfo object for the queue. (This
  ' example does so by trying to create the queue and
  ' ignoring errors if the queue already exists.)
  '**********************************************************
  qinfo.PathName = ".\TestQueue"
  On Error Resume Next
  qinfo.Create                  'Ignore error if queue already exists
  On Error GoTo 0               'Reset error handling

  '**********************************************************
  ' Refresh MSMQQueueInfo object with registered settings.
  '**********************************************************
  qinfo.Refresh                 'Retrieve registered property values

  If qinfo.IsTransactional = 1 Then
     MsgBox "The queue is transactional."
  Else
     MsgBox "The queue is not transactional."
  End If

End Sub


Retrieving MSMQQueueInfo.IsWorldreadable

The read access level of a queue (MSMQQueueInfo.IsWorldreadable) indicates who can read messages from the queue. It is set when the queue is created or whenever the access control of the queue is changed. You must call MSMQQueueInfo.Refresh before attempting to retrieve this property.

Note If your application does not have MQSEC_GET_QUEUE_PROPERTIES access rights for the queue, an MQ_ERROR_ACCESS_DENIED error is returned to MSMQQueueInfo.Refresh.

To retrieve MSMQQueueInfo.IsWorldReadable

  1. Declare the MSMQQueueInfo variable for the queue.
  2. Obtain an MSMQQueueInfo object.
  3. Call MSMQQueueInfo.Refresh to update the local properties of the queue object. MSMQQueueInfo.IsWorldReadable is a read-only property set when the queue is created or whenever the access control of the queue is changed.
  4. Use MSMQQueueInfo.IsWorldReadable as needed. The following example displays the returned value.
For a code example using | See
Microsoft Visual Basic | Visual Basic Code Example


Visual Basic Code Example: Retrieving MSMQQueueInfo.IsWorldReadable

This example retrieves the read access level (MSMQQueueInfo.IsWorldreadable) of a queue.

To try this example in Microsoft® Visual Basic® (version 5.0), paste the code into the Declaration section of a form, press F5, and click on the form.

Option Explicit
Dim qinfo As New MSMQQueueInfo

Private Sub Form_Click()

  '**********************************************************
  ' Obtain the MSMQQueueInfo object for the queue. (This
  ' example does so by trying to create the queue and
  ' ignoring errors if the queue already exists.)
  '**********************************************************
  qinfo.PathName = ".\TestQueue"
  On Error Resume Next
  qinfo.Create                  'Ignore error if queue already exists
  On Error GoTo 0               'Reset error handling

  '**********************************************************
  ' Refresh MSMQQueueInfo object with registered settings.
  '**********************************************************
  qinfo.Refresh                 'Retrieve registered property values

  If qinfo.IsWorldReadable = 1 Then
     MsgBox "The queue is world readable."
  Else
     MsgBox "The queue is not world readable."
  End If

End Sub


Retrieving MSMQQueueInfo.Journal

The journaling level of a queue (MSMQQueueInfo.Journal) specifies whether or not messages retrieved from the queue are stored in a queue journal. By default retrieved messages are not sent to the queue journal.

Note If your application does not have MQSEC_GET_QUEUE_PROPERTIES access rights for the queue, an MQ_ERROR_ACCESS_DENIED error is returned to MSMQQueueInfo.Refresh.

To retrieve MSMQQueueInfo.Journal

  1. Declare the MSMQQueueInfo variable for the queue.
  2. Obtain an MSMQQueueInfo object.
  3. Optional. Call MSMQQueueInfo.Refresh if other applications may have changed the journaling level of the queue.
  4. Use MSMQQueueInfo.Journal as needed. The following example uses a Select Case statement to display the returned value.
For a code example using | See
Microsoft Visual Basic | Visual Basic Code Example


Visual Basic Code Example: Retrieving MSMQQueueInfo.Journal

This example retrieves the journaling level (MSMQQueueInfo.Journal) of a queue.

To try this example in Microsoft® Visual Basic® (version 5.0), paste the code into the Declaration section of a form, press F5, and click on the form.

Option Explicit
Dim qinfo As New MSMQQueueInfo

Private Sub Form_Click()

  '**********************************************************
  ' Obtain the MSMQQueueInfo object for the queue. (This
  ' example does so by trying to create the queue and
  ' ignoring errors if the queue already exists.)
  '**********************************************************
  qinfo.PathName = ".\TestQueue"
  On Error Resume Next
  qinfo.Create                  'Ignore error if queue already exists
  On Error GoTo 0               'Reset error handling

  '**********************************************************
  ' Refresh MSMQQueueInfo object with registered settings.
  '**********************************************************
  qinfo.Refresh                 'Retrieve registered property values

  Select Case qinfo.Journal
    Case MQ_JOURNAL
      MsgBox "MSMQQueueInfo.Journal is set to MQ_JOURNAL."
    Case MQ_JOURNAL_NONE
      MsgBox "MSMQQueueInfo.Journal is set to MQ_JOURNAL_NONE."
    Case Else
  End Select

End Sub


Retrieving MSMQQueueInfo.JournalQuota

The journal quota (MSMQQueueInfo.JournalQuota) is the maximum size (in kilobytes) of the queue journal. By default the maximum size of the queue journal is INFINITE (as defined by Message Queuing).

Note If your application does not have MQSEC_GET_QUEUE_PROPERTIES access rights for the queue, an MQ_ERROR_ACCESS_DENIED error is returned to MSMQQueueInfo.Refresh.

To retrieve MSMQQueueInfo.JournalQuota

  1. Declare the MSMQQueueInfo variable for the queue.
  2. Obtain an MSMQQueueInfo object.
  3. Optional. Call MSMQQueueInfo.Refresh if other applications may have changed the journal quota of the queue journal.
  4. Use MSMQQueueInfo.JournalQuota as needed. The following example converts the returned Long to a String for display purposes.
For a code example using | See
Microsoft Visual Basic | Visual Basic Code Example


Visual Basic Code Example: Retrieving MSMQQueueInfo.JournalQuota

This example retrieves the maximum size (in kilobytes) of a queue journal (MSMQQueueInfo.JournalQuota).

To try this example in Microsoft® Visual Basic® (version 5.0), paste the code into the Declaration section of a form, press F5, and click on the form.

Option Explicit
Dim qinfo As New MSMQQueueInfo

Private Sub Form_Click()

  '**********************************************************
  ' Obtain the MSMQQueueInfo object for the queue. (This
  ' example does so by trying to create the queue and
  ' ignoring errors if the queue already exists.)
  '**********************************************************
  qinfo.PathName = ".\TestQueue"
  On Error Resume Next
  qinfo.Create                  'Ignore error if queue already exists
  On Error GoTo 0               'Reset error handling

  '**********************************************************
  ' Refresh MSMQQueueInfo object with registered settings.
  '**********************************************************
  qinfo.Refresh                 'Retrieve registered property values

  Select Case qinfo.JournalQuota
    Case -1
      MsgBox "MSMQQueueInfo.JournalQuota is set to INFINITE."
    Case Else
      MsgBox "MSMQQueueInfo.JournalQuota is set to: " + _
             CStr(qinfo.JournalQuota)
  End Select

End Sub


Retrieving MSMQQueueInfo.Label

The label of the queue (MSMQQueueInfo.Label) identifies the queue.

Note If your application does not have MQSEC_GET_QUEUE_PROPERTIES access rights for the queue, an MQ_ERROR_ACCESS_DENIED error is returned to MSMQQueueInfo.Refresh.

To retrieve MSMQQueueInfo.Label

  1. Declare the MSMQQueueInfo variable for the queue.
  2. Obtain an MSMQQueueInfo object.
  3. Optional. Call MSMQQueueInfo.Refresh if other applications may have changed the authentication level of the queue.
  4. Use MSMQQueueInfo.Label as needed. The following example displays the returned value.
For a code example using | See
Microsoft Visual Basic | Visual Basic Code Example


Visual Basic Code Example: Retrieving MSMQQueueInfo.Label

This example retrieves the label (MSMQQueueInfo.Label) of a queue.

To try this example in Microsoft® Visual Basic® (version 5.0), paste the code into the Declaration section of a form, press F5, and click on the form.

Option Explicit
Dim qinfo As New MSMQQueueInfo

Private Sub Form_Click()

  '**********************************************************
  ' Obtain the MSMQQueueInfo object for the queue. (This
  ' example does so by trying to create the queue and
  ' ignoring errors if the queue already exists.)
  '**********************************************************
  qinfo.PathName = ".\TestQueue"
  On Error Resume Next
  qinfo.Create                  'Ignore error if queue already exists
  On Error GoTo 0               'Reset error handling

  '**********************************************************
  ' Refresh MSMQQueueInfo object with registered settings.
  '**********************************************************
  qinfo.Refresh                 'Retrieve registered property values

  MsgBox "MSMQQueueInfo.Label is: " + qinfo.Label

End Sub


Retrieving MSMQQueueInfo.ModifyTime

The date and time when the queue was last modified (MSMQQueueInfo.ModifyTime) is set by Message Queuing. You must call MSMQQueueInfo.Refresh before attempting to retrieve this property.

Note If your application does not have MQSEC_GET_QUEUE_PROPERTIES access rights for the queue, an MQ_ERROR_ACCESS_DENIED error is returned to MSMQQueueInfo.Refresh.

To retrieve MSMQQueueInfo.ModifyTime

  1. Declare the MSMQQueueInfo variable for the queue.
  2. Obtain an MSMQQueueInfo object.
  3. Call MSMQQueueInfo.Refresh to update the local properties of the queue object. MSMQQueueInfo.ModifyTime is a read-only property set when the properties of the queue are changed.
  4. Use MSMQQueueInfo.ModifyTime as needed. The following example converts the returned Date value to a String for display purposes.
For a code example using | See
Microsoft Visual Basic | Visual Basic Code Example


Visual Basic Code Example: Retrieving MSMQQueueInfo.ModifyTime

This example retrieves the date and time when the queue was last modified (MSMQQueueInfo.ModifyTime).

To try this example in Microsoft® Visual Basic® (version 5.0), paste the code into the Declaration section of a form, press F5, and click on the form.

Option Explicit
Dim qinfo As New MSMQQueueInfo

Private Sub Form_Click()

  '**********************************************************
  ' Obtain the MSMQQueueInfo object for the queue. (This
  ' example does so by trying to create the queue and
  ' ignoring errors if the queue already exists.)
  '**********************************************************
  qinfo.PathName = ".\TestQueue"
  On Error Resume Next
  qinfo.Create                  'Ignore error if queue already exists
  On Error GoTo 0               'Reset error handling

  '**********************************************************
  ' Refresh MSMQQueueInfo object with registered settings.
  '**********************************************************
  qinfo.Refresh                 'Retrieve registered property values

  MsgBox "MSMQQueueInfo.ModifyTime is set to: " + CStr(qinfo.ModifyTime)

End Sub


Retrieving MSMQQueueInfo.PathName

The pathname of the queue (MSMQQueueInfo.PathName) indicates the machine where the queue resides and the name of the queue.

Note If your application does not have MQSEC_GET_QUEUE_PROPERTIES access rights for the queue, an MQ_ERROR_ACCESS_DENIED error is returned to MSMQQueueInfo.Refresh.

To retrieve MSMQQueueInfo.PathName

  1. Declare the MSMQQueueInfo variable for the queue.
  2. Obtain an MSMQQueueInfo object.
  3. Optional. Call MSMQQueueInfo.Refresh if other applications may have changed the pathname of the queue.
  4. Use MSMQQueueInfo.PathName as needed. The following example displays the returned value.
For a code example using | See
Microsoft Visual Basic | Visual Basic Code Example


Visual Basic Code Example: Retrieving MSMQQueueInfo.PathName

This example retrieves the pathname (MSMQQueueInfo.PathName) of a queue.

To try this example in Microsoft® Visual Basic® (version 5.0), paste the code into the Declaration section of a form, press F5, and click on the form.

Option Explicit
Dim qinfo As New MSMQQueueInfo

Private Sub Form_Click()

  '**********************************************************
  ' Obtain the MSMQQueueInfo object for the queue. (This
  ' example does so by trying to create the queue and
  ' ignoring errors if the queue already exists.)
  '**********************************************************
  qinfo.PathName = ".\TestQueue"
  On Error Resume Next
  qinfo.Create                  'Ignore error if queue already exists
  On Error GoTo 0               'Reset error handling

  '**********************************************************
  ' Refresh MSMQQueueInfo object with registered settings.
  '**********************************************************
  qinfo.Refresh                 'Retrieve registered property values

  MsgBox "MSMQQueueInfo.PathName is: " + qinfo.PathName

End Sub


Retrieving MSMQQueueInfo.PrivLevel

The privacy level of a queue (MSMQQueueInfo.PrivLevel) specifies whether the queue accepts private (encrypted) messages, non-private messages, or both.

By default a queue accepts both private and non-private messages.

Note If your application does not have MQSEC_GET_QUEUE_PROPERTIES access rights for the queue, an MQ_ERROR_ACCESS_DENIED error is returned to MSMQQueueInfo.Refresh.

To retrieve MSMQQueueInfo.PrivLevel

  1. Declare the MSMQQueueInfo variable for the queue.
  2. Obtain an MSMQQueueInfo object.
  3. Optional. Call MSMQQueueInfo.Refresh if other applications may have changed the privacy level of the queue.
  4. Use MSMQQueueInfo.PrivLevel as needed. The following example converts the returned Long to a String for display purposes.
For a code example using | See
Microsoft Visual Basic | Visual Basic Code Example


Visual Basic Code Example: Retrieving MSMQQueueInfo.PrivLevel

This example retrieves the privacy level (MSMQQueueInfo.PrivLevel) of a queue.

To try this example in Microsoft® Visual Basic® (version 5.0), paste the code into the Declaration section of a form, press F5, and click on the form.

Option Explicit
Dim qinfo As New MSMQQueueInfo

Private Sub Form_Click()

  '**********************************************************
  ' Obtain the MSMQQueueInfo object for the queue. (This
  ' example does so by trying to create the queue and
  ' ignoring errors if the queue already exists.)
  '**********************************************************
  qinfo.PathName = ".\TestQueue"
  On Error Resume Next
  qinfo.Create                  'Ignore error if queue already exists
  On Error GoTo 0               'Reset error handling

  '**********************************************************
  ' Refresh MSMQQueueInfo object with registered settings.
  '**********************************************************
  qinfo.Refresh                 'Retrieve registered property values

  Select Case qinfo.PrivLevel
    Case MQ_PRIV_LEVEL_NONE
      MsgBox "MSMQQueueInfo.PrivLevel is set to MQ_PRIV_LEVEL_NONE."
    Case MQ_PRIV_LEVEL_BODY
      MsgBox "MSMQQueueInfo.PrivLevel is set to MQ_PRIV_LEVEL_BODY."
    Case MQ_PRIV_LEVEL_OPTIONAL
      MsgBox "MSMQQueueInfo.PrivLevel is set to MQ_PRIV_LEVEL_OPTIONAL."
    Case Else
  End Select

End Sub


Retrieving MSMQQueueInfo.QueueGuid

The identifier of the queue (MSMQQueueInfo.QueueGuid) is a GUID that uniquely identifies the queue. MSMQQueueInfo.QueueGuid is a read-only property that is set by Message Queuing when the queue is created. You must call MSMQQueueInfo.Refresh before attempting to retrieve this property.

Note If your application does not have MQSEC_GET_QUEUE_PROPERTIES access rights for the queue, an MQ_ERROR_ACCESS_DENIED error is returned to MSMQQueueInfo.Refresh.

To retrieve MSMQQueueInfo.QueueGuid

  1. Declare the MSMQQueueInfo variable for the queue.
  2. Obtain an MSMQQueueInfo object.
  3. Call MSMQQueueInfo.Refresh to update the local properties of the queue object. MSMQQueueInfo.QueueGuid is a read-only property set when the queue is created
  4. Use MSMQQueueInfo.QueueGuid as needed. The following example converts the returned GUID to a String for display purposes.
For a code example using | See
Microsoft Visual Basic | Visual Basic Code Example


Visual Basic Code Example: Retrieving MSMQQueueInfo.QueueGuid

This example retrieves the identifier (MSMQQueueInfo.QueueGuid) of a queue and converts it to a string.

To try this example in Microsoft® Visual Basic® (version 5.0), paste the code into the Declaration section of a form, press F5, and click on the form.

Option Explicit
Dim qinfo As New MSMQQueueInfo

Private Sub Form_Click()

  '**********************************************************
  ' Obtain the MSMQQueueInfo object for the queue. (This
  ' example does so by trying to create the queue and
  ' ignoring errors if the queue already exists.)
  '**********************************************************
  qinfo.PathName = ".\TestQueue"
  On Error Resume Next
  qinfo.Create                  'Ignore error if queue already exists
  On Error GoTo 0               'Reset error handling

  '**********************************************************
  ' Refresh MSMQQueueInfo object with registered settings.
  '**********************************************************
  qinfo.Refresh                 'Retrieve registered property values

 MsgBox "MSMQQueueInfo.QueueGuid is: " + CStr(qinfo.QueueGuid)

End Sub


Retrieving MSMQQueueInfo.Quota

The quota (MSMQQueueInfo.Quota) is the maximum size (in kilobytes) of the queue. By default the maximum size of the queue is INFINITE (as defined by Message Queuing).

Note If your application does not have MQSEC_GET_QUEUE_PROPERTIES access rights for the queue, an MQ_ERROR_ACCESS_DENIED error is returned to MSMQQueueInfo.Refresh.

To retrieve MSMQQueueInfo.Quota

  1. Declare the MSMQQueueInfo variable for the queue.
  2. Obtain an MSMQQueueInfo object.
  3. Optional. Call MSMQQueueInfo.Refresh if other applications may have changed the quota of the queue.
  4. Use MSMQQueueInfo.Quota as needed. The following example converts the returned Long to a String for display purposes.
For a code example using | See
Microsoft Visual Basic | Visual Basic Code Example


Visual Basic Code Example: Retrieving MSMQQueueInfo.Quota

This example retrieves the maximum size (MSMQQueueInfo.Quota) of a queue.

To try this example in Microsoft® Visual Basic® (version 5.0), paste the code into the Declaration section of a form, press F5, and click on the form.

Option Explicit
Dim qinfo As New MSMQQueueInfo

Private Sub Form_Click()

  '**********************************************************
  ' Obtain the MSMQQueueInfo object for the queue. (This
  ' example does so by trying to create the queue and
  ' ignoring errors if the queue already exists.)
  '**********************************************************
  qinfo.PathName = ".\TestQueue"
  On Error Resume Next
  qinfo.Create                  'Ignore error if queue already exists
  On Error GoTo 0               'Reset error handling

  '**********************************************************
  ' Refresh MSMQQueueInfo object with registered settings.
  '**********************************************************
  qinfo.Refresh                 'Retrieve registered property values

  Select Case qinfo.Quota
    Case -1
      MsgBox "MSMQQueueInfo.Quota is set to INFINITE."
    Case Else
      MsgBox "MSMQQueueInfo.Quota is set to: " + _
             CStr(qinfo.Quota)
  End Select

End Sub


Retrieving MSMQQueueInfo.ServiceTypeGuid

The service type of the queue (MSMQQueueInfo.ServiceTypeGuid) is a GUID that identifies the type of queue. Service type can be set by applications or by Message Queuing.

Note If your application does not have MQSEC_GET_QUEUE_PROPERTIES access rights for the queue, an MQ_ERROR_ACCESS_DENIED error is returned to MSMQQueueInfo.Refresh.

To retrieve MSMQQueueInfo.ServiceTypeGuid

  1. Declare the MSMQQueueInfo variable for the queue.
  2. Obtain an MSMQQueueInfo object.
  3. Optional. Call MSMQQueueInfo.Refresh to update the local properties of the queue object if another application may have changed the service type of the queue.
  4. Use MSMQQueueInfo.ServiceTypeGuid as needed. The following example converts the returned GUID to a String for display purposes.
For a code example using | See
Microsoft Visual Basic | Visual Basic Code Example


Visual Basic Code Example: Retrieving MSMQQueueInfo.ServiceTypeGuid

This example retrieves the service type (MSMQQueueInfo.ServiceTypeGuid) of the queue and converts it to a string.

To try this example in Microsoft® Visual Basic® (version 5.0), paste the code into the Declaration section of a form, press F5, and click on the form.

Option Explicit
Dim qinfo As New MSMQQueueInfo

Private Sub Form_Click()

  '**********************************************************
  ' Obtain the MSMQQueueInfo object for the queue. (This
  ' example does so by trying to create the queue and
  ' ignoring errors if the queue already exists.)
  '**********************************************************
  qinfo.PathName = ".\TestQueue"
  On Error Resume Next
  qinfo.Create                  'Ignore error if queue already exists
  On Error GoTo 0               'Reset error handling

  '**********************************************************
  ' Refresh MSMQQueueInfo object with registered settings.
  '**********************************************************
  qinfo.Refresh                 'Retrieve registered property values

 MsgBox "MSMQQueueInfo.ServiceTypeGuid is: " +
         _CStr(qinfo.ServiceTypeGuid)

End Sub


Setting Queue Properties (COM)

The properties of a queue can be dynamically set by calling MSMQQueueInfo.Update.

Note MSMQQueueInfo.Update can only be called on queues that exist. It cannot be called on an MSMQQueueInfo object before the queue is created or after the queue is deleted.

When updating public queues, the directory service is updated with the current settings of the MSMQQueueInfo object. Always call MSMQQueueInfo.Refresh first to retrieve the existing settings of the queue. This will retrieve any changes that have been made using Active Directory or another application.

When updating private queues, the local computer is updated with the current settings of the MSMQQueueInfo object. Properties for private queues can only be updated if the queue is located on the local computer.

In most cases, any application can set a queue's properties. However, if MQ_ERROR_ACCESS_DENIED is returned by MSMQQueueInfo.Update, the access control level of the queue is blocking the application from setting the queue's properties. For information about access rights, see Access Control.

Note Not all properties can be set by calling MSMQQueueInfo.Update. Only the properties in the following examples can be set in this way. Other properties can only be set by Message Queuing, or they can only be set when the queue is created.

For an example of | See
Setting the authentication level of the queue | Setting MSMQQueueInfo.Authenticate
Setting the base priority level of the queue | Setting MSMQQueueInfo.BasePriority
Setting the journaling level of the queue | Setting MSMQQueueInfo.Journal
Setting the maximum size of the queue journal | Setting MSMQQueueInfo.JournalQuota
Setting the label of the queue | Setting MSMQQueueInfo.Label
Setting the privacy level of the queue | Setting MSMQQueueInfo.PrivLevel
Setting the maximum size of the queue | Setting MSMQQueueInfo.Quota
Setting the type of service performed by the queue | Setting MSMQQueueInfo.ServiceTypeGuid


Setting MSMQQueueInfo.Authenticate

The authentication level of the queue (MSMQQueueInfo.Authenticate) specifies whether the queue accepts only authenticated messages. By default, a queue accepts both authenticated and non-authenticated messages.

To change the authentication level of a queue

  1. Declare an MSMQQueueInfo object.
  2. Call MSMQQueueInfo.Refresh to retrieve the registered properties of the queue.
  3. Set MSMQQueueInfo.Authenticate to the new authentication level.
  4. Call MSMQQueueInfo.Update to change the authentication level of the queue.
For a code example using | See
Microsoft Visual Basic | Visual Basic Code Example


Visual Basic Code Example: Setting MSMQQueueInfo.Authenticate

This example changes the authentication level (MSMQQueueInfo.Authenticate) of a known queue, creating a new queue if the old queue no longer exists.

To try this example in Microsoft® Visual Basic® (version 5.0), paste the code into the Declaration section of a form that has a single text box, press F5, and click on the form.

Option Explicit
Dim qinfo As New MSMQQueueInfo

Private Sub Form_Click()

  '**********************************************************
  ' Obtain the MSMQQueueInfo object for the queue. (This
  ' example does so by trying to create the queue and
  ' ignoring errors if the queue already exists.)
  '**********************************************************
  qinfo.PathName = ".\TestQueue"
  On Error Resume Next
  qinfo.Create                  'Ignore error if queue already exists
  On Error GoTo 0               'Reset error handling
  qinfo.Refresh                 'Retrieve registered property values

  '**********************************************************
  ' Specify authentication level.
  '**********************************************************
  qinfo.Authenticate = MQ_AUTHENTICATE

  '**********************************************************
  ' Update MSMQQueueInfo object.
  '**********************************************************
  qinfo.Update                  'Store changed property values

  MsgBox ("The queue now accepts only authenticated messages.")

End Sub


Setting MSMQQueueInfo.BasePriority

The priority level of a queue (MSMQQueueInfo.BasePriority) specifies a single base priority for all messages sent to a public queue. By default, the priority level of a queue is 0.

To change the priority level of a queue

  1. Declare an MSMQQueueInfo object.
  2. Call MSMQQueueInfo.Refresh to retrieve the existing properties of the queue.
  3. Set MSMQQueueInfo.BasePriority to the new priority level.
  4. Call MSMQQueueInfo.Update to change the priority level of the queue.
For a code example using | See
Microsoft Visual Basic | Visual Basic Code Example


Visual Basic Code Example: Setting MSMQQueueInfo.Authenticate

Platform SDK: Message Queuing

Visual Basic Code Example: Setting MSMQQueueInfo.BasePriority

This example changes the priority level (MSMQQueueInfo.BasePriority) of a known queue, creating a new queue if the old queue no longer exists.

To try this example in Microsoft® Visual Basic® (version 5.0), paste the code into the Declaration section of a form that has a single text box, press F5, and click on the form.

Option Explicit
Dim qinfo As New MSMQQueueInfo

Private Sub Form_Click()

  '**********************************************************
  ' Obtain the MSMQQueueInfo object for the queue. (This
  ' example does so by trying to create the queue and
  ' ignoring errors if the queue already exists.)
  '**********************************************************
  qinfo.PathName = ".\TestQueue"
  On Error Resume Next
  qinfo.Create                  'Ignore error if queue already exists
  On Error GoTo 0               'Reset error handling
  qinfo.Refresh                 'Retrieve registered property values

  '**********************************************************
  ' Specify priority level of queue.
  '**********************************************************
  qinfo.BasePriority = 7

  '**********************************************************
  ' Update MSMQQueueInfo object.
  '**********************************************************
  qinfo.Update                  'Store changed property values

  MsgBox ("The base priority of the queue is now: " + CStr(qinfo.BasePriority))

End Sub


Setting MSMQQueueInfo.Journal

The journaling level of the queue (MSMQQueueInfo.Journal) specifies whether messages retrieved from the queue are also copied to the queue's queue journal. By default, messages are not copied to the queue journal.

To change the journaling level of a queue

  1. Declare an MSMQQueueInfo object.
  2. Call MSMQQueueInfo.Refresh to retrieve the existing properties of the queue.
  3. Set MSMQQueueInfo.Journal to the new journaling level.
  4. Call MSMQQueueInfo.Update to change the journaling level of the queue.
For a code example using | See
Microsoft Visual Basic | Visual Basic Code Example


Visual Basic Code Example: Setting MSMQQueueInfo.Journal

This example changes the journaling level (MSMQQueueInfo.Journal) of a known queue, creating a new queue if the old queue no longer exists.

To try this example in Microsoft® Visual Basic® (version 5.0), paste the code into the Declaration section of a form that has a single text box, press F5, and click on the form.

Option Explicit
Dim qinfo As New MSMQQueueInfo

Private Sub Form_Click()

  '**********************************************************
  ' Obtain the MSMQQueueInfo object for the queue. (This
  ' example does so by trying to create the queue and
  ' ignoring errors if the queue already exists.)
  '**********************************************************
  qinfo.PathName = ".\TestQueue"
  On Error Resume Next
  qinfo.Create                  'Ignore error if queue already exists
  On Error GoTo 0               'Reset error handling
  qinfo.Refresh                 'Retrieve registered property values

  '**********************************************************
  ' Specify journaling level of queue.
  '**********************************************************
  qinfo.Journal = MQ_JOURNAL

  '**********************************************************
  ' Update MSMQQueueInfo object.
  '**********************************************************
  qinfo.Update                  'Store changed property values

 MsgBox ("Messages retrieved from the queue are now stored in the queue journal.")

End Sub


Setting MSMQQueueInfo.JournalQuota

The queue journal's quota (MSMQQueueInfo.JournalQuota) is the maximum size of the queue journal. By default, a queue journal's maximum size is set to INFINITE.

To change the size of the queue journal

  1. Declare an MSMQQueueInfo object.
  2. Call MSMQQueueInfo.Refresh to retrieve the existing properties of the queue.
  3. Set MSMQQueueInfo.JournalQuota to the new maximum size (in kilobytes).
  4. Call MSMQQueueInfo.Update to change the size of the queue.
For a code example using | See
Microsoft Visual Basic | Visual Basic Code Example


Visual Basic Code Example: Setting MSMQQueueInfo.JournalQuota

This example changes the maximum size of the queue journal (MSMQQueueInfo.JournalQuota) of a known destination queue, creating a new destination queue if the old queue no longer exists.

To try this example in Microsoft® Visual Basic® (version 5.0), paste the code into the Declaration section of a form that has a single text box, press F5, and click on the form.

Option Explicit
Dim qinfo As New MSMQQueueInfo

Private Sub Form_Click()

  '**********************************************************
  ' Obtain the MSMQQueueInfo object for the queue. (This
  ' example does so by trying to create the queue and
  ' ignoring errors if the queue already exists.)
  '**********************************************************
  qinfo.PathName = ".\TestQueue"
  On Error Resume Next
  qinfo.Create                  'Ignore error if queue already exists
  On Error GoTo 0               'Reset error handling
  qinfo.Refresh                 'Retrieve registered property values

  '**********************************************************
  ' Specify maximum size of the queue journal (in kilobytes).
  '**********************************************************
  qinfo.JournalQuota = 10

  '**********************************************************
  ' Update MSMQQueueInfo object.
  '**********************************************************
  qinfo.Update                  'Store changed property values

  MsgBox ("The maximum size of the queue journal is now 10 KB.")

End Sub


Setting MSMQQueueInfo.Label

The label of a queue (MSMQQueueInfo.Label) provides a description of the queue.

To change the label of a queue

  1. Declare an MSMQQueueInfo object.
  2. Call MSMQQueueInfo.Refresh to retrieve the existing properties of the queue.
  3. Set MSMQQueueInfo.Label to the new label.
  4. Call MSMQQueueInfo.Update to change the label of the queue.
For a code example using | See
Microsoft Visual Basic | Visual Basic Code Example


Visual Basic Code Example: Setting MSMQQueueInfo.Label

This example changes the label (MSMQQueueInfo.Label) of a known queue, creating a new queue if the old queue no longer exists.

To try this example in Microsoft® Visual Basic® (version 5.0), paste the code into the Declaration section of a form that has a single text box, press F5, and click on the form.

Option Explicit
Dim qinfo As New MSMQQueueInfo

Private Sub Form_Click()

  '**********************************************************
  ' Obtain the MSMQQueueInfo object for the queue. (This
  ' example does so by trying to create the queue and
  ' ignoring errors if the queue already exists.)
  '**********************************************************
  qinfo.PathName = ".\TestQueue"
  On Error Resume Next
  qinfo.Create                  'Ignore error if queue already exists
  On Error GoTo 0               'Reset error handling
  qinfo.Refresh                 'Retrieve registered property values

  '**********************************************************
  ' Specify the new label.
  '**********************************************************
  qinfo.Label = "New Label"

  '**********************************************************
  ' Update MSMQQueueInfo object.
  '**********************************************************
  qinfo.Update                  'Store changed property values

  MsgBox "The queue's new label is: " + qinfo.Label

End Sub


Setting MSMQQueueInfo.PrivLevel

The privacy level (MSMQQueueInfo.PrivLevel) of the queue specifies how the queue handles private (encrypted) messages. By default, a queue can accept private or non-private messages.

To change the privacy level of a queue

  1. Declare an MSMQQueueInfo object.
  2. Call MSMQQueueInfo.Refresh to retrieve the existing properties of the queue.
  3. Set MSMQQueueInfo.PrivLevel to the new privacy level.
  4. Call MSMQQueueInfo.Update to change the privacy level of the queue.
For a code example using | See
Microsoft Visual Basic | Visual Basic Code Example


Visual Basic Code Example: Setting MSMQQueueInfo.PrivLevel

Platform SDK: Message Queuing

Visual B Code Example: Setting MSMQQueueInfo.PrivLevel

This example changes the privacy level (MSMQQueueInfo.PrivLevel) of a known queue, creating a new queue if the old queue no longer exists.

To try this example in Microsoft® Visual Basic® (version 5.0), paste the code into the Declaration section of a form that has a single text box, press F5, and click on the form.

Private Sub Form_Click()

  '**********************************************************
  ' Obtain the MSMQQueueInfo object for the queue. (This
  ' example does so by trying to create the queue and
  ' ignoring errors if the queue already exists.)
  '**********************************************************
  qinfo.PathName = ".\TestQueue"
  On Error Resume Next
  qinfo.Create                  'Ignore error if queue already exists
  On Error GoTo 0               'Reset error handling
  qinfo.Refresh                 'Retrieve registered property values

  '**********************************************************
  ' Specify the new privacy level.
  '**********************************************************
    qinfo.PrivLevel = MQ_PRIV_LEVEL_BODY

  '**********************************************************
  ' Update MSMQQueueInfo object.
  '**********************************************************
  qinfo.Update                  'Store changed property values

  MsgBox ("The queue now accepts only encrypted messages.")

End Sub


Setting MSMQQueueInfo.Quota

The quota (MSMQQueueInfo.Quota) of the queue is the maximum size of the queue. By default, a queue's maximum size is set to INFINITE.

To change the maximum size of a queue

  1. Declare an MSMQQueueInfo object.
  2. Call MSMQQueueInfo.Refresh to retrieve the existing properties of the queue.
  3. Set MSMQQueueInfo.Quota to the new maximum size for the queue.
  4. Call MSMQQueueInfo.Update to change the maximum size of the queue.
For a code example using | See
Microsoft Visual Basic | Visual Basic Code Example


Visual Basic Code Example: Setting MSMQQueueInfo.Quota

This example changes the maximum size (MSMQQueueInfo.Quota) of a known queue, creating a new queue if the old queue no longer exists.

To try this example in Microsoft® Visual Basic® (version 5.0), paste the code into the Declaration section of a form that has a single text box, press F5, and click on the form.

Option Explicit
Dim qinfo As New MSMQQueueInfo

Private Sub Form_Click()

  '**********************************************************
  ' Obtain the MSMQQueueInfo object for the queue. (This
  ' example does so by trying to create the queue and
  ' ignoring errors if the queue already exists.)
  '**********************************************************
  qinfo.PathName = ".\TestQueue"
  On Error Resume Next
  qinfo.Create                  'Ignore error if queue already exists
  On Error GoTo 0               'Reset error handling
  qinfo.Refresh                 'Retrieve registered property values

  '**********************************************************
  ' Specify maximum size of the queue (in kilobytes).
  '**********************************************************
  qinfo.Quota = 10

  '**********************************************************
  ' Update MSMQQueueInfo object.
  '**********************************************************
  qinfo.Update                  'Store changed property values

  MsgBox ("The maximum size of the queue is now 10 KB.")

End Sub


Setting MSMQQueueInfo.ServiceTypeGuid

The queue's type (MSMQQueueInfo.ServiceTypeGuid) identifies the type of service provided by the queue. Some queue types are defined by Message Queuing. However, applications can define their own queue types so that they can later locate a set of queues by the type of service the queue provides.

To change the queue type

  1. Declare an MSMQQueueInfo object.
  2. Call MSMQQueueInfo.Refresh to retrieve the existing properties of the queue.
  3. Set MSMQQueueInfo.ServiceTypeGuid to the new type identifier (GUID).
  4. Call MSMQQueueInfo.Update to change the queue type identifier.
For a code example using | See
Microsoft Visual Basic | Visual Basic Code Example


Visual Basic Code Example: Setting MSMQQueueInfo.ServiceTypeGuid

This example changes the type identifier (MSMQQueueInfo.ServiceTypeGuid) of a known queue, creating a new queue if the old queue no longer exists.

To try this example in Microsoft® Visual Basic® (version 5.0), paste the code into the Declaration section of a form that has a single text box, press F5, and click on the form.

Option Explicit
Dim qinfo As New MSMQQueueInfo

Private Sub Form_Click()

  '**********************************************************
  ' Obtain the MSMQQueueInfo object for the queue. (This
  ' example does so by trying to create the queue and
  ' ignoring errors if the queue already exists.)
  '**********************************************************
  qinfo.PathName = ".\TestQueue"
  On Error Resume Next
  qinfo.Create                  'Ignore error if queue already exists
  On Error GoTo 0               'Reset error handling
  qinfo.Refresh                 'Retrieve registered property values

  '**********************************************************
  ' Specify the type identifier (GUID) of the queue.
  '**********************************************************
  qinfo.ServiceTypeGuid = "{bed40680-b773-11d0-8b96-00aa0062c8e9}"

  '**********************************************************
  ' Update MSMQQueueInfo object.
  '**********************************************************
  qinfo.Update                  'Store changed property values

  MsgBox ("The service type (GUID) of the queue is now: {bed40680-b773-11d0-8b96-00aa0062c8e9}")

End Sub


Using Transactions (COM)

Message Queuing provides several types of transactions. This section provides a brief overview of the COM methods and properties that can be used in a transaction, plus examples on how to create a transactional queue and how to send messages within different types of transaction.

For Information on | See
A summary of what your application must do | Programming Considerations when Using Transactions (COM)
A description of the different types of transaction provided by Message Queuing | Message Queuing Transactions

For an Example of | See
Creating a transactional queue | Creating a Transactional Queue (COM)
Using an external message to send a message | Sending Messages Using an MS DTC External Transaction (COM)
Using an internal transaction to send a message | Sending Messages Using an Internal Transaction (COM)
Using a single-message transaction to send a message | Sending a Single-message Transaction (COM)
Using an MTS transaction to send a message | Sending Messages Using an MTS Transaction (COM)
Using an MTS transaction to retrieve a message | Retrieving Messages Using an MTS Transaction (COM)


Programming Considerations when Using Transactions (COM)

Here is an overview of issues that you should consider when building your application.

Creating a Transactional Queue
Messages sent within a transaction must be sent to a transactional queue. To create a transactional queue, the IsTransactional parameter of MSMQQueueInfo.Create must be set to True when the queue is created.
Specify Transaction type
The Transaction parameter of MSMQMessage.Send, MSMQQueue.Receive, and MSMQQueue.ReceiveCurrent specifies the transaction type.
MS DTC External Transaction
Set Transaction to the transaction object returned by MSMQCoordinatedTransactionDispenser.BeginTransaction.
Message Queuing Internal Transaction
Set Transaction to the transaction object returned by MSMQTransactionDispenser.BeginTransaction.
Single Message Transaction
Set Transaction to MQ_SINGLE_MESSAGE.
MTS Transaction
Set Transaction to MQ_MTS_TRANSACTION. This is the default setting for this parameter.
XA-compliant Transaction
Set Transaction to MQ_XA_TRANSACTION.
Committing and Aborting the transaction
Messages are not sent or retrieved until the application commits to the transaction. When the transaction is aborted, all changes to the queue are rolled back to their original state.
Sending messages
Transactional messages must be sent to transactional queues and non-transactional messages must be sent to non-transactional queues.
Message priority levels
The priority level of all transactional messages is set to 0. Message Queuing sets the value of MSMQMessage.Priority to "0" regardless of what the sending application may specify.
Message timers
When sending multiple messages, Message Queuing sets the time-to-be-received and time-to-reach-queue timers of all messages to the MSMQMessage.MaxTimeToReceive and MSMQMessage.MaxTimeToReachQueue value specified by the first transactional message sent within the transaction.
MTS Transactions
Message Queuing can automatically detect and become part of an MTS transaction. The MQ_MTS_TRANSACTION constant is the default value of the Transaction parameter of MSMQMessage.Send, MSMQQueue.Receive, and MSMQQueue.ReceiveCurrent.

The current MTS context may or may not be transactional. Before using the MTS context, always verify that it is transaction. (See examples on sending message within an MTS transaction.
For an Example of | See
Creating a transactional queue | Creating a Transactional Queue
Using an external message to send a message | Sending Messages Using an MS DTC External Transaction
Using an internal transaction to send a message | Sending Messages Using an Internal Transaction
Using a single-message transaction to send a message | Sending a Single-message Transaction
Using an MTS transaction to send a message | Sending Messages Using an MTS Transaction
Using an MTS transaction to retrieve a message | Retrieving Messages Using an MTS Transaction


Sending Messages Using an MS DTC External Transaction (COM)

To send a message within an MS DTC external transaction, the MSMQCoordinatedTransactionDispenser is used to create the transaction object. After the transaction object is created, make sure it is referenced in the call to Send.

Note Each Message Queuing message can have no more than 4 MB of data.

To send a message using an external transaction

  1. Specify the type of transaction dispenser you want to use. For external transactions, specify the MSMQCoordinatedTransactionDispenser object.
  2. Call MSMQCoordinatedTransactionDispenser.BeginTransaction.
  3. Open the queue with send access.
  4. Create and send the message. Make sure the call to MSMQMessage.Send is associated with the transaction.
For a code example using | See
Microsoft Visual Basic | Visual Basic Code Example


Visual Basic Code Example: Sending a Message Using an External Transaction

This example sends a single message within an external transaction.

To try this example in Microsoft® Visual Basic® (version 5.0), paste the code into the Declaration section of a form, press F5, and click on the form.

Dim xdispenser as New MSMQCoordinatedTransactionDispenser
Dim xact as MSMQTransaction

Dim qSend as MSMQQueue
Dim msg as New MSMQMessage

Set xact = xdispenser.BeginTransaction

'Assumes queue already exists and is transactional.
Set qSend = qinfo.Open(MQ_SEND_ACCESS, MQ_DENY_NONE)
msg.Label = "MyTransactional message"
msg.Body = "Message 1 Body"
msg.Send qSend, xact                     'Associates send with xact.
xact.commit


Sending Messages Using an Internal Transaction (COM)

To send a message within an internal transaction, the MSMQTransactionDispenser is used to create the transaction object. After the transaction object is created, make sure it is referenced in the call to MSMQMessage.Send.

Note Each Message Queuing message can have no more than 4 MB of data.

To send a message using an internal transaction

  1. Declare the objects needed to send a message. This example uses a MSMQQueueInfo, MSMQQueue, MSMQMessage, MSMQTransactionDispenser, and MSMQTransaction object. In this example, MSMQTransactionDispenser object is used because the message is sent in an internal transaction.
  2. Call MSMQQueueInfo.Open to open the transactional queue with send access. This example also calls MSMQQueueInfo.Create to create a transactional queue on the local computer if the specified queue does not exist.
  3. Call MSMQTransactionDispenser.BeginTransaction to start the transaction. From this point on, any errors will cause the function to end prematurely and the transaction will be aborted.
  4. Call MSMQMessage.Send to send the message. In this example the Transaction parameter is set to the transaction object.
  5. Call MSMQTransaction.Commit to accept the transaction.
  6. Call MSMQQueue.Close to close the queue.
For a code example using | See
Microsoft Visual Basic | Visual Basic Code Example


Visual Basic Code Example: Sending a Message Using an Internal Transaction

This example sends a message within an internal transaction. It uses the pathname of the queue to specify the queue, opens the queue with send access, starts the transaction, sends the message to the queue, commits to the transaction, and then closes the queue.

To try this example in Microsoft® Visual Basic® (version 5.0), paste the code into the Declaration section of a form, press F5, and click on the form.

Option Explicit

'*************************************************************
' Declare the required objects.
'*************************************************************
Dim qinfo As New MSMQQueueInfo
Dim qSend As MSMQQueue
Dim mSend As New MSMQMessage
Dim xdispenser As New MSMQTransactionDispenser    ' Used for internal transactions
Dim xact As MSMQTransaction

Private Sub Form_Click()

  '*************************************************************
  ' Open transactional queue with SEND access. The queue is
  ' if no such queue exists
  '*************************************************************

  qinfo.PathName = ".\TransactionTestQueue"
  qinfo.Label = "Send Message Test"
  On Error Resume Next          'Ignore if queue already exists.
  qinfo.Create IsTransactional:=True
  On Error GoTo 0
  Set qSend = qinfo.Open(MQ_SEND_ACCESS, MQ_DENY_NONE)

  '*************************************************************
  ' Start internal transaction. From this point on, any errors
  ' will exit this function prematurely and the transaction will
  ' be aborted. Commits only occur if explicitly invoked.
  '*************************************************************

  Set xact = xdispenser.BeginTransaction

  '*************************************************************
  ' Send message to queue as an internal transaction.
  '*************************************************************

  mSend.Label = "Transaction test message"
  mSend.Body = "Message sent as internal transaction."
  mSend.Send qSend, xact
  xact.Commit

  '*************************************************************
  ' Close the queue.
  '*************************************************************

  qSend.Close

End Sub


Sending a Single-Message Transaction (COM)

Message Queuing provides a single-message transaction that implicitly uses the internal transaction support provided by Message Queuing. The benefits of this type of transaction include:

  • Greater speed, compared to using an external transaction coordinator.
  • Simplified application code.
  • Exactly once delivery without the need to coordinate other activities within a single transaction.

The only difference between sending a non-transactional message and using a single-message transaction is that the destination queue must be a transactional queue, and the Transaction parameter of MSMQMessage.Send must be set to MQ_SINGLE_MESSAGE.

Note Each Message Queuing message can have no more than 4 MB of data.

To send a single-message transaction

  1. Declare the objects needed to send a message. This example uses a MSMQQueueInfo, MSMQQueue, and MSMQMessage object.
  2. Call MSMQQueueInfo.Open to open the transactional queue with send access. This example also calls MSMQQueueInfo.Create to create a transactional queue on the local computer if the specified queue does not exist.
  3. Call MSMQMessage.Send to send the message. In this example, the Transaction parameter is set to MQ_SINGLE_MESSAGE.
  4. Call MSMQQueue.Close to close the queue.
For a code example using | See
Microsoft Visual Basic | Visual Basic Code Example


Visual Basic Code Example: Sending a Message Using a Single Message Transaction

This example sends a single message to a known transactional queue. It uses the pathname of the queue to specify the queue, opens the queue with send access, sends the message to the queue, and then closes the queue.

To try this example in Microsoft® Visual Basic® (version 5.0), paste the code into the Declaration section of a form, press F5, and click on the form.

Option Explicit

'*************************************************************
' Declare the required objects.
'*************************************************************
Dim qinfo As New MSMQQueueInfo
Dim qSend As MSMQQueue
Dim mSend As New MSMQMessage

Private Sub Form_Click()

  '*************************************************************
  ' Open transactional queue with SEND access. The queue is
  ' created if no such queue exists
  '*************************************************************

  qinfo.PathName = ".\TransactionTestQueue"
  qinfo.Label = "Send Message Test"
  On Error Resume Next          'Ignore if queue already exists.
  qinfo.Create IsTransactional:=True
  On Error GoTo 0
  Set qSend = qinfo.Open(MQ_SEND_ACCESS, MQ_DENY_NONE)

  '*************************************************************
  ' Send message to queue as a single-message transaction.
  '*************************************************************

  mSend.Label = "Transaction test message"
  mSend.Body = "Message sent as single-message transaction."
  mSend.Send qSend, MQ_SINGLE_MESSAGE

  '*************************************************************
  ' Close the queue.
  '*************************************************************

  qSend.Close

End Sub


Sending Messages Using an MTS Transaction (COM)

Message Queuing provides a way to use the current MTS context to send messages if the MTS context is available. The MTS context can then be used either to commit to or to abort the operation. Messages are not actually sent until the transaction commits. As in all send transactions, the destination queue of the transaction must be transactional.

Note The MTS component must be part of a transaction. If it is not participating in the transaction, the message is sent as a non-transactional message and the send operation fails because the destination queue is transactional. You cannot send non-transactional messages to a transactional queue.

Message Queuing does not guarantee that the MTS context is transactional. The sending application must verify that the current object is transactional before it sends a message. If the current object is not transactional, your application must explicitly create its own transaction for the messages. In the following example, a single-message transaction is used if the MTS context is not transactional.

To send a message within an MTS Transaction

  1. Declare the MSMQQueueInfo, MSMQQueue, MSMQMessage, and MTS Context.
  2. Use the Set command to obtain the current MTS Context.
  3. Call MSMQQueueInfo.Open to open the transactional queue with send access. The example below creates a queue if one does not exist.
  4. Specify message properties.
  5. Send the message as part of a transaction. The example below first verifies that the MTS context is transactional. If the object is transactional (it is participating in a transaction) an MTS transaction is specified. If the object is not transactional, the message is sent as a single-message transaction.
  6. Call MSMQQueue.Close to close the queue and free its resources.
  7. Commit or abort the transaction. The example below aborts the transaction within the functions error handler (SendError).
For a code example using | See
Microsoft Visual Basic | Visual Basic Code Example


Visual Basic Code Example: Sending a Message Using an MTS Transaction

The following example sends a message within an MTS transaction if the MTS context is transactional, or as a single-message transaction if the MTS context is not transactional.

To try this example in Microsoft® Visual Basic® (version 5.0), paste the code into the Declaration section of a form, press F5, and click on the form.

Option Explicit

'*************************************************************
' Declare the required objects.
'*************************************************************
Dim qinfo As New MSMQQueueInfo
Dim qSend As MSMQQueue
Dim mSend As New MSMQMessage
Dim ctxObject As ObjectContext

Public Function MQSend(strSend As String) As String
  On Error GoTo SendError

  '*************************************************************
  ' Get MTS Context object
  '*************************************************************
  Set ctxObject = GetObjectContext

  '*************************************************************
  ' Optional. Add code for database updates if needed.
  '*************************************************************

  '*************************************************************
  ' Open transactional queue with SEND access. The queue is
  ' created if no such queue exists
  '*************************************************************

  qinfo.PathName = ".\TransactionTestQueue"
  qinfo.Label = "MTS Transaction Test"
  On Error Resume Next          'Ignore if queue already exists.
  qinfo.Create IsTransactional:=True
  On Error GoTo SendError
  Set qSend = qinfo.Open(MQ_SEND_ACCESS, MQ_DENY_NONE)

  '*************************************************************
  ' Set message properties as needed
  '*************************************************************
  mSend.Body = "MTS Transaction Test message"
  mSend.Label = "Test Message"

  '*************************************************************
  ' Make sure MTS context is transactional (that it is
  ' participating in a transaction) and send the message. Note
  ' this example sends the message within a transaction in
  ' either case.
  '*************************************************************
  If (Not ctxObject Is Nothing) Then
     If (ctxObject.IsInTransaction) Then
        mSend.Send qSend                              'Sends message as MTS transaction by default
     Else
        mSend.Send qSend, MQ_SINGLE_MESSAGE
     End If
  Else
     mSend.Send qSend, MQ_SINGLE_MESSAGE
  End If

  '*************************************************************
  ' Close queue.
  '*************************************************************
  qSend.Close

  '*************************************************************
  ' Commit or abort transaction.
  '*************************************************************
  If (Not ctxObject Is Nothing) Then
     ctxObject.SetComplete
  End If

  Set ctxObject = Nothing
  Exit Function

SendError:
If (Not ctxObject Is Nothing) Then
   ctxObject.SetAbort
End If

Set ctxObject = Nothing
MQSend = "SendFailure"

End Function


Retrieving Messages Using an MTS Transaction (COM)

Message Queuing provides a way to use the current MTS context to retrieve messages if the object is available. The MTS context can then be used to either commit to retrieving the messages or roll back the operation by aborting the transaction. As in all receive transactions, the messages are not actually retrieved until the transaction commits.

Note MQ_MTS_TRANSACTION is the default setting for the Transaction parameter of MSMQQueue.Receive. Consequently, setting Transaction is optional when working with MTS transactions.

To retrieve a message within an MTS Transaction

  1. Declare the MSMQQueueInfo, MSMQQueue, MSMQMessage, and MTS Context.
  2. Use the Set command to get the current MTS object.
  3. Call MSMQQueueInfo.Open to open the transactional queue with receive access.
  4. Call Receive to retrieve the message from the queue. Note that no transaction object is supplied when retrieving a message, so the message can be retrieved regardless of whether you're in an MTS component or not.

    In addition, the Transaction parameter of this call is optional because MQ_MTS_TRANSACTION is the default setting.

  5. Call MSMQQueue.Close to close the queue and free its resources.
  6. Commit or abort the transaction. The example below aborts the transaction within the functions error handler (RecError).
For a code example using | See
Microsoft Visual Basic | Visual Basic Code Example


Visual Basic Code Example: Retrieving a Message Using an MTS Transaction

The following example retrieves a message within an MTS transaction.

To try this example in Microsoft® Visual Basic® (version 5.0), paste the code into the Declaration section of a form, press F5, and click on the form.

Option Explicit

'*************************************************************
' Declare the required objects.
'*************************************************************
Dim qinfo As New MSMQQueueInfo
Dim qRec As MSMQQueue
Dim mRec As New MSMQMessage
Dim ctxObject As ObjectContext

Public Function MQReceive(strReceive As String) As String
  On Error GoTo RecError

  '*************************************************************
  ' Get current MTS object.
  '*************************************************************
  Set ctxObject = GetObjectContext

  '*************************************************************
  ' Optional. Add code for database updates if needed.
  '*************************************************************

  '*************************************************************
  ' Open transactional queue with RECEIVE access.
  '*************************************************************

  qinfo.PathName = ".\TransactionTestQueue"
  qinfo.Label = "MTS Transaction Test"
  Set qRec = qinfo.Open(MQ_RECEIVE_ACCESS, MQ_DENY_NONE)

  '*************************************************************
  ' Retrieve message from queue. Note that this code does not
  ' check for the existence of an MTS object. The message is
  ' retrieved regardless of the existence of an MTS object.
  '*************************************************************
  Set mRec = qRec.Receive(ReceiveTimeout:=0)
  If (Not mRec Is Nothing) Then
      strReceive = mRec.Body
      MQReceive = "MessageReceived"
  Else
      MqReceive = "NoMessage"
  End If

  '*************************************************************
  ' Close the queue.
  '*************************************************************
  qRec.Close

  '*************************************************************
  ' Commit or abort transaction.
  '*************************************************************
  If (Not ctxObject Is Nothing) Then
     ctxObject.SetComplete
  End If
  Set ctxObject = Nothing
  Exit Function

RecError:
If (Not ctxObject Is Nothing) Then
   ctxObject.SetAbort
End If

Set ctxObject = Nothing
MQReceive = "ReceiveFailure"

End Function


Message Queuing Reference

This section describes the functions, properties, structures, error and warning codes, and the COM components provided by the Message Queuing (MSMQ) API.

For background information on Message Queuing concepts, refer to About Message Queuing.

For information on | See
Functions | Message Queuing Functions
Queue, message, and queue manager properties | Message Queuing Properties
Structures | Message Queuing Structures
COM object classes, properties, methods, and events | Message Queuing COM Components


Message Queuing Functions

Platform SDK: Message Queuing

MSMQ Functions

The Message Queuing functions provide means for to managing queues and messages within your Message Queuing application. The Message Queuing API includes functions for creating, opening, and deleting queues; for locating existing queues and messages in queues; for sending messages and reading them in queues; and for setting and retrieving properties.

Note All strings passed to or returned by Message Queuing functions are in Unicode format (two-byte characters).

Message Queuing functions include the following functions.

Function | Description
MQBeginTransaction | Creates an internal Message Queuing transaction object that can be used to send messages to a queue or read messages from a queue.
MQCloseCursor | Closes a given cursor, allowing Message Queuing to release the associated resources.
MQCloseQueue | Closes a given queue.
MQCreateCursor | Creates a cursor for a specific queue and returns its handle.
MQCreateQueue | Creates a public or private queue.
MQDeleteQueue | Deletes a queue from the directory service or from the local computer.
MQFreeMemory | Frees memory allocated by Message Queuing.
MQFreeSecurityContext | Frees the memory allocated by MQGetSecurityContext.
MQGetMachineProperties | Retrieves information about a queue manager computer.
MQGetOverlappedResult | Retrieves the Message Queuing receive success or error code from an overlapped structure used to retrieve message asynchronously.
MQGetPrivateComputerInformation | Retrieves information about the local computer without accessing the directory service.
MQGetQueueProperties | Retrieves the specified set of properties for a specific queue.
MQGetQueueSecurity | Retrieves the access control security descriptor for the specified queue.
MQGetSecurityContext | Retrieves security information needed to authenticate messages.
MQHandleToFormatName | Returns a format name for the queue based on its handle.
MQInstanceToFormatName | Returns a format name for the queue based on the identifier provided.
MQLocateBegin | Starts a query to locate a public queue, returning a query handle.
MQLocateEnd | Ends a query, releasing the resources associated with the query.
MQLocateNext | Retrieves the requested queue information from the query.
MQOpenQueue | Returns a format name based on the Message Queuing pathname provided.
MQPathNameToFormatName | Returns a format name based on the Message Queuing pathname provided.
MQReceiveMessage | Allows you to read messages in the queue.
MQReceiveMessageByLookupId | (Introduced in MSMQ 3.0) Peeks at or retrieves messages in the queue based on message lookup identifiers.
MQSendMessage | Sends a message to the queue corresponding to the handle hDestinationQueue.
MQSetQueueProperties | Sets the properties of a specific queue.
MQSetQueueSecurity | Sets the access control security for the queue.


MQBeginTransaction

The MQBeginTransaction function creates an internal Message Queuing transaction object that can be used to send messages to a queue or read messages from a queue.

HRESULT APIENTRY MQBeginTransaction(
  ITransaction **ppTransaction
);

Parameters

ppTransaction
[out] Pointer to Transaction variable that points to the new transaction object.

Return Values

MQ_OK
Indicates success.
MQ_ERROR_INSUFFICIENT_RESOURCES
There are no resources to create a new transaction.
MQ_ERROR_TRANSACTION_ENLIST
Message Queuing could not enlist in the transaction.

Remarks

The pointer returned by MQBeginTransaction can be used to set the pTransaction parameter of MQSendMessage or MQReceiveMessage.

When using an explicit internal transaction, make sure that the transact.h header file is included before mq.h. Transact.h provides the transaction object.

For information on | See
Explicit internal transactions | Message Queuing Internal Transactions
Implicit internal transactions | Single Message Transactions

For a complete example of | See
Sending a message using an internal transaction | Sending a Message Using an Internal Transaction

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mq.h.
Library: Use Mqrt.lib.

See Also

MQReceiveMessage, MQSendMessage


MQCloseCursor

The MQCloseCursor function closes a specific cursor, allowing Message Queuing to release the associated resources.

HRESULT APIENTRY MQCloseCursor(
  HANDLE hCursor
);

Parameters

hCursor
[in] Handle to the cursor you want to close.

Return Values

MQ_OK
Indicates success.
MQ_ERROR_INVALID_HANDLE
The cursor handle specified in hCursor is not valid.

Remarks

Typically, cursors are closed by calling MQCloseCursor. However, Message Queuing automatically closes any cursor created for a given queue when that queue is closed. MQCloseCursor returns MQ_ERROR_INVALID_HANDLE when an attempt is made to close a cursor that has already been closed by Message Queuing.

For information on how cursors behave when navigating queues, see Navigating with Cursors.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mq.h.
Library: Use Mqrt.lib.

See Also

MQCreateCursor


MQCloseQueue

The MQCloseQueue function closes a given queue.

HRESULT APIENTRY MQCloseQueue(
  QUEUEHANDLE hQueue
);

Parameters

hQueue
[in] Handle to the queue you want to close.

Return Values

MQ_OK
Indicates success.
MQ_ERROR_INVALID_HANDLE
The queue handle specified in hQueue is not valid.

Remarks

When an application closes a queue, the queue handle becomes invalid, but the messages waiting in the queue remain in the queue. These include messages sent to the queue by the application closing the queue.

When MQCloseQueue is called, cursors created for the queue are also closed.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mq.h.
Library: Use Mqrt.lib.

See Also

MQOpenQueue


MQCreateCursor

The MQCreateCursor function creates a cursor for a specific queue and returns a handle to the cursor. This cursor is used to maintain a specific location in a queue when reading the queue's messages.

HRESULT APIENTRY MQCreateCursor(
 QUEUEHANDLE hQueue,
 PHANDLE phCursor
);

Parameters

hQueue
[in] Handle to the queue for which you want to create a cursor.
phCursor
[out] Pointer to a variable that receives the resulting cursor handle.

Return Values

MQ_OK
Indicates success.
MQ_ERROR_INVALID_HANDLE
The queue handle specified in hQueue is not valid.
MQ_ERROR_INSUFFICIENT_RESOURCES
There are not enough resources to create a new cursor.
MQ_ERROR_STALE_HANDLE
The specified queue handle was obtained in a previous session of the queue manager service. Close the queue and open it again to obtain a fresh handle.

Remarks

The MQCreateCursor function is used with MQReceiveMessage when you need to read messages that are not at the front of the queue. (Cursors do not need to be used to read only the first message in a queue. For information on how cursors behave when navigating queues, see Navigating with Cursors.

This includes reading messages synchronously or asynchronously.

Note When reading messages within a transaction, Message Queuing does not roll back cursor movement if the transaction is aborted. For example, given a queue with two messages A1 and A2, if you remove message A1 while in a transaction Message Queuing will move the cursor to the next message A2. However, if the transaction is aborted for any reason, message A1 is inserted back into the queue yet the cursor will remain pointing at message A2.

To close the cursor, call MQCloseCursor.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mq.h.
Library: Use Mqrt.lib.

See Also

MQCloseCursor, MQReceiveMessage


MQCreateQueue

The MQCreateQueue function creates a public or private queue based on the queue properties provided.

HRESULT APIENTRY MQCreateQueue(
  PSECURITY_DESCRIPTOR pSecurityDescriptor,
  MQQUEUEPROPS* pQueueProps,
  LPWSTR lpwcsFormatName,
  LPDWORD lpdwFormatNameLength
);

Parameters

pSecurityDescriptor
[in] Pointer to a SECURITY_DESCRIPTOR structure that specifies the security information associated with the queue. Following are the default values (a NULL pointer indicates that all default values are used):
Owner
The process user.
Group
The process group.
DACL
Full control for the creator of the queue. All other processes can get queue properties, get queue security, and send messages to the queue.
SACL
None.
pQueueProps
[in, out] Pointer to the MQQUEUEPROPS structure that specifies the properties of the queue.

On input, the cProp member of MQQUEUEPROPS specifies the number of queue properties supplied, the aPropID array specifies their property identifiers, and the aPropVar array specifies their values.

On output, the optional aStatus array, if it was included in MQQUEUEPROPS, indicates the status of the properties.

lpwcsFormatName
[out] Pointer to buffer to receive the format name for the queue (NULL pointer allowed). This buffer is called the format name buffer.
lpdwFormatNameLength
[in, out] On input, specifies the length (in Unicode characters) of the format name buffer specified in lpwcsFormatName . Public queues require at least 44 Unicode characters; private queues require at least 54. If a NULL pointer is specified in lpwcsFormatName, set lpdwFormatNameLength to 0 (zero) on input.

On output, indicates the length of the returned format name string, including the null-terminating character. If the output value is greater than the initial input value, the supplied buffer is not large enough to contain the complete format name string and MQ_INFORMATION_FORMATNAME_BUFFER_TOO_SMALL is returned. In this case, the queue is created and only a portion of the format name is returned.

Return Values

MQ_OK
Indicates success.
MQ_ERROR_ACCESS_DENIED
The process does not have the rights to create a queue on this computer.
MQ_ERROR_ILLEGAL_PROPERTY_VALUE
An illegal property value is specified.
MQ_ERROR_ILLEGAL_QUEUE_PATHNAME
PROPID_Q_PATHNAME contains an illegal Message Queuing pathname string.
MQ_ERROR_ILLEGAL_SECURITY_DESCRIPTOR
The passed security descriptor has an invalid structure.
MQ_ERROR_INSUFFICIENT_PROPERTIES
No Message Queuing pathname was specified (PROPID_Q_PATHNAME).
MQ_ERROR_INVALID_OWNER
The specified pathname in PROPID_Q_PATHNAME contains the name of an unrecognized machine. For example, this code is returned when you try to create a queue on a machine where Message Queuing is not installed.
MQ_ERROR_INVALID_PARAMETER
An invalid parameter was specified. For example, lpwcsFormatName is set to a NULL pointer and lpdwFormatNameLength is not set to 0 (zero) on input set.
MQ_ERROR_NO_DS
Cannot access the directory service. Verify permissions for accessing directory service.
MQ_ERROR_PROPERTY
One or more properties resulted in an error.
MQ_ERROR_PROPERTY_NOTALLOWED
A specified property is not valid when creating the queue.
MQ_ERROR_QUEUE_EXISTS
A queue with an identical Message Queuing pathname or instance already exists.
MQ_ERROR_SERVICE_NOT_AVAILABLE
Cannot connect to the queue manager.
MQ_ERROR_WRITE_NOT_ALLOWED
Cannot add a queue to directory service.
MQ_INFORMATION_FORMATNAME_BUFFER_TOO_SMALL
The queue was created successfully, but the size of the buffer for receiving the format name of the created queue is too small.
MQ_INFORMATION_PROPERTY
The function completed, but one or more properties resulted in a warning.

Remarks

You must always specify the PROPID_Q_PATHNAME property before calling MQCreateQueue. The PROPID_Q_PATHNAME property tells Message Queuing where to store the messages sent to the queue, whether the queue is public or private, and the name of the queue. When setting this property you can use specify the UNC or DNS pathname for the queue.

Setting other queue properties is optional. If a property is not specified in the pQueueProps parameter, Message Queuing uses its default value when creating the queue. After the queue is created, its properties can be changed by calling MQSetQueueProperties.

Message Queuing registers public queues in the directory service and private queues on the local computer specified. All queues exist until deleted explicitly.

Private queues can be created only on the local computer. When a private queue is created, Message Queuing stores a description of the queue in the LQS directory on the local computer (by default, \program files\msmq\storage\lqs). Applications must ensure that no other private queues with the same name exist on a local computer. If a queue with the same name already exists, Message Queuing will return an MQ_ERROR_QUEUE_EXISTS error when MQCreateQueue is called.

To create a transactional queue, set the PROPID_Q_TRANSACTION property to MQ_TRANSACTIONAL. This property cannot be changed once the queue is created.

Foreign queues must be public queues. Their PROPID_Q_PATHNAME property must specify the name of the foreign computer as it is defined in the directory service. For information on connecting to foreign queues, see MSMQ Connector Servers.

To specify target journaling, set PROPID_Q_JOURNAL and PROPID_Q_JOURNAL_QUOTA .

Access control for the queue is based on the security descriptor specified in the pSecurityDescriptor parameter. For information on access control, see Access Control.

The queue's returned format name is invalid if MQCreateQueue fails for any reason, including returning the error MQ_ERROR_QUEUE_EXISTS. If the call returns MQ_INFORMATION_FORMATNAME_BUFFER_TOO_SMALL, this means that the queue was created, but the format name could not fit in the format name buffer.

Public queues cannot be created if there is no connection to the directory service. This restriction applies to dependent client computers, independent client computers that are working offline, and Message Queuing routing servers (FRS). For information on offline operations, see Message Queuing Offline Support.

When creating a public queue, some clients may not be able to see the new queue registered in the directory service even though the queue exists. Changes to the directory service (such as creating a public queue) are propagated from domain controller to domain controller, which can cause delays in the availability of new information. Consequently, clients using a specific domain controller may not be able to open the queue, even though it exists. Propagation delays, including communication network delays such as down links, are controlled by the MSMQ Administrator.

For information on | See
The different types of queues provided by Message Queueing | Message Queuing Queues
What information Message Queuing needs to create queues | Creating Queues
Optional queue properties that can be set when you create a queue | Setting Queue Behavior
Transaction support provided by Message Queuing | Message Queuing Transactions

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mq.h.
Library: Use Mqrt.lib.

See Also

PROPID_Q_JOURNAL, PROPID_Q_JOURNAL_QUOTA, PROPID_Q_PATHNAME, PROPID_Q_TRANSACTION


MQDeleteQueue

The MQDeleteQueue function deletes a queue from the directory service (in the case of public queues) or from the local computer (in the case of private queues).

HRESULT APIENTRY MQDeleteQueue(
  LPCWSTR lpwcsFormatName
);

Parameters

lpwcsFormatName
[in] Pointer to the format name string of the queue to be deleted.

Return Values

MQ_OK
Indicates success.
MQ_ERROR_ACCESS_DENIED
The process does not have the access rights to delete this queue. To change access rights, call MQSetQueueSecurity.
MQ_ERROR_ILLEGAL_FORMATNAME
The specified format name in lpwcsFormatName is illegal.
MQ_ERROR_NO_DS
Cannot access the directory service. Verify permissions for accessing the directory service.
MQ_ERROR_SERVICE_NOT_AVAILABLE
Cannot connect to the queue manager.
MQ_ERROR_UNSUPPORTED_FORMATNAME_OPERATION
The format name specified by lpwcsFormatName cannot be used to delete a queue. You cannot reference a queue using a direct format name, nor can you delete a journal, dead-letter, or connector queue.
MQ_ERROR_WRITE_NOT_ALLOWED
Cannot delete a queue from the directory service.

Remarks

All queues must be referenced using a public or private format name. Message Queuing must be able to access the directory service to delete public queues, or the local computer to delete private queues. If the format name of the queue is unknown, see Obtaining Format Names.

Private queues registered on a remote computer, as well as journal, dead-letter, and connector queues cannot be deleted.

Public queues cannot be deleted if there is no connection to the directory service. This restriction applies to dependent client computers, independent client computers that are working offline, and Message Queuing routing servers (FRS). (For information on offline operations, see Message Queuing Offline Support.)

When a public queue is deleted, some clients may still see the queue registered in the directory service after the queue has been deleted. A change to the directory service (such as deleting a public queue) is propagated from domain controller to domain controller, which can cause delays in the availability of new information. Consequently, clients using a specific domain controller may try to send messages to the queue, even though it has been deleted. Propagation delays, including communication network delays such as down links, are controlled by the Message Queuing administrator.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mq.h.
Library: Use Mqrt.lib.

See Also

MQCloseQueue, MQCreateQueue, MQOpenQueue, MQSetQueueSecurity


MQFreeMemory

The MQFreeMemory function frees memory allocated by Message Queuing.

VOID MQFreeMemory(
  PVOID pvMemory
);

Parameters

pvMemory
[in] Pointer to the memory to be freed.

Remarks

Whenever an application passes VT_NULL in an aPropVar array and Message Queuing allocates memory for the returned property value (for example, puuid and pwszVal), MQFreeMemory must be called.

For MQLocateNext, all properties whose values returned by Message Queuing are stored outside aPropVar must also be freed using MQFreeMemory.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mq.h.
Library: Use Mqrt.lib.

See Also

aPropVar, MQLocateNext


MQFreeSecurityContext

The MQFreeSecurityContext function frees the memory allocated by MQGetSecurityContext.

VOID APIENTRY MQFreeSecurityContext(
  HANDLE hSecurityContext
);

Parameters

hSecurityContext
[in] Handle to the security context buffer.

Return Values

None

Remarks

The security context buffer is created by MQGetSecurityContext. It contains information Message Queuing needs to authenticate messages.

MQFreeSecurityContext and MQSendMessage must all be called within the same user context.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mq.h.
Library: Use Mqrt.lib.

See Also

MQGetSecurityContext, MQSendMessage


MQGetMachineProperties

The MQGetMachineProperties function retrieves information about a queue manager computer.

HRESULT APIENTRY MQGetMachineProperties(
  LPCWSTR lpwcsMachineName,
  const GUID* pguidMachineID,
  MQQMPROPS* pQMProps
);

Parameters

lpwcsMachineName
[in] The name of the queue manager computer you want to access. Specify the NetBIOS or DNS name of the computer. If this parameter is used, set pguidMachineID to NULL.
pguidMachineID
[in] The identifier of the queue manager computer you want to access. If this parameter is used, set lpwcsMachineName to NULL.
pQMProps
[in, out] Pointer to a queue manager properties structure (MQQMPROPS) specifying which properties to retrieve.

Return Values

MQ_OK
Indicates success.
MQ_ERROR_ACCESS_DENIED
Access to the specified computer is denied. Verify the access rights for the operation.
MQ_ERROR_INVALID_PARAMETER
Both name (lpwcsMachineName) and computer (pguidMachineID) identifiers were specified.
MQ_ERROR_ILLEGAL_MQQMPROPS
Either pQMprops was NULL or no properties were specified.
MQ_ERROR_ILLEGAL_PROPERTY_VT
An invalid type indicator was supplied for one of the property values in pQMProps.
MQ_ERROR_MACHINE_NOT_FOUND
The specified computer could not be found in the directory service.
MQ_ERROR_NO_DS
Cannot access the directory service. Verify permissions for accessing the directory service.
MQ_ERROR_PUBLIC_KEY_DOES_NOT_EXIST
(Introduced in MSMQ 2.0) This error is returned when you attempt to retrieve PROPID_QM_ENCRYPTION_PK_ENHANCED and the enhanced key is not registered. Message Queuing was able to successfully query the directory service, but the enhanced key was not found.
MQ_ERROR_PUBLIC_KEY_NOT_FOUND.
(Introduced in MSMQ 2.0) This error is returned when you attempt to retrieve PROPID_QM_ENCRYPTION_PK_ENHANCED and Message Queuing failed to query the directory service. For example, this can happen if the computer calling MQGetMachineProperties is operating offline or if you are trying to retrieve the machine properties of a computer running MSMQ 1.0.
MQ_INFORMATION_UNSUPPORTED_PROPERTY
An unsupported property identifier was specified in pQMProps.
MQ_INFORMATION_DUPLICATE_PROPERTY
A duplicate property identifier was specified in pQMProps. The second entry is ignored.

Remarks

If lpwcsMachineName and pguidMachineID are set to NULL, the properties of the local computer are retrieved.

Valid queue manager properties are:

  • PROPID_QM_CONNECTION
  • PROPID_QM_ENCRYPTION_PK
  • PROPID_QM_ENCRYPTION_PK_BASE
  • PROPID_QM_ENCRYPTION_PK_ENHANCED
  • PROPID_QM_MACHINE_ID
  • PROPID_QM_PATHNAME
  • PROPID_QM_SITE_ID
  • PROPID_QM_PATHNAME_DNS

If a property specified by pQMProps is set to VT_NULL, Message Queuing allocates the memory needed to store the property value when MQGetMachineProperties is called. However, when the returned property type replaces the VT_NULL value, the application must still free the memory allocated for the property value by calling MQFreeMemory.

Machine properties cannot be retrieved if there is no connection to the directory service. This restriction applies to dependent client computers, independent client computers that are working offline, and Message Queuing routing servers (FRS). (For information on offline operations, see Message Queuing Offline Support.)

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mq.h.
Library: Use Mqrt.lib.

See Also

MQFreeMemory, MQQMPROPS, PROPID_QM_CONNECTION, PROPID_QM_ENCRYPTION_PK, PROPID_QM_MACHINE_ID, PROPID_QM_PATHNAME, PROPID_QM_SITE_ID


MQGetOverlappedResult

The MQGetOverlappedResult function retrieves the Message Queuing success or error code from an overlapped structure used to retrieve message asynchronously.

HRESULT APIENTRY MQGetOverlappedResult(
LPOVERLAPPED lpOverlapped
);

Parameters

lpOverlapped
[in] The overlapped structure used to retrieve the message.

Return Values

MQ_OK
Indicates success.

Remarks

Call this function after the event is signaled or after you get a completion port notification. The function retrieves the success or error code from the internal member of the overlapped structure.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Mq.h.
Library: Use Mqrt.lib.

See Also

MQReceiveMessage


MQGetPrivateComputerInformation

(Introduced in MSMQ 2.0) The MQGetPrivateComputerInformation function retrieves information about the a computer without accessing the directory service.

HRESULT APIENTRY MQGetPrivateComputerInformation(
  LPCWSTR lpwcsComputerName,
  MQPRIVATEPROPS* pPrivateProps
);

Parameters

lpwcsComputerName
[in] The name of the computer you want to access. This parameter must be NULL to specify the local computer.
pPrivateProps
[in, out] Pointer to a MQPRIVATEPROPS structure that specifies which private computer properties to retrieve.

On input, this structure specifies which properties to retrieve.

On output, this structure contains the returned values for the properties and any optional status error codes for the properties (some properties do not return status error codes).

Return Values

MQ_OK
Indicates success.

Remarks

This function may be called even when Message Queuing does not have access to a directory service. The values of the local computer properties retrieved by this method are calculated, they are not retrieved from the directory service.

This function can only be called on computers running MSMQ 2.0. You can retrieve the following two private computer properties, PROPID_PC_VERSION and PROPID_PC_DS_ENABLED.

For an example of | See
Checking the directory service – enabled property | Verifying Workgroup Installation

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Mq.h.
Library: Use Mqrt.lib.

See Also

MQPRIVATEPROPS, PROPID_PC_VERSION, PROPID_PC_DS_ENABLED


MQGetQueueProperties

The MQGetQueueProperties function retrieves the specified set of properties for a specific queue.

HRESULT APIENTRY MQGetQueueProperties(
  LPCWSTR lpwcsFormatName,
  MQQUEUEPROPS *pQueueProps
);

Parameters

lpwcsFormatName
[in] Pointer to the format name string of the queue whose properties will be retrieved. Use only public or private format name to specify queue. See "Remarks" for limitations on private queues.
pQueueProps
[in, out] Pointer to the MQQUEUEPROPS structure where the properties are specified.

On input, the cProp member of MQQUEUEPROPS specifies the number of properties to be retrieved, and the aPropID array specifies the specific properties.

On output, the aPropVar array indicates the current values of the requested properties, and the optional aStatus array indicates their status (to use the property status array, include aStatus in MQQUEUEPROPS declaration).

Return Values

MQ_OK
Indicates success.
MQ_ERROR_ACCESS_DENIED
The process does not have the correct access rights to get the queue's properties. For a complete list of queue access rights, see Access Control.

To change access rights, call MQSetQueueSecurity.

MQ_ERROR_ILLEGAL_FORMATNAME
The lpwcsFormatName parameter specified an illegal format name.
MQ_ERROR_ILLEGAL_PROPERTY_VT
The variant type of a property does not match the expected variant type. For example, for PROPID_Q_TYPE, the expected variant types are VT_NULL or VT_CLSID. For PROPID_Q_PATHNAME and PROPID_Q_LABEL, the expected variant type is VT_NULL.
MQ_ERROR_NO_DS
Cannot access the directory service. Verify permissions for accessing the directory service.
MQ_ERROR_PROPERTY
One or more properties resulted in an error.
MQ_ERROR_SERVICE_NOT_AVAILABLE
Cannot connect to the queue manager.
MQ_ERROR_UNSUPPORTED_FORMATNAME_OPERATION
The format name specified in the lpwcsFormatName parameter cannot be used. You cannot get properties from a queue using a direct format name.
MQ_INFORMATION_DUPLICATE_PROPERTY
The same property appears more than once in the aPropID array. This information is returned on the second appearance of the property.
MQ_INFORMATION_PROPERTY
One or more of the properties resulted in a warning code even though the function was completed.
MQ_INFORMATION_UNSUPPORTED_PROPERTY
Not a valid property identifier. The property is ignored.

Remarks

The properties of a public queue can be retrieved at any time; however, you can only retrieve the properties of a private queue if it is located on your local computer.

To retrieve the queue's pathname (PROPID_Q_PATHNAME) or label (PROPID_Q_LABEL), the corresponding property's variant type must be initially set to VT_NULL so that Message Queuing knows to allocate memory for the returned value. After using the retrieved value, the application must then call MQFreeMemory to free the memory allocated by Message Queuing.

To retrieve the queue's identifier (PROPID_Q_INSTANCE) or type (PROPID_Q_TYPE), a buffer of type CLSID must be declared to hold the returned GUID.

A public queue's properties cannot be retrieved if there is no connection to the directory service. This restriction applies to dependent client computers, independent client computers (working offline), and Message Queuing routing servers (FRS).

For information on | See
Obtaining a format name for the queue | Obtaining Format Names
Offline operations | Message Queuing Offline Support

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mq.h.
Library: Use Mqrt.lib.

See Also

aPropID, aPropVar, aStatus, MQFreeMemory, MQQUEUEPROPS, PROPID_Q_INSTANCE, PROPID_Q_LABEL, PROPID_Q_PATHNAME, PROPID_Q_TYPE


MQGetQueueSecurity

The MQGetQueueSecurity function retrieves the access control security descriptor for the specified queue.

HRESULT APIENTRY MQGetQueueSecurity(
  LPCWSTR lpwcsFormatName,
  SECURITY_INFORMATION SecurityInformation,
  PSECURITY_DESCRIPTOR pSecurityDescriptor,
  DWORD nLength,
  LPDWORD lpnLengthNeeded
);

Parameters

lpwcsFormatName
[in] Pointer to the format name string of the queue whose security information will be retrieved. Use only public or private format name to specify the queue. See "Remarks" for limitations on private queues.
SecurityInformation
[in] Specifies the SECURITY_INFORMATION structure that identifies the access control information being requested.
pSecurityDescriptor
[out] Pointer to the security descriptor buffer that receives the queue's security descriptor. The calling process must have the rights to view the specified aspects of the queue's security status. The SECURITY_DESCRIPTOR structure is returned in self-relative format.
nLength
[in] Specifies the size, in bytes, of the security descriptor buffer (see pSecurityDescriptor).
lpnLengthNeeded
[out] Pointer to a variable that indicates if any additional length is needed for the security descriptor. If the security descriptor fits in the buffer, this variable indicates the actual size of the security descriptor.

If the security descriptor buffer is too small for the security descriptor (the value of lpnLengthNeeded is greater than the value of nLength), this variable indicates the size of the buffer needed to hold the security descriptor. When this happens, the security descriptor is not copied to the buffer and MQ_ERROR_SECURITY_DESCRIPTOR_TOO_SMALL is returned.

Return Values

MQ_OK
Indicates success.
MQ_ERROR_ACCESS_DENIED
The process does not have the correct access rights to get the queue's security descriptor. For a complete list of queue access rights, see Access Control.

To change access rights, call MQSetQueueSecurity.

MQ_ERROR_FUNCTION_NOT_SUPPORTED
MQGetQueueSecurity is not supported in Windows 95.
MQ_ERROR_ILLEGAL_FORMATNAME
The lpwcsFormatName parameter specified an illegal format name.
MQ_ERROR_NO_DS
Cannot access the directory service. Verify permissions for accessing the directory service.
MQ_ERROR_PRIVILEGE_NOT_HELD
The process does not have the proper privilege to read the queue's system access control list.
MQ_ERROR_SECURITY_DESCRIPTOR_TOO_SMALL
The buffer pointed to by pSecurityDescriptor is too small to hold the security descriptor; the returned value of lpnLengthNeeded is greater than the supplied value of nLength.
MQ_ERROR_UNSUPPORTED_FORMATNAME_OPERATION
The format name specified in the lpwcsFormatName parameter cannot be used. You cannot reference a queue using a direct format name, nor can you get the security descriptor of a journal, dead-letter, or connector queue.

Remarks

The queue's security descriptor is initially set when the queue is created (see MQCreateQueue). Access to the following queue operations can be controlled: creating, deleting, and opening the queue for sending messages to and reading messages from the queue; getting and setting the queue's properties; and getting and setting the queue's security descriptor.

The security descriptor of a public queue can be retrieved at any time; however, you can only retrieve the security descriptor of a private queue if it is located on your local computer.

The security descriptor of a journal, dead-letter, connector, and foreign queue cannot be retrieved.

To read the security descriptor of a queue, the calling process must have READ_CONTROL access or be the owner of the queue. Access rights such as READ_CONTROL are set when the queue is created and can be modified by calling MQSetQueueSecurity.

To read the queue's system access control list, the caller must have SE_SECURITY_NAME privileges on the directory service server (for public queues) or on the local computer (for private queues).

A public queue's security descriptor cannot be retrieved if there is no connection to the directory service. This restriction applies to dependent client computers, independent client computers that are working offline, and Message Queuing routing servers (FRS).

For information on | See
Obtaining a format name for the queue | Obtaining Format Names
Offline operations | Message Queuing Offline Support

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mq.h.
Library: Use Mqrt.lib.

See Also

MQCreateQueue, MQSetQueueSecurity


MQGetSecurityContext

The MQGetSecurityContext function retrieves the security information needed to attach a certificate to a message when requesting authentication.

This function is superseded by MQGetSecurityContextEx.

HRESULT APIENTRY MQGetSecurityContext(
  LPVOID lpCertBuffer,
  DWORD dwCertBufferLength,
  HANDLE *hSecurityContext
);

Parameters

lpCertBuffer
[In] Pointer to the security certificate buffer. External certificates must be in ASN.1 DER encoded format. If this parameter is NULL, the internal security certificate provided by Message Queuing is used.
dwCertBufferLength
[In] Length of the security certificate buffer pointed to by lpCertBuffer. For internal certificates, set to 0.
hSecurityContext
[Out] Handle to the security context buffer allocated by Message Queuing.

Return Values

MQ_OK
Indicates success.
MQ_ERROR_CORRUPTED_INTERNAL_CERTIFICATE
(MSMQ 1.0 only) Message Queuing–supplied internal certificate is corrupted.
MQ_ERROR_CORRUPTED_SECURITY_DATA
Cryptographic function (CryptoAPI) has failed.
MQ_ERROR_COULD_NOT_GET_USER_SID
Message Queuing could not get the specified sender identifier.
MQ_ERROR_INVALID_PARAMETER
One of the IN parameters supplied by the operation is not valid.
MQ_ERROR_INSUFFICIENT_RESOURCES
Insufficient resources to complete operation (for example, not enough memory). Operation failed.
MQ_ERROR_INVALID_CERTIFICATE
The certificate is not correctly placed in the Microsoft® Internet Explorer personal certificate store.
MQ_ERROR_NO_NTERNAL_USER_CERT
No internal certificate is registered, or the registered certificate is corrupted.

Remarks

The MQGetSecurityContext function is obsolete. Use MQGetSecurityContextEx whenever possible. Both functions provide the same functionality, however MQGetSecurityContextEx provides more security when impersonating another user.

When you are sending authenticated messages, MQGetSecurityContext retrieves the information Message Queuing run-time needs to attach a certificate to the messages. This provides an easier, more efficient way to send a large number of messages that require authentication using the same certificate. When MQGetSecurityContext is used, the sending application is only responsible for passing the security context buffer (PROPID_M_SECURITY_CONTEXT) to MQSendMessage.

When using more than one certificate, the sending application must call MQGetSecurityContextEx for each certificate that is used.

When impersonating another user, the sending application must call MQGetSecurityContext before it sends a message. Once the security information for the impersonated user is retrieved, the sending application can revert to the original user and later use the impersonated security context information to send another message without needing to impersonate the user again.

After the security certificate is no longer needed, free the memory allocated for the security context buffer by calling MQFreeSecurityContext.

For information on | See
What it means to authenticate a message: message integrity and sender authentication | Message Authentication
The process used to authenticate a messages | How Message Queuing Authenticates Messages
Using security context when impersonating another user | Impersonating a User

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mq.h.
Library: Use Mqrt.lib.

See Also

MQFreeSecurityContext, MQSendMessage, PROPID_M_SECURITY_CONTEXT, PROPID_M_SENDER_CERT


MQGetSecurityContextEx

(Introduced in Windows 2000 Service Pack 2.) The MQGetSecurityContextEx function retrieves the security information needed to attach a certificate to a message when requesting authentication.

MQGetSecurityContextEx supersedes MQGetSecurityContext.

HRESULT APIENTRY MQGetSecurityContextEx(
  LPVOID lpCertBuffer,
  DWORD dwCertBufferLength,
  HANDLE *hSecurityContext
);

Parameters

lpCertBuffer
[In] Pointer to the security certificate buffer. External certificates must be in ASN.1 DER encoded format. If this parameter is NULL, the internal security certificate provided by Message Queuing is used.
dwCertBufferLength
[In] Length of the security certificate buffer pointed to by lpCertBuffer. For internal certificates, set this parameter to 0.
hSecurityContext
[Out] Handle to the security context buffer allocated by Message Queuing.

Return Values

MQ_OK
Indicates success.
MQ_ERROR_CORRUPTED_SECURITY_DATA
Cryptographic function (CryptoAPI) has failed.
MQ_ERROR_COULD_NOT_GET_USER_SID
Message Queuing could not get the specified SID of the sender.
MQ_ERROR_INVALID_PARAMETER
One of the input parameters supplied is not valid.
MQ_ERROR_INSUFFICIENT_RESOURCES
Insufficient resources to complete operation (for example, not enough memory). Operation failed.
MQ_ERROR_INVALID_CERTIFICATE
The certificate is not correctly placed in the Microsoft® Internet Explorer personal certificate store.
MQ_ERROR_NO_INTERNAL_USER_CERT
No internal certificate is registered, or the registered certificate is corrupted.

Remarks

The MQGetSecurityContextEx function is used method is used whenever possible to send large numbers of messages using the same certificate or when impersonating another user.

When sending authenticated messages (and not impersonating another user), the sending application must call MQGetSecurityContextEx and MQSendMessage in the same user context.

When an application sends authenticated messages, the call to MQGetSecurityContextEx retrieves the information that the Message Queuing run-time needs to attach the same certificate to each of several messages. This provides an easier, more efficient way to send a large number of messages that require authentication using the same certificate. When MQGetSecurityContextEx is used, the sending application is responsible only for passing the security context buffer (PROPID_M_SECURITY_CONTEXT) to MQSendMessage.

If, however, the sending application is using more than one certificate, it must call MQGetSecurityContextEx for each certificate it uses.

When impersonating another user, the sending application must load the hive of the impersonated user, impersonate the user, and then call MQGetSecurityContextEx before it sends the messages of the impersonated user. Internally, MQGetSecurityContextEx uses the RegOpenCurrentUser function to access the user hive where the certificate of the impersonated user is stored. Once the security information for the impersonated user is retrieved, the sending application can revert to the original user and later use the impersonated security context information to send another message without needing to impersonate the user again.

The hive of the impersonated user can be loaded programmatically (for code example see Microsoft Knowledge Base article Q168877) or manually using a tool such as RegEdit32.

After the security certificate is no longer needed, free the memory allocated for the security context buffer by calling MQFreeSecurityContext.

The MQGetSecurityContextEx function supercedes MQGetSecurityContext. Both functions provide the same functionality, however MQGetSecurityContextEx provides improved security.

Equivalent COM Method

When using COM components, you can retrieve security context information by calling MSMQMessage.AttachCurrentSecurityContext2.

For information on | See
What it means to authenticate a message: message integrity and sender authentication | Message Authentication
The process used to authenticate a messages | How Message Queuing Authenticates Messages
Using security context when impersonating another user (including differences between MQGetSecurityContextEx and MQGetSecurityContext) | Impersonating a User

Requirements

Windows NT/2000 or later: Requires Windows 2000 SP2 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Mq.h.
Library: Use Mqrt.lib.

See Also

MQFreeSecurityContext, MQGetSecurityContext, MQSendMessage, PROPID_M_SECURITY_CONTEXT


MQHandleToFormatName

The MQHandleToFormatName function returns a format name for the queue based on its handle.

HRESULT APIENTRY MQHandleToFormatName(
  QUEUEHANDLE hQueue,
  LPWSTR lpwcsFormatName,
  LPDWORD lpdwCount
);

Parameters

hQueue
[in] Handle to the queue.
lpwcsFormatName
[out] Buffer to receive the format name for the queue.
lpdwCount
[in, out] On input, specifies the length of the lpwcsFormatName buffer (in Unicode characters). Public queues require at least 44 Unicode characters; private queues require at least 54. NULL pointer is not allowed.

On output, indicates the length of the returned format name string, including the null-terminating character. If the output value is greater than the initial input value, the supplied buffer is not large enough to contain the complete format name string and MQ_ERROR_FORMATNAME_BUFFER_TOO_SMALL is returned. In this case, only a portion of the format name is returned.

Return Values

MQ_OK
Indicates success.
MQ_ERROR_FORMATNAME_BUFFER_TOO_SMALL
The lpwcsFormatName buffer is too small to contain the format name string.
MQ_ERROR_INVALID_HANDLE
The queue handle specified in hQueue is not valid.
MQ_ERROR_SERVICE_NOT_AVAILABLE
Cannot connect to the queue manager.
MQ_ERROR_STALE_HANDLE
The specified queue handle was obtained in a previous session of the queue manager service. Close the queue and open it again to obtain a fresh handle.

Remarks

Format names are not stored by Message Queuing; the format name is created when MQHandleToFormatName is called.

Typically, this function is used when you need a format name to specify a queue when calling MQGetQueueProperties, MQSetQueueProperties, MQGetQueueSecurity, or MQSetQueueSecurity.

This function can be called while operating offline. Message Queuing does not use information stored in the directory service to generate a format name from the queue handle. For information on offline operations, see Message Queuing Offline Support.

Other format name translation functions include MQPathNameToFormatName and MQInstanceToFormatName.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mq.h.
Library: Use Mqrt.lib.

See Also

MQGetQueueProperties, MQGetQueueSecurity, MQInstanceToFormatName, MQPathNameToFormatName, MQSetQueueProperties, MQSetQueueSecurity


MQInstanceToFormatName

The MQInstanceToFormatName function returns a format name for the queue based on the identifier provided.

This function does not check to see if the identifier is valid.

HRESULT APIENTRY MQInstanceToFormatName(
  GUID *pGUID,
  LPWSTR lpwcsFormatName,
  LPDWORD lpdwCount
);

Parameters

pGUID
[in] Pointer to the queue identifier (a GUID structure).
lpwcsFormatName
[out] Pointer to a buffer to receive the format name for the queue.
lpdwCount
[in, out] On input, specifies the length of the lpwcsFormatName buffer (in Unicode characters). Public queues require at least 44 Unicode characters; private queues require at least 54. NULL pointer is not allowed.

On output, indicates the length of the returned format name string, including the null-terminating character. If the output value is greater than the initial input value, the supplied buffer is not large enough to contain the complete format name string and MQ_ERROR_FORMATNAME_BUFFER_TOO_SMALL is returned. In this case, only a portion of the format name is returned.

Return Values

MQ_OK
Indicates success.
MQ_ERROR_SERVICE_NOT_AVAILABLE
Cannot connect to the queue manager.
MQ_ERROR_FORMATNAME_BUFFER_TOO_SMALL
The buffer pointed to by lpwcsFormatName is too small to contain the format name string.

Remarks

Format names are not stored by Message Queuing; the format name is created when MQInstanceToFormatName is called.

This function is used when you need a format name to specify a queue when calling MQOpenQueue, MQGetQueueProperties, MQSetQueueProperties, MQGetQueueSecurity, or MQSetQueueSecurity, and the only available information is the queue's identifier (PROPID_Q_INSTANCE). Typically, this happens when MQLocateBegin or MQLocateNext locates a queue and stores its identifier, not the queue's format name, in the directory service.

This function can be called while you are operating offline. Message Queuing does not use information stored in the directory service to generate a format name from the queue identifier. For information on offline operations, see Message Queuing Offline Support.

Other format name translation functions include MQPathNameToFormatName and MQHandleToFormatName.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mq.h.
Library: Use Mqrt.lib.

See Also

MQGetQueueProperties, MQGetQueueSecurity, MQHandleToFormatName, MQLocateBegin, MQLocateNext, MQOpenQueue, MQPathNameToFormatName, MQSetQueueProperties, MQSetQueueSecurity, PROPID_Q_INSTANCE


MQLocateBegin

The MQLocateBegin function starts a query of the directory service to locate a set of public queues. Use MQLocateNext to retrieve the query results.

This function does not return the number of matching entries.

HRESULT APIENTRY MQLocateBegin(
  LPCWSTR lpwcsContext,
  MQRESTRICTION *pRestriction,
  MQCOLUMNSET *pColumns,
  MQSORTSET *pSort,
  PHANDLE phEnum
);

Parameters

lpwcsContext
[in] Specifies the starting point of the query within the directory service. Must be NULL.
pRestriction
[in] Specifies the search criteria for the query. NULL value indicates no restrictions and properties for all public queues registered in the directory service are returned.
pColumns
[in] Specifies which queue properties should be returned by the query. Must not be set to NULL.
pSort
[in] An MQSORTSET structure that specifies the sort keys of the query.
phEnum
[out] Pointer to a query handle to use when calling MQLocateNext and MQLocateEnd.

Return Values

MQ_OK
Indicates success.
MQ_ERROR_ILLEGAL_CONTEXT
Indicates that lpwcsContext is not NULL.
MQ_ERROR_ILLEGAL_MQCOLUMNS
Indicates that pColumns is NULL.
MQ_ERROR_ILLEGAL_PROPERTY_VALUE
Indicates that an illegal property value was specified in pRestriction. For example, this error is returned if PROPID_Q_LABEL is specified and the supplied queue label is longer than the maximum label length.
MQ_ERROR_ILLEGAL_PROPID
Indicates that an illegal property identifier was specified in pColumns.
MQ_ERROR_ILLEGAL_RELATION
Indicates that an invalid relationship value was specified in pRestriction.
MQ_ERROR_ILLEGAL_RESTRICTION_PROPID
Indicates that an illegal property identifier was specified in pRestriction. For example, PROPID_Q_PATHNAME is not valid.
MQ_ERROR_ILLEGAL_SORT_PROPID
Indicates that an illegal property identifier was specified in pSort. For example, if pSort specifies PROPID_Q_PATHNAME, this error is returned.
MQ_ERROR_NO_DS
Cannot access the directory service. Verify permissions for accessing the directory service.
MQ_ERROR_Q_DNS_PROPERTY_NOT _SUPPORTED
Indicates that PROPID_Q_PATHNAME_DNS was specified in pColumns. You cannot retrieve the DNS pathname of a queue.

Remarks

MQLocateBegin locates public queues that are in the directory service when MQLocateBegin is called. Public queues added to the directory service after MQLocateBegin is called are not included. MQLocateBegin can cannot locate private queues that reside on computers. For a complete description of running a query, see Locating Queues Using Function Calls.

Starting with Whistler, the returned query handle is a handle to an ADSI COM object, which means that the calling application cannot change the thread model on the calling thread.

The pRestriction parameter of MQLocateBegin specifies the search criteria (which queue properties and values are used in the search). It is a pointer to a structure containing a list of property restrictions logically combined by the And operator, with each restriction including a queue property identifier, a property value, and a comparison operator. Comparison operators include: less than (PRLT), less than or equal to (PRLE), equal (PREQ), not equal (PRNE), greater than or equal to (PRGE), greater than (PRGT).

Setting pRestriction to NULL retrieves information about all public queues registered in the directory service.

For information on the structures used to set the search criteria, see Specifying Search Criteria.

The pColumns parameter allows you to specify which queue properties to retrieve. You can retrieve any number of queue properties (with the exception of PROPID_Q_PATHNAME_DNS) using the same call to MQLocateBegin.

For information on the structures used to set the queue properties to be returned, see Specifying Queue Properties to Retrieve.

The pSort parameter allows you to specify the key and sort order (ascending or descending) of the query. Each key is a queue property (PROPID_Q_PATHNAME cannot be used as a sort key). The MQSORTSET structure contains an array of MQSORTKEY structures, each representing a single sort key. Currently, Message Queuing supports only one sort key per query.

When running a query, Message Queuing can locate queues faster when the query is based on PROPID_Q_INSTANCE, PROPID_Q_TYPE, or PROPID_Q_LABEL (PREQ only). The query runs faster because these properties are indexed in the directory service, providing a faster way for Message Queuing to locate the property specified in the call.

MQLocateBegin cannot locate public queues if there is no connection to the directory service. This restriction applies to dependent client computers, independent client computers that are working offline, and Message Queuing routing servers (FRS).

For information on offline operations, see Message Queuing Offline Support.

For information on | See
What information Message Queuing needs to locate queues | Locating Queues Using Function Calls
Structures used to set search criteria | Specifying Search Criteria
Structures used to set returned queue properties | Specifying Queue Properties to Retrieve

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mq.h.
Library: Use Mqrt.lib.

See Also

MQLocateEnd, MQLocateNext, MQSORTKEY, MQSORTSET, PROPID_Q_INSTANCE, PROPID_Q_LABEL, PROPID_Q_PATHNAME, PROPID_Q_PATHNAME_DNS, PROPID_Q_TYPE


MQLocateEnd

The MQLocateEnd function ends a query, releasing the resources associated with the query.

HRESULT APIENTRY MQLocateEnd(
  HANDLE hEnum
);

Parameters

hEnum
[in] Query handle returned by a call to MQLocateBegin.

Return Values

MQ_OK
Indicates success.
MQ_ERROR_INVALID_HANDLE
The query handle specified in hEnum is not valid.

Remarks

MQLocateEnd is not supported if there is no connection to the directory service. This restriction applies to dependent client computers, independent client computers (working offline), and Message Queuing routing servers (FRS). (For information on offline operations, see Message Queuing Offline Support.)

For information on | See
What information Message Queuing needs to locate queues | Locating Queues Using Function Calls
Structures used to set search criteria | Specifying Search Criteria
Structures used to set returned queue properties | Specifying Queue Properties to Retrieve

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mq.h.
Library: Use Mqrt.lib.

See Also

MQLocateBegin


MQLocateNext

The MQLocateNext function retrieves the requested queue information from the query. It is called after obtaining a query handle from a previous call to MQLocateBegin.

HRESULT APIENTRY MQLocateNext(
  HANDLE hEnum,
  DWORD *pcProps,
  MQPROPVARIANT aPropVar[]
);

Parameters

hEnum
[in] Query handle returned by a previous call to MQLocateBegin.
pcProps
[in, out] On input, a pointer to a variable that specifies the number of elements in the aPropVar[] array.

On return, pcProps holds the number of properties returned to the query. MQLocateNext returns as many completed sets of properties (the number of properties returned for each queue) as possible. A returned value of 0 indicates no queues were found.

aPropVar
[out] Holds the values of the retrieved properties in an array of MQPROPVARIANT. For each property returned, MQLocateNext sets the VT field and the corresponding union member of the appropriate aPropVar[] element. MQFreeMemory must be called to free memory allocated by Message Queuing, which happens when a MQPROPVARIANT element involves allocation of memory (for example lpwstr, GUID).

Return Values

MQ_OK
Indicates success.
MQ_ERROR_INVALID_HANDLE
The query handle specified in hEnum is not valid.
MQ_ERROR_NO_DS
Cannot access the directory service. Verify permissions for accessing the directory service.
MQ_ERROR_RESULT_BUFFER_TOO_SMALL
The supplied buffer for aPropVar is too small. MQLocateNext could not return at least one complete query result.

Remarks

The MQLocateNext function is called after obtaining a query handle from a previous call to MQLocateBegin. The call can be repeated, using the same query handle, until all the results of the query are received (until pcProps is 0).

The MQLocateNext function returns as many completed results (the number of properties requested in MQLocateBegin) as possible. Consequently, you should always specify a multiple of the number of requested properties when setting pcProps. By using a multiple of the requested properties, allocated space for these properties is not wasted.

Message Queuing returns information only for those queues for which the calling application has access rights (MQSEC_GET_QUEUE_PROPERTIES) to retrieve the queue properties. For information on access rights see, Access Control.

MQLocateBegin cannot locate public queues if there is no connection to the directory service. This restriction applies to dependent client computers, independent client computers that are working offline, and Message Queuing routing servers (FRS).

For information on offline operations, see Message Queuing Offline Support.

For information on | See
What information Message Queuing needs to locate queues | Locating Queues Using Function Calls
Structures used to set search criteria | Specifying Search Criteria
Structures used to set returned queue properties | Specifying Queue Properties to Retrieve

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mq.h.
Library: Use Mqrt.lib.

See Also

MQFreeMemory, MQGetQueueProperties, MQLocateBegin, MQLocateEnd, MQSetQueueSecurity, MQPROPVARIANT


MQOpenQueue

The MQOpenQueue function opens queues for sending, peeking at, or retrieving messages.

HRESULT APIENTRY MQOpenQueue(
  LPCWSTR lpwcsFormatName,
  DWORD dwAccess,
  DWORD dwShareMode,
  QUEUEHANDLE phQueue
);

Parameters

lpwcsFormatName
[in] Pointer to the format name string of the queue you want to open. The string can contain a single-element format name or a multiple-element format name. Single-element format names include public, private, direct, distribution list, machine, or connector format names. Multiple-element format names can contain one or more single-element format name.
dwAccess
[in] Specifies how the application accesses the queue (peek, send, or receive). This setting cannot be changed while the queue is open.

Specify one of the following access modes:

MQ_PEEK_ACCESS
Messages can only be looked at. They cannot be removed from the queue.
MQ_SEND_ACCESS
Messages can only be sent to the queue.
MQ_RECEIVE_ACCESS
Messages can be looked at and removed from the queue. Whether a message is removed from the queue or looked at depends on the dwAction parameter of MQReceiveMessage.

See the description of the dwShareMode parameter for information on limiting who can receive messages from the queue.

dwShareMode
[in] How the queue will be shared. Specify one of the following:
MQ_DENY_NONE
Default. The queue is available to everyone. This setting must be used if dwAccess is set to MQ_SEND_ACCESS.
MQ_DENY_RECEIVE_SHARE
Limits those who can receive messages from the queue to this process. Once a process opens a queue with this share mode, no one else, including the process that opened the queue, can open it again to read messages (this includes attempting to open the queue with multiple threads within the same process) until the original caller closes the queue. However, inside the process, the returned queue handle can be used by several threads.

Once the queue is opened with this share mode, the MQ_ERROR_SHARING_VIOLATION error is returned when a second attempt is made to open the queue.

Applicable only when dwAccess is set to MQ_RECEIVE_ACCESS or MQ_PEEK_ACCESS.

phQueue
[out] Pointer to a handle to the opened queue. If MQOpenQueue fails, a NULL pointer is returned.

Return Values

MQ_OK
Indicates success.
MQ_ERROR_ACCESS_DENIED
The calling process does not have the required access rights to open the queue with the access mode specified by dwAccess.
MQ_ERROR_ILLEGAL_FORMATNAME
The lpwcsFormatName parameter specified an illegal format name.
MQ_ERROR_NO_DS
Cannot access the directory service. Verify permissions for accessing the directory service.
MQ_ERROR_QUEUE_NOT_FOUND
Returned when Message Queuing cannot find the queue. This includes public queues not registered in the directory service and Internet queues that do not exist in the MSMQ namespace.
MQ_ERROR_SERVICE_NOT_AVAILABLE
Cannot connect to the queue manager.
MQ_ERROR_INVALID_PARAMETER
One of the IN parameters is not valid.
MQ_ERROR_SHARING_VIOLATION
Another process already opened this queue with dwShareMode set to MQ_DENY_RECEIVE_SHARE, or another process has already opened the queue for receive so you can't specify MQ_DENY_RECEIVE_SHARE.
MQ_ERROR_UNSUPPORTED_ACCESS_MODE
The access mode parameter (dwAccess) is set to an invalid value, or dwAcess is set to MQ_SEND_MESSAGE and the share mode parameter (dwShareMode) is set to MQ_DENY_RECEIVE_SHARE.
MQ_ERROR_UNSUPPORTED_FORMATNAME_OPERATION
The format name specified in the lpwcsFormatName parameter cannot be used.

Direct format names cannot be used if dwAccess is set to MQ_PEEK_ACCESS or MQ_RECEIVE_ACCESS. See the following Remarks section for details.

Format names that reference journal, dead-letter, or connector queues cannot be used if dwAccess is set to MQ_SEND_ACCESS.

Remarks

The MQOpenQueue function can be used to open queues for sending or reading messages. When opening queues to send messages the application can specify a one queue or several queues. When opening a queue to read messages the application can only specify one queue.

Opening Multiple Queues for Sending Messages

To open multiple queues, the application can specify a distribution list format name or multiple-element format name in the lpwcsFormatName parameter.

The main difference between distribution lists and multiple element format names is that distribution lists are public lists that are published in Active Directory and multiple-element format names are private lists that are created and maintained at the application level.

For information on distribution lists and multiple-element format names, see Sending Messages to Multiple Destinations.

Opening Queues on Remote Computers

When opening a queue to send messages to a remote computer (when dwAccess is set to MQ_SEND_ACCESS ), Message Queuing does not check for the existence of the queue.

When opening a queue to read messages from a remote computer (when dwAccess is set to MQ_RECEIVE_ACCESS or MQ_PEEK_ACCESS), the computer opening the queue must support the same protocol as the remote computer where the queue resides. To read messages from a queue on a remote computer, there must be a direct connection between the two computers.

Obtaining a Format Name

If the format name of the queue is unknown, see Obtaining Format Names.

You cannot use a direct format name to open a queue to read messages. Direct format names can only be used if dwAccess is set to MQ_SEND_ACCESS. When using a direct format name to send a message, all routing information is derived from the format name and Message Queuing sends the messages to the queue in a single hop.

Queue Access Rights

If the calling application does not have sufficient access rights to a queue, the following two things can happen:

  • If dwAccess is set to MQ_ACCESS_SEND, MQOpenQueue will succeed, but errors will be returned when the application tries to send a message.
  • If dwAccess is set to MQ_PEEK_ACCESS or MQ_RECEIVE_ACCESS, MQOpenQueue will fail and return MQ_ERROR_ACCESS_DENIED. In this case a queue handle is not returned to phQueue.

To change the access rights of the queue, call MQSetQueueSecurity. The following table lists the access right needed to open the queue in peek, send, or receive access mode.

Queue access mode | Queue access rights
MQ_PEEK_ACCESS | MQSEC_PEEK_MESSAGE
MQ_SEND_ACCESS | MQSEC_WRITE_MESSAGE
MQ_RECEIVE_ACCESS | MQSEC_RECEIVE_MESSAGE

There is no provision to change the access mode of the queue when it is open. Either close and open the queue with the desired access mode, or open a second instance of the queue.

Opening Journal, Dead-Letter, and Connector Queues

You cannot open a queue journal , computer journal, dead-letter queue or connector queue with dwAccess set to MQ_SEND_MESSAGE. These queues are read-only system queues.

Opening Foreign Queues

Foreign queues cannot be opened using a direct format name. Message Queuing needs the routing information stored in the directory service to find the appropriate connector server for the foreign queue.

Setting Share Mode

Setting dwShareMode to MQ_DENY_RECEIVE_SHARE indicates that until the calling application calls MQCloseQueue, no other Message Queuing applications can open a queue with receive access.

For Windows NT/Windows 2000

For Windows NT/Windows 2000, a queue handle is always inherited by a child process. If a child process is created by the process that opened the queue, the queue handle is inherited by the child process.

For Windows 95

For Windows 95 (with IE302 or later installed), a queue handle is not inherited by a child process.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mq.h.
Library: Use Mqrt.lib.

See Also

MQCloseQueue, MQReceiveMessage, MQSetQueueSecurity


MQPathNameToFormatName

The MQPathNameToFormatName function returns a format name based on the pathname provided.

HRESULT APIENTRY MQPathNameToFormatName(
  LPCWSTR lpwcsPathName,
  LPWSTR lpwcsFormatName,
  LPDWORD lpdwCount
);

Parameters

lpwcsPathName
[in]UNC or DNS pathname of the queue. Either private or public Message Queuing pathnames are valid.
lpwcsFormatName
[out] Pointer to a buffer to receive the format name for the queue.
lpdwCount
[in, out] On input, specifies the length of the lpwcsFormatName buffer (in Unicode characters). Public queues require at least 44 Unicode characters; private queues require at least 54.

On output, indicates the length of the returned format name string, including the null-terminating character. If the output value is greater than the initial input value, the supplied buffer is not large enough to contain the complete format name string and MQ_ERROR_FORMATNAME_BUFFER_TOO_SMALL is returned. In this case, only a portion of the format name is returned.

Return Values

MQ_OK
Indicates success.
MQ_ERROR_ILLEGAL_QUEUE_PATHNAME
The lpwcsPathName parameter contains an illegal Message Queuing pathname string.
MQ_ERROR_QUEUE_NOT_FOUND
(Public queues only) Queue is not registered in the directory service.
MQ_ERROR_SERVICE_NOT_AVAILABLE
Cannot connect to the queue manager.
MQ_ERROR_NO_DS
Cannot access the directory service. Verify permissions for accessing the directory service.
MQ_ERROR_FORMATNAME_BUFFER_TOO_SMALL
The buffer pointed to by lpwcsFormatName is too small to contain the format name string.

Remarks

Private (local only) and public Message Queuing pathnames can be specified.

Typically, this function is used when the only available information is the queue's Message Queuing pathname and you need the format name for calls to MQOpenQueue, MQGetQueueProperties, MQSetQueueProperties, MQGetQueueSecurity, or MQSetQueueSecurity.

To generate a DNS pathname for the queue, use MQGetQueueProperties to retrieve the PROPID_Q_PATHNAME_DNS property of the queue.

This function cannot be called from dependent client computers and Message Queuing routing servers (FRS). The format name of a public queue cannot be retrieved if there is no connection to the directory service.

This function cannot be called while operating offline. Message Queuing uses information stored in the directory service to generate a format name from the pathname. For information on offline operations, see Message Queuing Offline Support.

Other format name translation functions include MQInstanceToFormatName and MQHandleToFormatName.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mq.h.
Library: Use Mqrt.lib.

See Also

MQGetQueueProperties, MQGetQueueSecurity, MQHandleToFormatName, MQInstanceToFormatName, MQOpenQueue, MQSetQueueProperties, MQSetQueueSecurity


MQReceiveMessage

The MQReceiveMessage function allows you to read messages in the queue. When reading messages, you can either peek at (not removing them) or retrieve the messages (removing them) in the queue.

Messages can be read either synchronously, asynchronously, or through a transaction.

HRESULT APIENTRY MQReceiveMessage(
  QUEUEHANDLE hSource,
  DWORD dwTimeout,
  DWORD dwAction,
  MQMSGPROPS pMessageProps,
  LPOVERLAPPED lpOverlapped,
  PMQRECEIVECALLBACK fnReceiveCallback,
  HANDLE hCursor,
  Transaction *pTransaction
);

Parameters

hSource
[in] Handle to the queue that contains the message. For transactions, specify a queue on a local computer.
dwTimeout
[in] Time, in milliseconds, to wait for the message. This parameter can be set to infinite (-1), 0, or a specific amount of time. The default setting is infinite. For more information, see Remarks.
dwAction
[in] How the message is read in the queue. Specify one of the following:
MQ_ACTION_RECEIVE
Reads the message at the current cursor location and removes it from the queue.
MQ_ACTION_PEEK_CURRENT
Reads the message at the current cursor location but does not remove it from the queue. The cursor remains pointing at the current message.

If a cursor was not created by MQCreateCursor (hCursor is NULL), the queue's cursor can only point to the first message in the queue.

MQ_ACTION_PEEK_NEXT
Reads the next message in the queue (skipping the message at the current cursor location) but does not remove it from the queue.

You must call MQCreateCursor (hCursor is not NULL) before you can use MQ_ACTION_PEEK_NEXT.

pMessageProps
[in, out] On input, a pointer to an MQMSGPROPS structure that specifies which message properties will be received. Can be set to NULL.

On output, it contains the received message property values.

lpOverlapped
[in, out] Pointer to an Overlapped structure. Set to NULL for synchronous receive and transactions.
fnReceiveCallback
[in] Pointer to the callback function. Set to NULL for synchronous receive and transactions.
hCursor
[in] Handle to cursor for looking at messages in the queue. Can be set to NULL. See the following Remarks section.
pTransaction
[in] Must be a pointer to a transaction object, a constant, or NULL.

Transaction objects can be obtained internally from Message Queuing (by calling MQBeginTransaction), or externally from Microsoft® DTC (Distributed Transaction Coordinator).

Constants include:

MQ_NO_TRANSACTION
Specifies that the call is not part of a transaction.
MQ_MTS_TRANSACTION
Specifies that the current MTS (Microsoft® Transaction Server) transaction is used to retrieve the message.
MQ_XA_TRANSACTION
Specifies that the call is part of an externally coordinated, XA-compliant transaction.

NULL indicates the message is not retrieved as part of a transaction.

Return Values

MQ_OK
Indicates success.
MQ_ERROR_ACCESS_DENIED
The action specified in dwAction does not agree with the access rights the queue was opened with.
MQ_ERROR_BUFFER_OVERFLOW
A supplied buffer for a property is too small. In the case of the message body buffer, the portion of the message body that fits is copied to the buffer, but the message is not removed from the queue.
MQ_ERROR_SENDERID_BUFFER_TOO_SMALL
The supplied sender identification buffer is too small to hold the sender identification.
MQ_ERROR_SYMM_KEY_BUFFER_TOO_SMALL
The supplied symmetric key buffer is too small to hold the symmetric key.
MQ_ERROR_SENDER_CERT_BUFFER_TOO_SMALL
The supplied sender certificate buffer is too small to hold the security certificate.
MQ_ERROR_SIGNATURE_BUFFER_TOO_SMALL
The supplied signature buffer is too small to hold the message's digital signature.
MQ_ERROR_PROV_NAME_BUFFER_TOO_SMALL
The supplied provider name buffer is too small to hold the cryptographic service provider's name.
MQ_ERROR_LABEL_BUFFER_TOO_SMALL
The supplied message label buffer is too small to hold the message's label.
MQ_ERROR_FORMATNAME_BUFFER_TOO_SMALL
The supplied format name buffer is too small to hold the format name of the queue.
MQ_ERROR_DTC_CONNECT
Message Queuing was unable to connect to the MS DTC.
MQ_ERROR_INSUFFICIENT_PROPERTIES
One of the following message properties was specified (in pMessageProps) without its associated length property: PROPID_M_ADMIN_QUEUE, PROPID_M_DEST_QUEUE, PROPID_M_LABEL, PROPID_M_RESP_QUEUE, PROPID_M_XACT_STATUS_QUEUE, or PROPID_M_PROV_NAME.
MQ_ERROR_INVALID_HANDLE
The queue handle specified in hSource is not valid.
MQ_ERROR_IO_TIMEOUT
No message was received within the time-out period specified by dwTimeout.
MQ_ERROR_MESSAGE_ALREADY_RECEIVED
A message that is currently pointed at by the cursor has been removed from the queue. It can be removed by another process or by another call to MQReceiveMessage using a different cursor, or the message time-to-be-received timer has expired.
MQ_ERROR_OPERATION_CANCELLED
The operation was canceled before it could be completed. For example, the queue handle was closed by another thread while waiting for a message.
MQ_ERROR_PROPERTY
One or more message properties specified in pMessageProps resulted in an error.
MQ_ERROR_QUEUE_DELETED
The queue was deleted before the message could be read. The specified queue handle is no longer valid and the queue handle must be closed.
MQ_ERROR_ILLEGAL_CURSOR_ACTION
MQ_ACTION_PEEK_NEXT cannot be used with the current cursor position.
MQ_ERROR_SERVICE_NOT_AVAILABLE
Cannot connect to the queue manager.
MQ_ERROR_STALE_HANDLE
The specified queue handle was obtained in a previous session of the queue manager service. Close the queue and open it again to obtain a fresh handle.
MQ_ERROR_TRANSACTION_USAGE
One of the following actions were attempted within the context of a transaction.
  • An attempt was made to open a remote queue for read access.
  • An attempt was made to read a message from a non-transactional queue.
  • An attempt was made to read a message using a callback or overlap function.
MQ_INFORMATION_PROPERTY
One or more of the properties specified in pMessageProps resulted in a warning code even though the function is completed.

Remarks

All message properties can be read. However, only those properties specified in the pMessageProps parameter are returned to the calling application; other properties are simply discarded when the message is read. For example, you may choose to retrieve the size of the message without retrieving the message body itself.

When retrieving a message body, you should always look at the body type of the message before looking at the message body itself. Always retrieve PROPID_M_BODY and PROPID_M_BODY_TYPE together. If you do not check the message body type, assume that the message body is an array of bytes (the Message Queuing COM implementation does this automatically for you). Valid types are listed in the PROPID_M_BODY_TYPE reference topic.

The hCursor parameter contains the handle to a cursor created by MQCreateCursor. Using a cursor is optional and is only necessary when you want to read messages that are not at the front of the queue. When using a cursor, you must peek at the first message in the queue by setting dwAction to MQ_ACTION_PEEK_CURRENT before you make calls with dwAction set to MQ_ACTION_PEEK_NEXT. For more information, see Navigating with Cursors.

To retrieve the message body, you must specify PROPID_M_BODY in pMessageProps. The VT field of the corresponding element in the aPropVar array should be set to VT_UI1 | VT_VECTOR, allowing Message Queuing to use the buffer specified in CAUI1 to store the message. If the supplied buffer is too small to contain the entire message body, MQReceiveMessage fails and MQ_ERROR_BUFFER_OVERFLOW is returned. The buffer is filled to capacity, and the full message remains in the queue. When this happens, the other properties specified by pMessageProps are still read.

To retrieve the size of the message, specify PROPID_M_BODY_SIZE in pMessageProps. Message Queuing sets PROPID_M_BODY_SIZE to the size of the message body, even if MQReceiveMessage fails because the message body exceeded the buffer allocated by PROPID_M_BODY. When retrieving the message body size, the CAUI1 structure associated with the PROPID_M_BODY property does not indicate the size. The cElems field of the CAUI1 structure merely indicates the maximum message body, which could be copied into the pElems buffer. The cElems field is never modified by Message Queuing.

Not all properties require the application to specify the property type in the VT field of the aPropVar array. For these properties, the corresponding VT field in the aPropVar array can be set to VT_NULL.

The dwTimeout parameter can be set to the following values:

  • Infinite (-1): processing is blocked until a message is in the queue (this is the default setting).
  • "0": a messages is read if one exists or an MQ_ERROR_IO_TIMEOUT error is returned immediately.
  • A positive amount of time (in milliseconds): Message Queuing waits for a message for the specified amount of time.

Messages cannot be read from a queue that resides on a computer without a direct connection. Opening a queue with receive or peek access requires a direct connection to the computer where the queue resides.

To synchronously read messages, set fnReceiveCallback and lpOverlapped to NULL. When this is done, the calling thread is blocked until a suitable message is available or a time-out occurs. For information on reading message synchronously, see Synchronous Reading.

When asynchronously reading messages, MQReceiveMessage returns a SUCCESS value if a suitable message is found. Otherwise, MQReceiveMessage returns immediately with the return value MQ_INFORMATION_OPERATION_PENDING. This return value indicates that the operation is pending and will be completed as soon as a suitable message can be found.

To cancel a pending asynchronous receive call, call CancelIo or MQCloseQueue. The CancelIo function cancels all pending input and output (I/O) operations that were issued by the calling thread. The MQCloseQueue function cancels all input and output (I/O) operations for the given queue handle.

Asynchronous receive is based on standard Microsoft® Win32® mechanisms.

Applications can use a callback function, a Windows Event mechanism, or a Microsoft® Windows NT®/Windows® 2000 completion port to read messages asynchronously.

The output parameters to an asynchronous call to MQReceiveMessage should be kept intact until the operation is complete (that is, you cannot free them or reuse them). Use automatic variables with caution.

When using a callback function, you can register only 64 callbacks at the same time. Internally, Message Queuing uses the WaitForMultipleObjects API which is limited to 64 objects per process.

Completion ports cannot be used by dependent client applications. On Message Queuing independent clients and servers, queue handles are implemented as Windows NT/Windows 2000 file handles and so, can be associated with completion ports. However, on dependent clients, queue handles are not file handles and as a result, cannot be used with completion ports.

Reading Message in Transactions

If MQReceiveMessage is called as part of a transaction (pTransaction is not set to MQ_NO_TRANSACTION or NULL), the following parameters must be set accordingly:

  • The lpOverlapped and fnReceiveCallback parameters must be set to NULL. The operation must be synchronous receive.
  • The hSource parameter must specify a queue on the local computer.

Messages cannot be retrieved from remote queues within a transaction.

When the call is made, Message Queuing performs the following tasks.

  • In the case of a subsequent Abort, the message is returned to its original place in the queue.
  • In the case of a Commit, a positive acknowledgment message is sent to the sender's administration queue. The class property of the acknowledgment message is MQMSG_CLASS_ACK_RECEIVE.

Transaction objects cannot be reused after you commit to or abort the transaction. If you release the transaction object without calling Commit or Abort, the transaction is aborted for you. For more information, see Message Queuing Transactions.

Messages in Administration Queues

When reading acknowledgment messages in an administration queue, you can see if the original message failed to reach its destination or was not retrieved from the queue by looking at the class property (PROPID_M_CLASS) of the acknowledgment message. The class property will contain a positive or negative acknowledgment, depending on the acknowledgment level specified by the original message.

If the class property is positive, the original message body is not included in the acknowledgment message. If the class property is negative, the message body is included as the message body of the acknowledgment message. For a complete description of all the properties of the acknowledgment message, see Acknowledgment Messages.

Responding to Messages

The receiving application can determine if the sending application expects a response by retrieving the PROPID_M_RESP_QUEUE and PROPID_M_RESP_QUEUE_LEN property when reading a message. PROPID_M_RESP_QUEUE contains the format name of a response queue if a response is requested. For information on how to respond, see Response Messages.

Note When opening a response queue to send several response messages, the receiving application can cache the queue handle returned by MQOpenQueue, thus eliminating the need to call MQOpenQueue several times for the same response queue.

For information on | See
How Message Queuing sets the body type of a message | Message Body Types

For a complete example of | See
Reading the first message in a queue synchronously | Reading Messages Synchronously

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mq.h.
Library: Use Mqrt.lib.

See Also

aPropVar, MQBeginTransaction, MQCreateCursor, MQMSGPROPS, MQOpenQueue, MQPROPVARIANT, MQSetQueueSecurity, PROPID_M_ADMIN_QUEUE, PROPID_M_BODY, PROPID_M_BODY_SIZE, PROPID_M_CLASS, PROPID_M_DEST_QUEUE, PROPID_M_LABEL, PROPID_M_PROV_NAME, PROPID_M_RESP_QUEUE, PROPID_M_XACT_STATUS_QUEUE


MQReceiveMessageByLookupId

(Introduced in MSMQ 3.0.) The MQReceiveMessageByLookupId function reads a specific message in the queue. Messages can be referenced by their lookup identifier or by their position at the front or end of the queue.

Messages can be read asynchronously, synchronously, or through a transaction.

HRESULT APIENTRY MQReceiveMessageByLookupId(
  QUEUEHANDLE hSource,
  ULONGLONG ullLookupId
  DWORD dwLookupAction,
  MQMSGPROPS* pMessageProps,
  LPOVERLAPPED lpOverlapped,
  PMQRECEIVECALLBACK fnReceiveCallback,
  Transaction *pTransaction
);

Parameters

hSource
[in] Handle to the queue that contains the message. For transactions, specify a queue on a local computer.
ullLookupId
[in] The lookup identifier of the message or 0 ("0" is used when accessing the first or last message in the queue).
dwLookupAction
[in] How the message is read in the queue. Specify one of the following:
MQ_LOOKUP_PEEK_FIRST
Peeks at the first message in the queue but does not remove it from the queue. The ullLookupId parameter must be set to 0.
MQ_LOOKUP_PEEK_PREV
Peeks at the message preceding the message specified by ullLookupId but does not remove it from the queue.
MQ_LOOKUP_PEEK_CURRENT
Peeks at the message specified by ullLookupId but does not remove it from the queue.
MQ_LOOKUP_PEEK_NEXT
Peeks at the message following the message specified by ullLookupId but does not remove it from the queue.
MQ_LOOKUP_PEEK_LAST
Peeks at the last message in the queue but does not remove it from the queue. The ullLookupId parameter must be set to 0.
MQ_LOOKUP_RECEIVE_FIRST
Retrieves the first message in the queue and removes it from the queue. The ullLookupId parameter must be set to 0.
MQ_LOOKUP_RECEIVE_PREV
Retrieves the message preceding the message specified by ullLookupId and removes it from the queue.
MQ_LOOKUP_RECEIVE_CURRENT
Retrieves the message specified by ullLookupId and removes it from the queue.
MQ_LOOKUP_RECEIVE_NEXT
Retrieves the message following the message specified by ullLookupId and removes it from the queue.
MQ_LOOKUP_RECEIVE_LAST
Retrieves the last message in the queue and removes it from the queue. The ullLookupId parameter must be set to 0.
pMessageProps
[in, out] On input, a pointer to an MQMSGPROPS structure that specifies which message properties will be retrieved. Can be set to NULL.

On output, pMessageProps contains the retrieved message property values.

lpOverlapped
[in, out] Pointer to an Overlapped structure. Set to NULL for synchronous receive and transactions.
fnReceiveCallback
[in] Pointer to the callback function. Set to NULL for synchronous receive and transactions.
pTransaction
[in] Must be a pointer to a transaction object, a constant, or NULL.

Transaction objects can be obtained internally from Message Queuing (by calling MQBeginTransaction), or externally from Microsoft® DTC (Distributed Transaction Coordinator).

Constants include:

MQ_NO_TRANSACTION
Specifies that the call is not part of a transaction.
MQ_MTS_TRANSACTION
Specifies that the current MTS (Microsoft® Transaction Server) transaction is used to retrieve the message.
MQ_XA_TRANSACTION
Specifies that the call is part of an externally coordinated, XA-compliant transaction.

NULL indicates the message is not retrieved as part of a transaction.

Return Values

MQ_OK
Indicates success.
MQ_ERROR_ACCESS_DENIED
The user that opened the queue does not have access rights for the action specified in dwLookupAction.
MQ_ERROR_BUFFER_OVERFLOW
A supplied buffer for a property is too small. In the case of the message body buffer, the portion of the message body that fits is copied to the buffer, but the message is not removed from the queue.
MQ_ERROR_MESSAGE_NOT_FOUND
The message referenced by the lookup identifier in does not exist. Either the lookup identifier is incorrect or the message has been removed from the queue.
MQ_ERROR_SENDERID_BUFFER_TOO_SMALL
The supplied sender identification buffer is too small to hold the sender identification.
MQ_ERROR_SYMM_KEY_BUFFER_TOO_SMALL
The supplied symmetric key buffer is too small to hold the symmetric key.
MQ_ERROR_SENDER_CERT_BUFFER_TOO_SMALL
The supplied sender certificate buffer is too small to hold the security certificate.
MQ_ERROR_SIGNATURE_BUFFER_TOO_SMALL
The supplied signature buffer is too small to hold the message's digital signature.
MQ_ERROR_PROV_NAME_BUFFER_TOO_SMALL
The supplied provider name buffer is too small to hold the cryptographic service provider's name.
MQ_ERROR_LABEL_BUFFER_TOO_SMALL
The supplied message label buffer is too small to hold the message's label.
MQ_ERROR_FORMATNAME_BUFFER_TOO_SMALL
The supplied format name buffer is too small to hold the format name of the queue.
MQ_ERROR_DTC_CONNECT
Message Queuing was unable to connect to the MS DTC.
MQ_ERROR_INSUFFICIENT_PROPERTIES
A property was specified in pMessageProps without its associated length property.
MQ_ERROR_INVALID_HANDLE
The queue handle specified in hSource is not valid.
MQ_ERROR_OPERATION_CANCELLED
The operation was canceled before it could be completed. For example, the queue handle was closed by another thread while waiting for a message.
MQ_ERROR_PROPERTY
One or more message properties specified in pMessageProps resulted in an error.
MQ_ERROR_QUEUE_DELETED
The queue was deleted before the message could be read. The specified queue handle is no longer valid and the queue handle must be closed.
MQ_ERROR_SERVICE_NOT_AVAILABLE
Cannot connect to the queue manager.
MQ_ERROR_STALE_HANDLE
The specified queue handle was obtained in a previous session of the queue manager service. Close the queue and open it again to obtain a fresh handle.
MQ_ERROR_TRANSACTION_USAGE
One of the following actions were attempted within the context of a transaction.
  • An attempt was made to open a remote queue for read access.
  • An attempt was made to read a message from a non-transactional queue.
  • An attempt was made to read a message using a callback or overlap function.
MQ_INFORMATION_PROPERTY
One or more of the properties specified in pMessageProps resulted in a warning code even though the function is completed.

Remarks

The MQReceiveMessageByLookupId function is used by the receiving application to peek at or retrieve the messages in the queue. This function can be used to go directly to any message in the queue, and then navigate to the preceding or following messages.

The lookup identifier of a message (PROPID_M_LOOKUPID) is generated by message Queuing when the message is placed in the queue (this is not the message identifier generated when the message is sent). Lookup identifiers are assigned to all messages that are put in application-generated destination, administration, and report queues, as well as system-generated journal, dead-letter, and connector queues. The lookup identifier is unique to the queue and has no meaning outside the queue.

When retrieving messages using MQReceiveMessageByLookupId there is no receive time-out functionality as provided in MQReceiveMessage. The message must exist when MQReceiveMessageByLookupId is called. If the message does not exist, an MQ_ERROR_MESSAGE_NOT_FOUND error is returned and the call fails.

Requirements

Windows NT/2000 or later: Requires Whistler.
Windows 95/98/Me: Unsupported.
Header: Declared in Mq.h.
Library: Use Mqrt.lib.

See Also

MQReceiveMessage, PROPID_M_LOOKUPID


MQRegisterCertificate

The MQRegisterCertificate function registers an internal or external certificate in the directory service.

HRESULT APIENTRY MQRegisterCertificate(
  DWORD dwFlags,
  PVOID lpCertBuffer,
  DWORD dwCertBufferLength
);

Parameters

dwFlags
[in] Specifies when the certificate is registered

Specify one of the following:

MQCERT_REGISTER_ALWAYS
Registers an internal or external certificate each time MQRegisterCertificate is called.

For internal certificates (lpCertBuffer = NULL), a new certificate is created and registered, deleting any existing certificate.

For external certificates, this option must be set.

MQCERT_REGISTER_IF_NOT_EXIST
Registers an internal certificate only when none exist. This option cannot be used when registering external certificates.

If an internal certificate is found, the certificate is not registered. In this case, the call succeeds and the MQ_INFORMATION_INTERNAL_USER_CERT_EXIST information code is returned.

Checking for an existing certificate is done locally, without querying the directory service.

lpCertBuffer
[in] Pointer to the buffer that contains the certificate blob of an external certificate, or NULL if registering an internal certificate. External certificates must be in ASN.1 DER encoded format.
dwCertBufferLength
[in] The length of the certificate buffer. For internal certificates, specify 0.

Return Values

MQ_OK
Indicates success.
MQ_ERROR_CANNOT_CREATE_CERT_STORE
Message Queuing cannot create a certificate store for its internal certificate. This error is returned only when you do not have permission to manipulate your own profile.
MQ_ERROR_CANNOT_OPEN_CERT_STORE
Message Queuing cannot open the certificate store for its internal certificate. This error is only returned only when you do not have permission to manipulate your own profile.
MQ_ERROR_ILLEGAL_USER
User is not a domain user. You must be a domain user to be able to register a certificate.
MQ_ERROR_INVALID_PARAMETER.
A supplied parameter is not set to a valid value. For example, dwCertBufferLength is set to 0 and lpCertBuffer points to a buffer containing an external certificate.
MQ_INFORMATION_INTERNAL_USER_CERT_EXIST
An internal certificate already exists. This information code does not indicate an error condition. It is returned when dwFlags is set to MQ_REGISTER_IF_NOT_EXIST.

Remarks

Message Queuing can only register external certificates placed in the Microsoft Internet Explorer personal certificate store. To obtain an external certificate, contact a trusted certification authority. For example, request a class 1 certificate from VeriSign Commercial Software Publishers using Microsoft® Internet Explorer. If Internet Explorer is used to obtain the certificate, the certificate is automatically placed in the Microsoft Internet Explorer personal certificate store.

Certificates can also be registered using MS Message Queue in the Control Panel. To register a certificate in MS Message Queue, go to the Security page and click Register.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Mq.h.
Library: Use Mqrt.lib.

See Also

MQGetSecurityContext, MQSendMessage


MQSendMessage

The MQSendMessage function sends a message to the queue corresponding to the handle hDestinationQueue.

HRESULT APIENTRY MQSendMessage(
  QUEUEHANDLE hDestinationQueue,
  MQMSGPROPS *pMessageProps,
  ITransaction *pTransaction
);

Parameters

hDestinationQueue
[in] Handle to the queue where you want to send the message.
pMessageProps
[in] Pointer to an MQMSGPROPS structure describing the message to send.
pTransaction
[in] Must be a pointer to a transaction object, a constant, or NULL.

Transaction object can be obtained internally from Message Queuing (by calling MQBeginTransaction) or externally from Microsoft® Distributed Transaction Coordinator (MS DTC).

Constants include:

MQ_NO_TRANSACTION
Specifies that the call is not part of a transaction.
MQ_MTS_TRANSACTION
Specifies that the current Microsoft Transaction Server (MTS) transaction is used to send the message.
MQ_SINGLE_MESSAGE
Specifies a single-message transaction. Messages sent as a single message transaction must be sent to a transactional queue.
MQ_XA_TRANSACTION
Specifies that the call is part of an externally coordinated, XA-compliant transaction.

NULL indicates the message is not sent as part of a transaction.

Return Values

MQ_OK
Indicates success.
MQ_ERROR_ACCESS_DENIED
The queue was not opened with MQ_SEND_ACCESS rights.
MQ_ERROR_BAD_SECURITY_CONTEXT
The security context buffer (PROPID_M_SECURITY_CONTEXT) is corrupted.
MQ_ERROR_CERTIFICATE_NOT_PROVIDED
The security context does not include a certificate.
MQ_ERROR_CORRUPTED_INTERNAL_CERTIFICATE
(MSMQ 1.0 only) The internal security certificate provided by Message Queuing is corrupted. Register the internal certificate again using MSMQ Control Panel.
MQ_ERROR_CORRUPTED_PERSONAL_CERT_STORE
The Microsoft® Internet Explorer personal certificate store is corrupted.
MQ_ERROR_CORRUPTED_SECURITY_DATA
The operating system encountered an error when calling one of the cryptographic functions (CryptoAPI).
MQ_ERROR_COULD_NOT_GET_USER_SID
MQSendMessage could not retrieve the user identifier specified by PROPID_M_SENDERID.
MQ_ERROR_DTC_CONNECT
Message Queuing was unable to connect to MS DTC.
MQ_ERROR_ILLEGAL_FORMATNAME
Format name specified in PROPID_M_ADMIN_QUEUE or PROPID_M_RESP_QUEUE is illegal.
MQ_ERROR_INSUFFICIENT_RESOURCES
Insufficient resources to complete operation (for example, an attempt was made to send a message whose body contained more than 4 MB of data). Operation failed.
MQ_ERROR_INVALID_CERTIFICATE
The external security certificate passed in PROPID_M_SENDER_CERT is not valid. The certificate is corrupted or not placed in the Microsoft Internet Explorer personal certificate store.
MQ_ERROR_INVALID_HANDLE
The queue handle specified in hDestinationQueue is not valid.
MQ_ERROR_INVALID_PARAMETER
one or more of the input parameters are not valid (for MSMQ 1.0, this error is returned if authentication is requested but there is no internal certificate registered).
MQ_ERROR_MESSAGE_STORAGE_FAILED
A recoverable message (PROPID_M_DELIVERY is set to MQMSG_DELIVERY_RECOVERABLE) could not be stored on the local computer.
MQ_ERROR_NO_NTERNAL_USER_CERT
No internal certificate is registered, or the registered certificate is corrupted.
MQ_ERROR_PROPERTY
One or more properties resulted in an error.
MQ_ERROR_SERVICE_NOT_AVAILABLE
Cannot connect to the queue manager.
MQ_ERROR_STALE_HANDLE
The specified queue handle was obtained in a previous session of the queue manager service. Close the queue and open it again to obtain a fresh handle.
MQ_ERROR_TRANSACTION_USAGE
Transaction error. An attempt was made to open a remote queue for read access from within a transaction, or an attempt was made from within a transaction to read a message from a non-transactional queue.
MQ_INFORMATION_PROPERTY
One or more of the properties resulted in a warning even though the function completed.

Remarks

Each Message Queuing message can have no more than 4 MB of data.

The PROPID_M_BODY property is a CAUI1 structure that contains the message body. The caui1.cElems field of this structure represents the size of the message body.

All message properties can be attached to a message. Some are attached by Message Queuing, and others can be attached by the sending application.

When sending messages, you should always specify the body type of the message that is being sent. Set PROPID_M_BODY_TYPE to one of the Variant types supported by Message Queuing. These types are listed in the PROPID_M_BODY_TYPE reference topic.

To save a copy of a message after it is successfully sent, set PROPID_M_JOURNAL to MQMSG_JOURNAL or MQMSG_JOURNAL | MQMSG_DEADLETTER and attach it to the message.

To save a copy of a message if it does not reach its destination, set PROPID_M_JOURNAL to MQMSG_DEADLETTER or MQMSG_JOURNAL | MQMSG_DEADLETTER and attach it to the message.

When sending authenticated messages or impersonating another user, you must call MQGetSecurityContext and MQSendMessage in the same user context.

If the send operation is part of a transaction (pTransaction is not set to MQ_NO_TRANSACTION or NULL), the hDestinationQueue parameter must refer to a transactional queue. As part of a transaction, messages are not sent until Commit is called.

Transaction objects cannot be reused after you commit to or abort the transaction. If you release the transaction object without calling Commit or Abort, the transaction is aborted for you.

The sending application can receive two types of messages in response to the messages it sends:

  • If PROPID_M_RESP_QUEUE is passed to MQSendMessage, the receiving application can send application-defined response messages back to a response queue.
  • If PROPID_M_ADMIN_QUEUE and PROPID_M_ACKNOWLEDGE are passed to MQSendMessage, Message Queuing can return acknowledgment messages back to an administration queue.

PROPID_M_RESP_QUEUE can also be used to send the format name of a private queue to another application. This is typically done when the sending application wants to make a private queue available to other applications.

For information on | See
How Message Queuing sets the body type of a message | Message Body Types
Tracking messages using source journaling | Source Journaling
How Message Queuing authenticates messages | Message Authentication
How Message Queuing responds to messages | Response Messages
Message Queuing Transactions | Message Queuing Transactions

For an example of | See
Sending a message that requests a response message from the receiving application. | Requesting Response Messages
Using a single message (internal) transaction to send a message | Sending a Message Using a Single Message Transaction
Using a Message Queuing internal transaction to send a message | Sending a Message Using an Internal Transaction
Using an MS DTC external transaction to send a message | Sending a Message Using an MS DTC External Transaction

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mq.h.
Library: Use Mqrt.lib.

See Also

MQBeginTransaction, MQGetSecurityContext, MQMSGPROPS, MQSendMessage, MQSetQueueSecurity, PROPID_M_ACKNOWLEDGE, PROPID_M_ADMIN_QUEUE, PROPID_M_BODY, PROPID_M_BODY_SIZE, PROPID_M_CLASS, PROPID_M_DELIVERY, PROPID_M_JOURNAL, PROPID_M_MSGID, PROPID_M_PRIORITY, PROPID_M_RESP_QUEUE, PROPID_M_SECURITY_CONTEXT, PROPID_M_SENDERID, PROPID_M_SENTTIME, PROPID_M_TIME_TO_BE_RECEIVED, PROPID_M_TIME_TO_REACH_QUEUE


MQSetQueueProperties

The MQSetQueueProperties function sets the properties of a specific queue.

HRESULT APIENTRY MQSetQueueProperties(
  LPCWSTR lpwcsFormatName,
  MQQUEUEPROPS *pQueueProps
);

Parameters

lpwcsFormatName
[in] Pointer to the format name string of the queue whose properties will be set. Use only public or private format name to specify the queue.
pQueueProps
[in] Pointer to the MQQUEUEPROPS structure that specifies the properties to be set.

On input, the cProp member of MQQUEUEPROPS specifies the number of properties to be set, the aPropID array specifies their property identifiers, and the aPropVar array indicates the new values of the specified properties.

On output, the optional aStatus array, if it was included in MQQUEUEPROPS, indicates the status of the properties.

Return Values

MQ_OK
Indicates success.
MQ_ERROR_ACCESS_DENIED
The process does not have the sufficient access rights to set the properties of the queue. For a complete list of queue access rights, see Access Control.

To change access rights, call MQSetQueueSecurity.

MQ_ERROR_ILLEGAL_FORMATNAME
The lpwcsFormatName parameter specified an illegal format name.
MQ_ERROR_ILLEGAL_PROPERTY_VALUE
An illegal property value is specified.
MQ_ERROR_NO_DS
Cannot access the directory service. Verify permissions for accessing the directory service.
MQ_ERROR_PROPERTY
One or more properties resulted in error.
MQ_ERROR_SERVICE_NOT_AVAILABLE
Cannot connect to the queue manager.
MQ_ERROR_UNSUPPORTED_FORMATNAME_OPERATION
The format name specified by the lpwcsFormatName parameter cannot be used. You cannot reference a queue using a direct format name, nor can you set the queue properties of a journal, dead-letter, or connector queue.
MQ_ERROR_WRITE_NOT_ALLOWED
Cannot set the properties for a queue in the directory service.
MQ_INFORMATION_PROPERTY
One or more of the properties resulted in a warning even though the function completed.

Remarks

The following queue properties cannot be set by MQSetQueueProperties.

Property Name | Reason
PROPID_Q_BASEPRIORITY | For public queues only. Cannot be set for private queues.
PROPID_Q_CREATE_TIME | Set by Message Queuing.
PROPID_Q_INSTANCE | Set by Message Queuing.
PROPID_Q_MODIFY_TIME | Set by Message Queuing.
PROPID_Q_PATHNAME | Can only be set when the queue is created.
PROPID_Q_TRANSACTION | Can only be set when the queue is created.

When setting the properties of a public queue, some clients may still see the old settings registered in the directory service after the properties have been changed. Changes to the directory service (such as setting properties) are propagated from domain controller to domain controller, which can cause delays in the availability of new information. Consequently, clients using a specific domain controller may still see the old property settings, even though the settings of the properties were changed by MQSetQueueProperties. Propagation delays, including communication network delays such as down links, are controlled by the Message Queuing administrator.

A public queue's properties cannot be set if there is no connection to the directory service. This restriction applies to dependent client computers, independent client computers that are working offline, and Message Queuing routing servers (FRS).

For information on | See
A complete list of queue properties | Message Queuing Properties
Obtaining a format name for opening a queue | Obtaining Format Names
Offline operations | Message Queuing Offline Support

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mq.h.
Library: Use Mqrt.lib.

See Also

aPropID, aPropVar, aStatus, MQGetQueueProperties, MQQUEUEPROPS, MQSetQueueSecurity


MQSetQueueSecurity

The MQSetQueueSecurity function sets the access control security for the queue.

HRESULT APIENTRY MQSetQueueSecurity(
  LPCWSTR lpwcsFormatName,
  SECURITY_INFORMATION SecurityInformation,
  PSECURITY_DESCRIPTOR pSecurityDescriptor
);

Parameters

lpwcsFormatName
[in] Pointer to the format name string of the queue to be secured. Use only public or private format names.
SecurityInformation
[in] Specifies a SECURITY_INFORMATION structure identifying the contents of the security descriptor pointed to by the pSecurityDescriptor parameter.
pSecurityDescriptor
[in] Pointer to a SECURITY_DESCRIPTOR structure. Can be set to NULL; see default values in the following Remarks section.

Return Values

MQ_OK
Indicates success.
MQ_ERROR_ACCESS_DENIED
The process owner does not have the sufficient access rights to set the queue security information. The following access rights may be required:
  • MQSEC_CHANGE_QUEUE_PERMISSIONS
  • MQSEC_TAKE_QUEUE_OWNERSHIP

If access is denied, contact someone who has rights to modify the security descriptor.

MQ_ERROR_FUNCTION_NOT_SUPPORTED
MQSetQueueSecurity is not supported in Windows 95.
MQ_ERROR_ILLEGAL_FORMATNAME
The lpwcsFormatName parameter specified an illegal format name.
MQ_ERROR_NO_DS
Cannot access the directory service. Verify permissions for accessing the directory service.
MQ_ERROR_PRIVILEGE_NOT_HELD
The process owner does not have the proper privilege to set the queue's system access control list.
MQ_ERROR_SERVICE_NOT_AVAILABLE
Cannot connect to the queue manager.
MQ_ERROR_UNSUPPORTED_FORMATNAME_OPERATION
The format name specified in the lpwcsFormatName parameter cannot be used. You cannot reference a queue using a direct format name, nor can you set the security rights of a journal, dead-letter, or connector queue.
MQ_INFORMATION_OWNER_IGNORED
MQSetQueueSecurity did not set the owner of the queue; however, it did set the other elements identified in the SECURITY_INFORMATION structure.

Remarks

The following access rights and privileges are required to change the security descriptor of a queue.

Access right/privilege | Required to
MQSEC_TAKE_ QUEUE_OWNERSHIP | Change the owner of the queue. This access right is equivalent to WRITE_OWNER as defined by the Win32 header files.
SE_TAKE_ OWNERSHIP_NAME | Change the owner of the queue. This privilege can be used instead of having the MQSEC_TAKE_QUEUE_OWNERSHIP access on the queue. If a user has this privilege on the server, the user can change the owner of any public queue in the enterprise. If the user has this privilege on the local computer, the user can change the owner of any private queue.
MQSEC_CHANGE_ QUEUE_PERMISSIONS | Change the queue's discretionary access control list (DACL) if the process is not the owner of the queue. This access right is equivalent to WRITE_DAC as defined by the Win32 header files.
SE_SECURITY_NAME | Change the queue's system ACL (SACL); this privilege must be enabled for the calling process on the directory service for public queues and on the local computer for private queues.

All queues must be referenced using a public or private format name. Message Queuing must be able to access the directory service for public queues, or the local computer for private queues. If the format name of the queue is unknown, see Obtaining Format Names.

The security descriptors of journal, dead-letter, connector, and foreign queues cannot be set.

A public queue's access security cannot be set if there is no connection to the directory service. This restriction applies to dependent client computers, independent client computers that are working offline, and Message Queuing routing servers (FRS). (For information on offline operations, see Message Queuing Offline Support.)

Following are the default values for the security descriptor.

Default Value | Meaning
Owner | The process user.
Group | The process group.
DACL | Full control for the process user. All processes of other users can get queue properties, get queue security, and send messages to the queue.
SACL | None.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mq.h.
Library: Use Mqrt.lib.

See Also

MQGetQueueSecurity


Message Queuing Properties

Message Queuing uses message, queue, and machine properties to specify the characteristics of messages, queues, and machines. A property can be an IN property, an OUT property, or both, depending on how it is used.

Message Queuing properties include the following.

Message properties | Description
PROPID_M_ACKNOWLEDGE | Specifies the type of acknowledgment messages returned to the sending application.
PROPID_M_ADMIN_FORMAT_NAME | (Introduced in MSMQ 3.0.) Specifies the administration queues used for returned acknowledgment messages.
PROPID_M_ADMIN_FORMAT_NAME_LEN | (Introduced in MSMQ 3.0.) Specifies the length of the administration queue buffer specified in PROPID_M_ADMIN_FORMAT_NAME.
PROPID_M_ADMIN_QUEUE | Specifies one administration queue used for returned acknowledgment messages.
PROPID_M_ADMIN_QUEUE_LEN | Specifies the length of the administration queue buffer specified in PROPID_M_ADMIN_QUEUE.
PROPID_M_APPSPECIFIC | Specifies application-generated information.
PROPID_M_ARRIVEDTIME | Indicates when the message arrived at the queue.
PROPID_M_AUTH_LEVEL | Specifies the authentication level of the message.
PROPID_M_AUTHENTICATED | Indicates whether the sending application requested authentication.
PROPID_M_AUTHENTICATED_EX | Indicates whether the sending application requested authentication and what type of signature was used. (MSMQ 2.0 only.)
PROPID_M_BODY | Contains the body of the message.
PROPID_M_BODY_SIZE | Indicates the actual size of the message body.
PROPID_M_BODY_TYPE | Indicates the type of body the message contains.
PROPID_M_CLASS | Indicates the type of message.
PROPID_M_CONNECTOR_TYPE | Indicates the connector used to route messages to a foreign queue.
PROPID_M_CORRELATIONID | Specifies the application-generated correlation identifier of the message.
PROPID_M_DELIVERY | Specifies how the message is delivered.
PROPID_M_DEST_QUEUE | Identifies the destination queue of the message.
PROPID_M_DEST_QUEUE_LEN | Indicates the length of the format name buffer for the destination queue.
PROPID_M_DEST_SYMM_KEY | Specifies the symmetric key used to encrypt messages sent to a foreign queue.
PROPID_M_DEST_SYMM_KEY_LEN | Specifies the length of the symmetric key used to encrypt message sent to a foreign queue.
PROPID_M_ENCRYPTION_ALG | Specifies the encryption algorithm used when encrypting private and authenticated messages.
PROPID_M_EXTENSION | Provides a place to put additional information associated with the message.
PROPID_M_EXTENSION_LEN | Specifies the length of the extension informationproperty.
PROPID_M_FIRST_IN_XACT | Indicates whether the message was the first message in a transaction. (MSMQ 2.0 only.)
PROPID_M_HASH_ALG | Identifies the hashing algorithm used when authenticating messages.
PROPID_M_JOURNAL | Specifies if the message should be kept in a Computer journal, sent to a dead-letter queue, or neither.
PROPID_M_LABEL | Specifies a description of the message.
PROPID_M_LABEL_LEN | Identifies the length of the message label buffer.
PROPID_M_LAST_IN_XACT | Indicates whether the message was the last message in a transaction. (MSMQ 2.0 only.)
PROPID_M_MSGID | Identifies the identifier of the message (GUID).
PROPID_M_PRIORITY | Specifies the priority level of the message.
PROPID_M_PRIV_LEVEL | Specifies the privacy level of the message to be sent.
PROPID_M_PROV_NAME | Specifies the name of the cryptographic provider used to generate the digital signature of a message.
PROPID_M_PROV_NAME_LEN | Identifies the length of the name of the cryptographic provider used for validating the digital signature of a message.
PROPID_M_PROV_TYPE | Specifies the type of cryptographic provider used to generate the digital signature of a message.
PROPID_M_RESP_QUEUE | Specifies the response queue used for returning response messages.
PROPID_M_RESP_QUEUE_LEN | Specifies the length of the format name of the response queue.
PROPID_M_SECURITY_CONTEXT | Specifies security context information taken from a security certificate.
PROPID_M_SENDER_CERT | Specifies the external certificate used to authenticate messages.
PROPID_M_SENDER_CERT_LEN | Specifies the length of the external certificate buffer.
PROPID_M_SENDERID | Identifies who sent the message.
PROPID_M_SENDERID_LEN | Indicates the length of the sender identifier.
PROPID_M_SENDERID_TYPE | Specifies the type of sender identifier.
PROPID_M_SENTTIME | Indicates the date and time that the message was sent by the source queue manager.
PROPID_M_SIGNATURE | Specifies the digital signature used to authenticate the message.
PROPID_M_SIGNATURE_LEN | Specifies the length of digital signature.
PROPID_M_SRC_MACHINE_ID | Specifies the computer where the message originated.
PROPID_M_TIME_TO_BE_RECEIVED | Specifies the total time the message is allowed to live.
PROPID_M_TIME_TO_REACH_QUEUE | Specifies a time limit for the message to reach the queue.
PROPID_M_TRACE | Specifies where report messages are sent when tracing a message.
PROPID_M_VERSION | Reserved for future use.
PROPID_M_XACTID | Indicates the transaction identifier for the message. (MSMQ 2.0 only.)
PROPID_M_XACT_STATUS_QUEUE | Identifies the transaction status queue on the source computer.
PROPID_M_XACT_STATUS_QUEUE_LEN | Indicates the length of the format name buffer of the transaction status queue.

Local computer properties | Description
PROPID_PC_DS_ENABLED | (MSMQ 2.0 only) Indicates if a directory service is available to Message Queuing.
PROPID_PC_VERSION | (MSMQ 2.0 only) Indicates the version of Message Queuing installed.

Queue properties | Description
PROPID_Q_AUTHENTICATE | Specifies the authentication level of the queue.
PROPID_Q_BASEPRIORITY | Specifies the priority level of the queue.
PROPID_Q_CREATE_TIME | Read-only. Indicates when the queue was created.
PROPID_Q_INSTANCE | Read-only. Indicates the identifier (GUID) for the queue.
PROPID_Q_JOURNAL | Specifies the journaling level of the queue.
PROPID_Q_JOURNAL_QUOTA | Specifies the maximum size of the queue journal.
PROPID_Q_LABEL | Specifies a descriptive label for the queue.
PROPID_Q_MODIFY_TIME | Read-only. Indicates the last time the properties of the queue were modified.
PROPID_Q_PATHNAME | Required. Specifies the pathname of the queue.
PROPID_Q_PATHNAME_DNS | Read-only. Indicates the DNS pathname of the queue. (MSMQ 2.0 only.)
PROPID_Q_PRIV_LEVEL | Specifies the privacy level of the queue.
PROPID_Q_QUOTA | Specifies the maximum size of the queue.
PROPID_Q_TRANSACTION | Specifies the transaction level of the queue.
PROPID_Q_TYPE | Specifies the type of service provided by the queue.

Queue manager properties | Description
PROPID_QM_CONNECTION | Identifies the CN (MSMQ 1.0) or site list (MSMQ 2.0) of the computer.
PROPID_QM_ENCRYPTION_PK | Indicates the 40-bit public encryption key of the computer.
PROPID_QM_ENCRYPTION_PK_BASE | Indicates the 40-bit public encryption key of the computer. (MSMQ 2.0 only.)
PROPID_QM_ENCRYPTION_PK_ENHANCED | Indicates the 128-bit public encryption key of the computer. (MSMQ 2.0 only.)
PROPID_QM_MACHINE_ID | Identifies the computer.
PROPID_QM_PATHNAME | Specifies the pathname of the computer.
PROPID_QM_PATHNAME_DNS | Indicates the DNS pathname of the computer. (MSMQ 2.0 only.)
PROPID_QM_SITE_ID | Identifies the site where the computer is located.


PROPID_M_ACKNOWLEDGE

The PROPID_M_ACKNOWLEDGE property specifies the type of acknowledgment messages the system posts (in the administration queue) and when acknowledgments are returned.

Property ID
PROPID_M_ACKNOWLEDGE
Type Indicator
VT_UI1 (or VT_NULL)
MQPROPVARIANT Field
bVal

Property Values

The MQPROPVARIANT field can be set to one or more of the following values, using the OR operator:

MQMSG_ACKNOWLEDGMENT_FULL_REACH_QUEUE
Posts a positive or negative acknowledgment depending on whether or not the message reaches the queue.

A negative acknowledgment is posted when the time-to-reach-queue timer of the message expires, or when the message cannot be authenticated.

MQMSG_ACKNOWLEDGMENT_NACK_REACH_QUEUE
Posts a negative acknowledgment when the message cannot reach the queue.

A negative acknowledgment is posted when the time-to-reach-queue timer of the message expires, or when the message cannot be authenticated.

MQMSG_ACKNOWLEDGMENT_FULL_RECEIVE
Posts a positive or negative acknowledgment depending on whether or not the message is retrieved from the queue before its time-to-be-received timer expires.
MQMSG_ACKNOWLEDGMENT_NACK_RECEIVE
Posts a negative acknowledgment when an error occurs and the message cannot be retrieved from the queue before its time-to-be-received timer expires.

MQMSG_ACKNOWLEDGMENT_NONE
The default. No acknowledgment messages (positive or negative) are posted.

Remarks

When asking for acknowledgments, you must also specify the administration queue where the acknowledgment messages will be sent.

To request acknowledgment messages, specify PROPID_M_ACKNOWLEDGE and PROPID_M_ADMIN_QUEUE in the MQMSGPROPS structure and call MQSendMessage.

To find out if an acknowledgment message was requested for a message in a queue, specify PROPID_M_ACKNOWLEDGE in the MQMSGPROPS structure. Then, call MQReceiveMessage and examine its returned value. (When specifying PROPID_M_ACKNOWLEDGE, you can set its Type Indicator to VT_NULL. When the Type Indicator is set to VT_NULL, Message Queuing sets the VT field to the appropriate type indicator.)

To receive a positive acknowledgment message when a message reaches its destination and when the message is retrieved, the following two full-acknowledgment settings must be combined using the OR operator: MQMSG_FULL_REACH_QUEUE and MQMSG_FULL_RECEIVE.

Acknowledgment messages are typically Message Queuing–generated messages, however they can also be created by connector applications when sending messages to a foreign queue.

For information on | See
What is in acknowledgment messages. | Acknowledgment Messages
The type of queues used as administration queues | Administration Queues
The time-to-reach-queue and time-to-be-received timers | Message Timers
Setting and retrieving the acknowledgment level when you are using COM components | MSMQMessage.Ack

Example Code

The following example shows how PROPID_M_ACKNOWLEDGE is specified in the MQMSGPROPS structure.

aMsgPropId[i] = PROPID_M_ACKNOWLEDGE;   // Property ID
aMsgPropVar[i].vt = VT_UI1;             // Type indicator
aMsgPropVar[i].bVal = MQMSG_ACKNOWLEDGMENT_FULL_RECEIVE;
i++;

See Also

MQReceiveMessage, MQSendMessage, MQMSGPROPS, PROPID_M_ADMIN_QUEUE, PROPID_M_TIME_TO_BE_RECEIVED, PROPID_M_TIME_TO_REACH_QUEUE


PROPID_M_ADMIN_FORMAT_NAME

(Introduced in MSMQ 3.0.) The PROPID_M_ADMIN_FORMAT_NAME property supersedes PROPID_M_ADMIN_QUEUE (both properties cannot be set in the same message). This property specifies the administration queues used for returned acknowledgment messages.

Property ID
PROPID_M_ADMIN_FORMAT_NAME
Type Indicator
VT_LPWSTR
MQPROPVARIANT Field
pwszVal

Property Values

String that contains a public, private, direct, distribution list, multicast address, or multiple-element format name.

Remarks

The PROPID_M_ADMIN_FORMAT_NAME property is set by the sending application when requesting acknowledgment messages from Message Queuing or a connector application (connector applications return acknowledgment messages for messages sent to foreign queues). Acknowledgment messages can indicate whether the original messages reached their destinations, whether the messages were retrieved from their destinations, or a combination of both.

Administration queues can be any non-transactional queue.

Sets of administration queues can be specified using the following format names.

  • Distribution list format names are used to reference administration queues based on a public distribution list that is published in Active Directory. For information the syntax of distribution list format names, see Distribution List Format Names.
  • Multicast address format names are used to reference administration queues that are associated with a specific multicast address. For information the syntax of multicast address format names, see Multicast Address Format Names.
  • Multiple-element format names are used to reference administration queues based on a private list of destination queues. For information the syntax of multiple element format names, see Multiple-Element Format Names.

Message Queuing provides backwards compatibility for sending applications that send message to MSMQ 2.0 computers, and for receiving applications that read messages sent from MSMQ 2.0 computers.

When sending messages, the queue manager sets the PROPID_M_ADMIN_QUEUE property of the message to one of the following values.

  • If the PROPID_M_ADMIN_FORMAT_NAME property contains a single public, private, or direct format name, the PROPID_M_ADMIN_QUEUE property is set to the format name string specified by PROPID_M_ADMIN_FORMAT_NAME.
  • If the PROPID_M_ADMIN_FORMAT_NAME property contains a multiple-element format name, the PROPID_M_ADMIN_QUEUE property is set to the first non-distribution list element in the format name string.
  • If PROPID_M_ADMIN_FORMAT_NAME contains a distribution list, the PROPID_M_ADMIN_QUEUE property is set to NULL.

When receiving MSMQ 1.0 or MSMQ 2.0 message, the receiving queue manager sets PROPID_M_ADMIN_FORMAT_NAME to the format name specified by the PROPID_M_ADMIN_QUEUE property.

To specify administration queues, include the following two message properties in the MQMSGPROPS structure and then call MQSendMessage.

  • PROPID_M_ACKNOWLEDGE (specifies authentication level)
  • PROPID_M_ADMIN_FORMAT_NAME (specifies administration queues)

Example Code

The following example code shows how PROPID_M_ADMIN_FORMAT_NAME and PROPID_M_ACKNOWLEDGE are specified the MQMSGPROPS structure.

aMsgPropId[i] = PROPID_M_ADMIN_FORMAT_NAME;    // Property ID
aMsgPropVar[i].vt = VT_LPWSTR;                 // Type indicator
aMsgPropVar[i].pwszVal = wszAdminQueueBuffer;
i++;

aMsgPropId[i] = PROPID_M_ACKNOWLEDGE;       // Property ID
aMsgPropVar[i].vt = VT_UI1;                 // Type indicator
aMsgPropVar[i].bVal = MQMSG_ACKNOWLEDGMENT_FULL_RECEIVE;
i++;

To retrieve the administration queues specified by the sending application, include the following two properties in the MQMSGPROPS structure, then call MQReceiveMessage and examine the returned values.

  • PROPID_M_ADMIN_FORMAT_NAME (returns administration queues)
  • PROPID_M_ADMIN_FORMAT_NAME_LEN (returns length of format name string)

Example Code

The following examples show how PROPID_M_ADMIN_FORMAT_NAME and PROPID_M_ADMIN_FORMAT_NAME_LEN is specified in the MQMSGPROPS structure for retrieving the administration queue set.

aMsgPropId[i] = PROPID_M_ADMIN_FORMAT_NAME;    // Property ID
aMsgPropVar[i].vt = VT_LPWSTR;              // Type indicator
aMsgPropVar[i].pwszVal = wszAdminQueueBuffer;
i++;

aMsgPropId[i] = PROPID_M_ADMIN_FORMAT_NAME_LEN; // Property ID
aMsgPropVar[i].vt = VT_UI4;                  // Type indicator
aMsgPropVar[i].ulVal = dwAdminQueueBufferLength;
i++;

When retrieving PROPID_M_ADMIN_FORMAT_NAME, always check the PROPID_M_ADMIN_FORMAT_NAME_LEN property first to see if the administration queues were specified by the sending application. If the returned value of PROPID_M_ADMIN_FORMAT_NAME_LEN is 0, an administration queue was not specified. If the returned value is non-0, PROPID_M_ADMIN_FORMAT_NAME contains a string that includes the single element or multiple element format name specified by the sending application.

Equivalent COM Property

When using COM components, you can specify a set of administration queues using MSMQMessage.AdminDestination.

See Also

MSMQMessage.AdminDestination, MQMSGPROPS, MQReceiveMessage, MQSendMessage, PROPID_M_ACKNOWLEDGE, PROPID_M_ADMIN_QUEUE, PROPID_M_ADMIN_FORMAT_NAME_LEN


PROPID_M_ADMIN_FORMAT_NAME_LEN

(Introduced in MSMQ 3.0.) The PROPID_M_ADMIN_FORMAT_NAME_LEN property indicates the length (in Unicode characters) of the format name buffer allocated by the receiving application and the length of the format name sting returned in PROPID_M_ADMIN_FORMAT_NAME.

Property ID
PROPID_M_ADMIN_FORMAT_NAME_LEN
Type Indicator
VT_UI4
MQPROPVARIANT Field
ulVal

Property Values

On input: The length of the format name buffer (in Unicode characters) allocated by the receiving application.

On return: The length (in Unicode characters) of the format name string (including the null-terminating character) returned in PROPID_M_ADMIN_FORMAT_NAME.

Remarks

The PROPID_M_ADMIN_FORMAT_NAME_LEN property is only used by the receiving application to allocate a buffer for the administration queue set specified by the sending application. The sending application specifies administration queues when it wants Message Queuing (or connector applications when sending messages to foreign queues) to acknowledge that messages reached their queue, were retrieved from their queue, or both.

To retrieve the administration queues specified by the sending application, include the following two message properties in the MQMSGPROPS structure and then call MQReceiveMessage.

  • PROPID_M_ADMIN_FORMAT_NAME (returns administration queue format name string)
  • PROPID_M_ADMIN_FORMAT_NAME_LEN (returns the length of the format name string)

The following example code shows how PROPID_M_ADMIN_FORMAT_NAME and PROPID_M_ADMIN_FORMAT_NAME_LEN is specified in the MQMSGPROPS structure for retrieving the administration queue set.

aMsgPropId[i] = PROPID_M_ADMIN_FORMAT_NAME;    // Property ID
aMsgPropVar[i].vt = VT_LPWSTR;              // Type indicator
aMsgPropVar[i].pwszVal = wszAdminQueueBuffer;
i++;

aMsgPropId[i] = PROPID_M_ADMIN_FORMAT_NAME_LEN; // Property ID
aMsgPropVar[i].vt = VT_UI4;                  // Type indicator
aMsgPropVar[i].ulVal = dwAdminQueueBufferLength;
i++;

When MQReceiveMessage succeeds, first test the returned value of PROPID_M_ADMIN_FORMAT_NAME_LEN to see if a set of administration queues was specified by the sending application. A returned value of 0 indicates that no administration queues were specified. A non-0 returned value indicates that the administration queue set was returned by PROPID_M_ADMIN_FORMAT_NAME.

If MQReceiveMessage fails, returning an MQ_ERROR_FORMATNAME_BUFFER_TOO_SMALL error, use the returned value of PROPID_M_ADMIN_FORMAT_NAME_LEN to reallocate the buffer, and call MQReceiveMessage again.

Equivalent COM Property

There is no equivalent COM property for this property.

See Also

MQMSGPROPS, MQReceiveMessage, PROPID_M_ADMIN_FORMAT_NAME


PROPID_M_ADMIN_QUEUE

The PROPID_M_ADMIN_QUEUE property specifies the administration queue used for system-generated acknowledgment messages.

Property ID
PROPID_M_ADMIN_QUEUE
Type Indicator
VT_LPWSTR
MQPROPVARIANT Field
pwszVal

Property Values

Format name string of administration queue.

Remarks

This property must be set when requesting acknowledgment messages from Message Queuing. Message Queuing will not return acknowledgment messages if an administration queue is not specified.

Note The administration queue can be any non-transactional queue. The acknowledgment messages sent to the queue can indicate whether the original message reached its destination queue, whether the message was retrieved by the receiving application, or a combination of both.

To send the administration queue format name with a message, specify PROPID_M_ADMIN_QUEUE along with PROPID_M_ACKNOWLEDGE in the MQMSGPROPS structure and call MQSendMessage.

To retrieve the format name of the administration queue from a message, specify PROPID_M_ADMIN_QUEUE and PROPID_M_ADMIN_QUEUE_LEN in the MQMSGPROPS structure (the length property is used to verify that the format name was sent). Then call MQReceiveMessage and examine the returned values.

Before using the returned format name, always check the length property PROPID_M_ADMIN_QUEUE_LEN to see if the administration queue format name was sent with the message. If the returned value of PROPID_M_ADMIN_QUEUE_LEN is 0, no format name was sent with the message. If the returned value is non-0, PROPID_M_ADMIN_QUEUE contains the format name of the administration queue.

For information on | See
How administration queues are used | Administration Queues
What is in an acknowledgment message | Acknowledgment Messages
Setting and retrieving the administration queue when you are using COM components | MSMQMessage.AdminQueueInfo

Example Code

The following examples show how PROPID_M_ADMIN_QUEUE is specified in the MQMSGPROPS structure for setting and retrieving the administration queue format name.

To set the format name

aMsgPropId[i] = PROPID_M_ADMIN_QUEUE;       // Property ID
aMsgPropVar[i].vt = VT_LPWSTR;              // Type indicator
aMsgPropVar[i].pwszVal = wszAdminFormatNameBuffer;
i++;

aMsgPropId[i] = PROPID_M_ACKNOWLEDGE;       // Property ID
aMsgPropVar[i].vt = VT_UI1;                 // Type indicator
aMsgPropVar[i].bVal = MQMSG_ACKNOWLEDGMENT_FULL_RECEIVE;
i++;

To retrieve the format name

aMsgPropId[i] = PROPID_M_ADMIN_QUEUE;       // Property ID
aMsgPropVar[i].vt = VT_LPWSTR;              // Type indicator
aMsgPropVar[i].pwszVal = wszAdminFormatNameBuffer;
i++;

aMsgPropId[i] = PROPID_M_ADMIN_QUEUE_LEN;   // Property ID
aMsgPropVar[i].vt = VT_UI4;                 // Type indicator
aMsgPropVar[i].ulVal = dwAdminFormatNameBufferLength;
i++;
For a complete example of | See
Testing to see if acknowledgment messages are used | Retrieving the Format Name of an Administration Queue

See Also

MQMSGPROPS, MQReceiveMessage, MQSendMessage, PROPID_M_ACKNOWLEDGE, PROPID_M_ADMIN_QUEUE_LEN


PROPID_M_ADMIN_QUEUE_LEN

The PROPID_M_ADMIN_QUEUE_LEN property indicates the length (in Unicode characters) of the format name buffer of the administration queue.

Property ID
PROPID_M_ADMIN_QUEUE_LEN
Type Indicator
VT_UI4
MQPROPVARIANT Field
ulVal

Property Values

On input: The length of the format name buffer (in Unicode characters) allocated by the receiving application.

On return: The length (in Unicode characters) of the format name string (including the null-terminating character) returned by PROPID_M_ADMIN_QUEUE.

Remarks

PROPID_M_ADMIN_QUEUE_LEN is only used by the receiving application when looking for the administration queue specified by the sending application.

On input, PROPID_M_ADMIN_QUEUE_LEN should be large enough to hold the format name string of the administration queue plus its null-terminating character.

To retrieve the format name of the administration queue, specify PROPID_M_ADMIN_QUEUE_LEN and PROPID_M_ADMIN_QUEUE in the MQMSGPROPS structure. Then call MQReceiveMessage and examine the returned values.

When MQReceiveMessage succeeds, first test the returned value of PROPID_M_ADMIN_QUEUE_LEN to see if an administration queue was used. A returned value of 0 indicates that no administration queue was specified by the sending application. A non-0 returned value indicates that the format name of an administration queue was returned by PROPID_M_ADMIN_QUEUE.

If MQReceiveMessage fails, returning an MQ_ERROR_FORMATNAME_BUFFER_TOO_SMALL error, use the returned value of PROPID_M_ADMIN_QUEUE_LEN to reallocate the format name buffer, and call MQReceiveMessage again.

This property is not needed when you are using COM components.

Example Code

The following example shows how PROPID_M_ADMIN_QUEUE_LEN and PROPID_M_ADMIN_QUEUE are specified in the MQMSGPROPS structure.

aMsgPropId[i] = PROPID_M_ADMIN_QUEUE_LEN;   // Property ID
aMsgPropVar[i].vt = VT_UI4;                 // Type indicator
aMsgPropVar[i].ulVal = dwAdminFormatNameBufferLength;
i++;

aMsgPropId[i] = PROPID_M_ADMIN_QUEUE;       // Property ID
aMsgPropVar[i].vt = VT_LPWSTR;              // Type indicator
aMsgPropVar[i].pwszVal = wszAdminFormatNameBuffer;
i++;
For a complete example of | See
Testing to see if acknowledgment messages are used | Retrieving the Format Name of an Administration Queue

See Also

MQMSGPROPS, MQReceiveMessage, PROPID_M_ADMIN_QUEUE


PROPID_M_APPSPECIFIC

The PROPID_M_APPSPECIFIC property specifies application-generated information such as single integer values or application-defined message classes.

Property ID
PROPID_M_APPSPECIFIC
Type Indicator
VT_UI4 (or VT_NULL)
MQPROPVARIANT Field
ulVal

Property Values

Unsigned integer. The default is 0.

Remarks

Application-specific information can be used to organize different types of messages. For example, several sending applications may be sending messages to a common queue. If each application uses a different application-specific index, the receiving application can use PROPID_M_APPSPECIFIC to filter out the messages from a single sending application.

To set application-specific information, specify PROPID_M_APPSPECIFIC in the MQMSGPROPS structure and call MQSendMessage.

To retrieve application specific information, specify PROPID_M_APPSPECIFIC in the MQMSGPROPS structure. Then call MQReceiveMessage and examine its returned value. (When specifying PROPID_M_APPSPECIFIC, you can set its Type Indicator to VT_NULL. When the Type Indicator is set to VT_NULL, Message Queuing sets the VT field to the appropriate type indicator.)

In addition to application-specific information, you can use the PROPID_M_CORRELATIONID message property for filtering as well.

For information on | See
Setting and retrieving application specific information when you are using COM components | MSMQMessage.AppSpecific

Example Code

The following example shows how PROPID_M_APPSPECIFIC is specified in the MQMSGPROPS structure:

aMsgPropId[i] = PROPID_M_APPSPECIFIC;        // Property ID
aMsgPropVar[i].vt = VT_UI4;                  // Type indicator
aMsgPropVar[i].ulVal = dwAppspecificIndex;   // Value
i++;

See Also

MQMSGPROPS, MQReceiveMessage, MQSendMessage, PROPID_M_CORRELATIONID


PROPID_M_ARRIVEDTIME

The PROPID_M_ARRIVEDTIME property indicates when the message arrived at the queue.

Property ID
PROPID_M_ARRIVEDTIME
Type Indicator
VT_UI4 (or VT_NULL)
MQPROPVARIANT Field
ulVal

Property Values

Unsigned integer.

Remarks

The PROPID_M_ARRIVEDTIME property is attached to the message by Message Queuing. The arrival time returned is the number of seconds elapsed since midnight (00:00:00), January 1, 1970 (Coordinated Universal time) according to the system clock.

To retrieve the arrived time of a message, specify PROPID_M_ARRIVEDTIME in the MQMSGPROPS structure. Then call MQReceiveMessage and examine the returned value. (When specifying PROPID_M_ARRIVEDTIME, you can set its Type Indicator to VT_NULL. When the Type Indicator is set to VT_NULL, Message Queuing sets the VT field to the appropriate type indicator.)

Microsoft provides several time functions that can be used to manipulate the returned Coordinated Universal time value. These functions are defined in the time.h header file.

When reading messages from a queue journal, PROPID_M_ARRIVETIME indicates the time the original message arrived at its destination queue, not when the copy of the original message arrived in the queue journal.

When reading messages from computer journal or dead-letter queues, PROPID_M_ARRIVETIME indicates when the message reached the journal or dead-letter queue.

For information on | See
Queue and computer journals | Journal Queues
Dead-letter queues | Dead-Letter Queues
Retrieving the arrived time when you are using COM components | MSMQMessage.ArrivedTime

Example Code

The following example shows how PROPID_M_ARRIVEDTIME is specified in the MQMSGPROPS structure.

aMsgPropId[i] = PROPID_M_ARRIVEDTIME;        // Property ID
aMsgPropVar[i].vt = VT_UI4;                  // Type indicator
aMsgPropVar[i].ulVal = dwArrivedTime;        // Value
i++;

See Also

MQMSGPROPS, MQReceiveMessage, PROPID_M_SENTTIME


PROPID_M_AUTH_LEVEL

The PROPID_M_AUTH_LEVEL property specifies whether the message must be authenticated and what type of digital signature is used.

Property ID
PROPID_M_AUTH_LEVEL
Type Indicator
VT_UI4
MQPROPVARIANT Field
ulVal

Property Values

This property can be set to one of the following values:

MQMSG_AUTH_LEVEL_NONE
The default. The message is not signed. Message Queuing does not need to authenticate the message when it reaches the queue.
MQMSG_AUTH_LEVEL_ALWAYS
Message Queuing run time signs the message using a one or more types of digital signatures.

Non-HTTP messages are signed based on the value of the sending authentication registry key. If the registry key is not set, an MQMSG_AUTH_LEVEL_SIG10 signature is used. (For information on the sending authentication registry key, see Digital Signature Registry Keys.

HTTP messages are signed with an XML digital signature.

MQMSG_AUTH_LEVEL_MSMQ10
Obsolete. This value is superseded by MQMSG_AUTH_LEVEL_SIG10.
MQMSG_AUTH_LEVEL_MSMQ20
Obsolete. This value is superseded by MQMSG_AUTH_LEVEL_SIG20.
MQMSG_AUTH_LEVEL_SIG10
Introduced in MSMQ 3.0. For non-HTTP messages, the Message Queuing run time ignores the sending authentication registry key and signs the message using only an MQMSG_AUTH_LEVEL_SIG10 signature.

For HTTP messages, the message is signed using an XML digital signature.

MQMSG_AUTH_LEVEL_SIG20
Introduced in MSMQ 3.0. For non-HTTP messages, the Message Queuing run time ignores the sending authentication registry key and signs the message using an MQMSG_AUTH_LEVEL_SIG20 signature. (This setting cannot be used when sending messages to multiple destinations using distribution lists, multicast addresses, or multiple-element format names.)

For HTTP messages, the message is signed using an XML digital signature.

MQMSG_AUTH_LEVEL_SIG30
Introduced in MSMQ 3.0. For non-HTTP messages, the Message Queuing run time ignores the sending authentication registry key and signs the message using an MQMSG_AUTH_LEVEL_SIG30 or MQMSG_AUTH_LEVEL_SIG20 signature.

MQMSG_AUTH_LEVEL_SIG30 signatures are used if the message is sent to using distribution lists, multicast addresses, or multiple-element format names.

MQMSG_AUTH_LEVEL_SIG20 signatures are used if the message is sent without using distribution lists, multicast addresses or multiple-element format names.

For HTTP messages, the message is signed using an XML digital signature.

Remarks

The PROPID_M_AUTH_LEVEL property is only used by the sending application to request authentication. When authentication is requested, Message Queuing creates an XML signature for HTTP message and one or more of three non-XML signatures for non-HTTP messages. The created digital signature is used to digitally sign the message when it is sent and authenticate the message when it reaches the target computer where the destination queue resides.

Authentication can be enforced at the queue level by setting the PROPID_Q_AUTHENTICATE property of the queue. When sending messages to queues that only accept authenticated messages, the message will be rejected when it reaches the queue if the authentication level of a message is set to MQMSG_AUTH_LEVEL_NONE.

Message Queuing provides different signatures for HTTP and non-HTTP messages. Non-HTTP signatures include the following (for a complete description, including the message properties used to create these signatures, see Digital Signatures):

  • MQMSG_AUTH_LEVEL_SIG10
  • MQMSG_AUTH_LEVEL_SIG20 (introduced in MSMQ 2.0)
  • MQMSG_AUTH_LEVEL_SIG30 (introduced in MSMQ 3.0)

XML signatures (introduced in MSMQ 3.0) are used whenever an HTTP message requests authentication.

The following authentication registry keys can be used to specify what type of signature is used for non-HTTP messages. When MQMSG_AUTH_LEVEL_ALWAYS is specified, the Message Queuing run-time creates digital signatures based on the value of the sending authentication registry key.

hklm\software\microsoft\msmq\parameters\security\SendMsgAuthn
hklm\software\microsoft\msmq\parameters\security\RcvOnlyEnhMsgAuthn

For details on setting these registry key, see Digital Signature Registry Keys.

The receiving application can check to see if authentication was requested by retrieving one of the following read-only message properties: PROPID_M_AUTHENTICATED and PROPID_M_AUTHENTICATED_EX (introduced in MSMQ 2.0).

To set the authentication level of a message, include PROP_M_AUTH_LEVEL in the MQMSGPROPS structure and call MQSendMessage.

The following example code shows how PROPID_M_AUTH_LEVEL is specified the MQMSGPROPS structure.

aMsgPropId[i] = PROPID_M_AUTH_LEVEL;    // Property ID
aMsgPropVar[i].vt = VT_UI4;             // Type indicator
aMsgPropVar[i].bVal = MQMSG_AUTH_LEVEL_ALWAYS;
i++;

Equivalent COM Property

When using COM components, you can request authentication using MSMQMessage.AuthLevel.

For a complete example of | See
Requesting authentication using an internal certificate | Requesting Authentication with an Internal Certificate
Requesting authentication using an external certificate | Requesting Authentication with an External Certificate

See Also

MQMSGPROPS, MQSendMessage, MSMQMessage.AuthLevel, PROPID_Q_AUTHENTICATE, PROPID_M_AUTHENTICATED, PROPID_M_AUTHENTICATED_EX


PROPID_M_AUTHENTICATED

The PROPID_M_AUTHENTICATED property indicates whether the sending application requested authentication.

Property ID
PROPID_M_AUTHENTICATED
Type Indicator
VT_UI1 (or VT_NULL)
MQPROPVARIANT Field
bVal

Property Values

This property can be set to one of the following:

MQMSG_AUTHENTICATION_NOT_REQUESTED
The sending application did not request authentication. The receiving queue manager did not attempt to authenticate the message when it received the message.
MQMSG_AUTHENTICATION_REQUESTED
The sending application requested authentication. The receiving queue manager authenticated the message when it received the message.

Remarks

This message property is only used by the receiving application when trying to determine if authentication was requested. Because messages that fail authentication are not placed in queue, if authentication was requested and the message is in the queue, then the message was authenticated.

Note It is not possible to look at the properties of a message and determine if a message failed authentication. Messages that fail authentication are discarded and are not delivered to the queue.

MSMQ 1.0 and 2.0 Differences

Message Queuing can use two different signatures to authenticate messages: MSMQ 1.0 signatures and MSMQ 2.0 signatures (by default, a receiving computer running MSMQ 2.0 accepts either type of signature.) The following registry key specifies what type of signature is accepted by the receiving computer.

hklm\software\microsoft\msmq\parameters\security\RcvOnlyEnhMsgAuthn

To change the default behavior, set this key to one of the following values.

To | Set registry key to
Accept either MSMQ 1.0 and MSMQ 2.0 signatures. | 0
Accept only MSMQ 2.0 signatures | 1

For compatibility, a source computer running MSMQ 2.0 sends, by default, only the MSMQ 1.0 signature. Therefore, when you set this receiving registry key to accept only MSMQ 2.0 signatures, make sure you reset the sending registry key on the source computer as well. For more information, see PROPID_M_AUTH_LEVEL.

If the receiving application needs to check only whether authentication was requested, it should use PROPID_M_AUTHENTICATED. However, if the receiving application also needs to check what type of signature was used during authentication, it should use PROPID_M_AUTHENTICATED_EX.

You cannot specify both message properties when calling MQReceiveMessage.

To see if authentication was requested, specify PROPID_M_AUTHENTICATED in the MQMSGPROPS structure. Then call MQReceiveMessage and examine the returned value. (When specifying PROPID_M_AUTHENTICATED, you can set its Type Indicator to VT_NULL. When the Type Indicator is set to VT_NULL, Message Queuing sets the VT field to the appropriate type indicator.)

For information on | See
The process of authenticating messages | How Message Queuing Authenticates Messages
Retrieving authentication requests when you are using COM components | MSMQMessage.IsAuthenticated

Example Code

The following example shows how PROPID_M_AUTHENTICATED is specified in the MQMSGPROPS structure.

aMsgPropId[i] = PROPID_M_AUTHENTICATED; // Property ID
aMsgPropVar[i].vt = VT_UI1;             // Type indicator
aMsgPropVar[i].bVal;                    // Type indicator
i++;
For a complete example of | See
Checking to see if a message was authenticated | Validating Authenticated Messages

See Also

MQMSGPROPS, MQReceiveMessage, PROPID_M_AUTHENTICATED_EX


PROPID_M_AUTHENTICATED_EX

(MSMQ 2.0 only.) The PROPID_M_AUTHENTICATED_EX property indicates whether the sending application requested authentication and indicates what type of signature was used.

Property ID
PROPID_M_AUTHENTICATED_EX
Type Indicator
VT_UI1 (or VT_NULL)
MQPROPVARIANT Field
bVal

Property Values

This property can be set to one of the following:

MQMSG_AUTHENTICATION_NOT_REQUESTED
The sending application did not request authentication. The receiving queue manager did not attempt to authenticate the message when it received the message.
MQMSG_AUTHENTICATION_REQUESTED
The sending application requested authentication using an MSMQ 1.0 signature.
MQMSG_AUTHENTICATION_REQUESTED_EX
The sending application requested authentication using an MSMQ 2.0 signature.

Remarks

This message property is used by the receiving application only when trying to determine if authentication was requested and what type of signature was used. Because messages that fail authentication are not placed in queue, if authentication was requested and the message is in the queue, the message was authenticated.

Note It is not possible to look at the properties of a message and determine if a message failed authentication. Messages that fail authentication are discarded and are not delivered to the queue.

MSMQ 1.0 and 2.0 Differences

Message Queuing can use two different signatures to authenticate messages: MSMQ 1.0 signatures and MSMQ 2.0 signatures (by default, the receiving computer will accept either type of signature.) The following registry key specifies what type of signature is used by the receiving computer.

hklm\software\microsoft\msmq\parameters\security\RcvOnlyEnhMsgAuthn
To | Set registry key to
Use MSMQ 1.0 and MSMQ 2.0 signatures. | 0
Use only MSMQ 2.0 signatures | 1

For compatibility, a source computer running MSMQ 2.0 sends, by default, only the MSMQ 1.0 signature. Therefore, when you set this receiving registry key to accept only MSMQ 2.0 signatures, make sure you reset the sending registry key on the source computer as well. For more information, see PROPID_M_AUTH_LEVEL.

If the receiving application needs to check only whether authentication was requested, it should use PROPID_M_AUTHENTICATED. However, if the receiving application also needs to check what type of signature was used during authentication, it should use PROPID_M_AUTHENTICATED_EX.

You cannot specify both message properties when calling MQReceiveMessage.

To see if authentication was requested, specify PROPID_M_AUTHENTICATED_EX in the MQMSGPROPS structure. Then call MQReceiveMessage and examine the returned value. (When specifying PROPID_M_AUTHENTICATED_EX, you can set its Type Indicator to VT_NULL. When the Type Indicator is set to VT_NULL, Message Queuing sets the VT field to the appropriate type indicator.)

For information on | See
The process of authenticating messages | How Message Queuing Authenticates Messages
Retrieving authentication requests when you are using COM components | MSMQMessage.ReceivedAuthenticationLevel

Example Code

The following example shows how PROPID_M_AUTHENTICATED_EX is specified in the MQMSGPROPS structure.

aMsgPropId[i] = PROPID_M_AUTHENTICATED_EX; // Property ID
aMsgPropVar[i].vt = VT_UI1;                // Type indicator
aMsgPropVar[i].bVal;                       // Type indicator
i++;

See Also

MQMSGPROPS, MQReceiveMessage, PROPID_M_AUTHENTICATED


PROPID_M_BODY

The PROPID_M_BODY property contains the body of the message.

Property ID
PROPID_M_BODY
Type Indicator
VT_VECTOR | VT_UI1
MQPROPVARIANT Field
caub

Property Values

Body of the message.

Remarks

Each Message Queuing message can have no more than 4 MB of data.

The body of a message can consist of any type of information, and it is the responsibility of the sending application to specify the message body type. For example, the sending application could send a string or a binary file with any internal structure. The PROPID_M_BODY_TYPE property is used to indicate what type of information is included in the message body. If PROPID_M_BODY_TYPE is not set, Message Queuing sets the body type to VT_EMPTY.

When retrieving messages, the receiving application should assume the message is an array of bytes if it does not know what type of body the message contains. The Message Queuing COM implementation does this automatically for you.

To set the body of a message, specify PROPID_M_BODY and PROPID_M_BODY_TYPE in the MQMSGPROPS structure and call MQSendMessage.

To retrieve the message body from a message, specify PROPID_M_BODY_SIZE , PROPID_M_BODY_TYPE, and PROPID_M_BODY in the MQMSGPROPS structure. Then, call MQReceiveMessage and examine the returned value.

Before using the returned value of PROPID_M_BODY, always inspect the body size and type. A returned PROPID_M_BODY_SIZE value of 0 indicates that no body was attached to the message. A returned PROPID_M_BODY_TYPE value of VT_EMPTY indicates that the message type was not set (the Message Queuing COM implementation sets the body type for you when the message is sent).

When passing fixed-size messages between the sending and receiving application, and if this is the only type of message passed, you can allocate a fixed size buffer for receiving the message body without caring about the body size.

For information on | See
How Message Queuing sets the body type of a message | Message Body Types
Setting and retrieving the message body when you are using COM components | MSMQMessage.Body

Example Code

The following examples show how PROPID_M_BODY is specified in the MQMSGPROPS structure when setting and retrieving the message body:

To send the message body

WCHAR wszMessageBody[] = L"Test Message.";
MsgProps.aPropID[i] = PROPID_M_BODY;                 // Property ID
MsgProps.aPropVar[i].vt = VT_VECTOR|VT_UI1;          // Type indicator
MsgProps.aPropVar[i].caub.pElems = (LPBYTE)wszMessageBody;
MsgProps.aPropVar[i].caub.cElems = sizeof(wszMessageBody);
i++

DWORD dwBodyType = VT_BSTR;
MsgProps.aPropID[i] = PROPID_M_BODY_TYPE;            // Property ID
MsgProps.aPropVar[i].vt = VT_UI4;                    // Type indicator
MsgProps.aPropVar[i].ulVal = dwBodyType;
i++

To retrieve the message body

MsgProps.aPropID[i] = PROPID_M_BODY_SIZE;            // Property ID
MsgProps.aPropVar[i].vt = VT_UI4;                    // Type indicator
i++

MsgProps.aPropID[i] = PROPID_M_BODY_TYPE;            // Property ID
MsgProps.aPropVar[i].vt = VT_UI4;                    // Type indicator
i++

DWORD dwBodyBufferSize = 1024;
UCHAR *pucBodyBuffer = (UCHAR *)malloc(dwBodyBufferSize);
MsgProps.aPropID[i] = PROPID_M_BODY;                 // Property ID
MsgProps.aPropVar[i].vt = VT_VECTOR|VT_UI1;          // Type indicator
MsgProps.aPropVar[i].caub.pElems = (UCHAR*)pucBodyBuffer;
MsgProps.aPropVar[i].caub.cElems = dwBodyBufferSize;
i++
For a complete example of | See
Setting the message body when sending messages | Sending Messages to a Queue
Retrieving the body of a message | Reading Messages Synchronously

See Also

MQMSGPROPS, MQReceiveMessage, MQSendMessage, PROPID_M_BODY_SIZE, PROPID_M_BODY_TYPE


PROPID_M_BODY_SIZE

The PROPID_M_BODY_SIZE property indicates the size of the message body.

Property ID
PROPID_M_BODY_SIZE
Type Indicator
VT_UI4 (or VT_NULL)
MQPROPVARIANT Field
ulVal

Property Values

The size of the message body returned by PROPID_M_BODY.

Remarks

PROPID_M_BODY_SIZE is used only by the receiving application to retrieve the size of a message. It is used to determine the size of a message body before the message body is retrieved.

Each Message Queuing message can have no more than 4 MB of data.

To retrieve the message body from a message, specify PROPID_M_BODY_SIZE and PROPID_M_BODY in the MQMSGPROPS structure. Then call MQReceiveMessage and examine the returned values. (When specifying PROPID_M_BODY_SIZE, you can set its Type Indicator to VT_NULL. When the Type Indicator is set to VT_NULL, Message Queuing sets the VT field to the appropriate type indicator.)

When MQReceiveMessage succeeds, first test the returned value of PROPID_M_BODY_SIZE to see if a message body exists. A returned value of 0 indicates that no body is attached to the message. A non-0 returned value indicates that a message body was returned by PROPID_M_BODY.

If MQReceiveMessage fails, returning an MQ_ERROR_BUFFER_OVERFLOW error, use the returned value of PROPID_M_BODY_SIZE to reallocate the message body buffer and call MQReceiveMessage again.

For information on | See
Retrieving the size of the message body when you are using COM components | MSMQMessage.BodyLength

Example Code

The following example shows how PROPID_M_BODY_SIZE and PROPID_M_BODY are specified in the MQMSGPROPS structure when retrieving the message body:

MsgProps.aPropID[i] = PROPID_M_BODY_SIZE;            // Property ID
MsgProps.aPropVar[i].vt = VT_UI4;                    // Type indicator
i++

DWORD dwBodyBufferSize = 1024;
UCHAR *pucBodyBuffer = (UCHAR *)malloc(dwBodyBufferSize);
MsgProps.aPropID[i] = PROPID_M_BODY;                 // Property ID
MsgProps.aPropVar[i].vt = VT_VECTOR|VT_UI1;          // Type indicator
MsgProps.aPropVar[i].caub.pElems = (UCHAR*)pucBodyBuffer;
MsgProps.aPropVar[i].caub.cElems = dwBodyBufferSize;
i++

See Also

MQMSGPROPS, MQReceiveMessage, PROPID_M_BODY


PROPID_M_BODY_TYPE

The PROPID_M_BODY_TYPE property indicates the type of body the message contains.

Property ID
PROPID_M_BODY_TYPE
Type Indicator
VT_UI4 (or VT_NULL)
MQPROPVARIANT Field
ulVal

Property Values

Type of message body. The default is VT_EMPTY.

Remarks

PROPID_M_BODY_TYPE should always be set whenever sending messages. If the body type is not set, the application reading the message must assume the message body is an array of bytes. The Message Queuing COM implementation does this automatically.

To set the body type, specify PROPID_M_BODY_TYPE in the MQMSGPROPS structure and call MQSendMessage.

To retrieve the body type, specify PROPID_M_BODY_TYPE in the MQMSGPROPS structure. Then call MQReceiveMessage and examine the returned value. (When specifying PROPID_M_BODY_TYPE, you can set its Type Indicator to VT_UI4 or VT_NULL. When the Type Indicator is set to VT_NULL, Message Queuing sets the VT field to the appropriate type indicator.)

The following table lists all the valid body types.

Type | Body contains
VT_EMPTY | Default. Note that the Message Queuing COM implementation treats this value as an array of bytes.
VT_I1 | A Char (1 byte) type.
VT_I2 | A short integer.
VT_I4 | A long integer.
VT_R4 | A float (4-byte floating point).
VT_R8 | A double-float (8-byte floating point).
VT_CY | A CURRENCY type (8-byte).
VT_DATE | An OLE DATE (8-byte) type.
VT_BSTR | String data in Unicode (does not have to be NULL terminated).
VT_DISPATCH | A COM Automation object (IDispatch object).
VT_BOOL | A VARIANT_BOOL (2-byte) type where -1 is TRUE and 0 is FALSE.
VT_UNKNOWN | A COM object (IUnknown interface).
VT_UI1 | A Char (1 byte) type. An array of bytes when joined by the OR operator with VT_ARRAY (VT_ARRAY | VT_UI1).
VT_UI2 | A short integer.
VT_UI4 | A long integer.
VT_LPSTR | A variable-size, NULL-terminated ANSI string.
VT_LPWSTR | A variable-size, NULL-terminated Unicode string.
VT_STREAMED_OBJECT | A persistent, serialized object whose format is the output of a call to OleSaveToStream using IPersistStream.
VT_STORED_OBJECT | A persistent, serialized object whose format is the output of a call to OleSave using IPersistStorage.
VT_ARRAY | VT_UI1 | An array of bytes.

This property is not available when you are using COM components.

For information on | See
How Message Queuing sets the body type of a message | Message Body Types

Example Code

The following examples show how PROPID_M_BODY_TYPE is specified in the MQMSGPROPS structure when setting and retrieving the message body (note this example specifies a string message body):

To specify the message body type

DWORD dwBodyType = VT_BSTR;                      // Specifies a string
MsgProps.aPropID[i] = PROPID_M_BODY_TYPE;        // Property ID
MsgProps.aPropVar[i].vt = VT_UI4;                // Type indicator
MsgProps.aPropVar[i].ulVal = dwBodyType;
i++

To retrieve the message body type

MsgProps.aPropID[i] = PROPID_M_BODY_TYPE;            // Property ID
MsgProps.aPropVar[i].vt = VT_UI4;                    // Type indicator
i++

See Also

MQReceiveMessage, MQSendMessage, PROPID_M_BODY, PROPID_M_BODY_SIZE


PROPID_M_CLASS

The PROPID_M_CLASS property indicates message type. A message can be a normal Message Queuing message, a positive or negative (arrival and read) acknowledgment message, or a report message. Typically this property is set by Message Queuing when it sends the message, however it can also be set by a connector application when the connector application sends a message.

Property ID
PROPID_M_CLASS
Type Indicator
VT_UI2 (or VT_NULL)
MQPROPVARIANT Field
uiVal

Property Values

Normal messages (all messages created by your application):

MQMSG_CLASS_NORMAL
A normal Message Queuing message.

Positive arrival acknowledgment message (typically generated by Message Queuing):

MQMSG_CLASS_ACK_REACH_QUEUE
The original message reached its destination queue.

Negative arrival acknowledgment messages (typically generated by Message Queuing):

MQMSG_CLASS_NACK_ACCESS_DENIED
The sending application does not have access rights to the destination queue.
MQMSG_CLASS_NACK_BAD_DST_Q
The destination queue is not available to the sending application.
MQMSG_CLASS_NACK_BAD_ENCRYPTION
The destination queue manager could not decrypt a private (encrypted) message (see PROPID_M_PRIV_LEVEL).
MQMSG_CLASS_NACK_BAD_SIGNATURE
Message Queuing could not authenticate the original message. The digital signature of the original message is not valid.
MQMSG_CLASS_NACK_COULD_NOT_ENCRYPT
The source queue manager could not encrypt a private message (PROPID_M_PRIV_LEVEL).
MQMSG_CLASS_NACK_HOP_COUNT_EXCEEDED
The hop count of the original message is exceeded.
MQMSG_CLASS_NACK_Q_EXCEED_QUOTA
The destination queue of the original message is full.
MQMSG_CLASS_NACK_REACH_QUEUE_TIMEOUT
Either the time-to-reach-queue or time-to-be-received timer expired before the original message could reach the destination queue.

For transactional message, this is an in-doubt negative acknowledgment. For example, the local queue manager will set this class when the message timer expires, even though a positive confirmation may be in route from the remote queue manager.

MQMSG_CLASS_NACK_PURGED
The message was purged before reaching the destination queue.
MQMSG_CLASS_NACK_NOT_TRANSACTIONAL_Q
A transactional message was sent to a non-transactional queue.
MQMSG_CLASS_NACK_NOT_TRANSACTIONAL_MSG
A non-transactional message was sent to a transactional queue.
MQMSG_CLASS_NACK_UNSUPPORTED_CRYPTO_PROVIDER
The target queue manager does not have the enhanced (128-bit) cryptographic provider installed.

Positive read acknowledgment message (typically generated by Message Queuing):

MQMSG_CLASS_ACK_RECEIVE
The original message was retrieved by the receiving application.

Negative read acknowledgment messages (typically generated by Message Queuing):

MQMSG_CLASS_NACK_Q_DELETED
The queue was deleted before the message could be read from the queue.
MQMSG_CLASS_NACK_Q_PURGED
The queue was purged and the message no longer exists.
MQMSG_CLASS_NACK_RECEIVE_TIMEOUT
The original message was not removed from the queue before its time-to-be-received timer expired.

For transactional message, the remote queue manager has indicated that the message was not retrieved. This is the only negative acknowledgment that can be trusted to indicate the message was not retrieved.

MQMSG_CLASS_NACK_RECEIVE_TIMEOUT_AT_SENDER
For transactional messages only. The local queue manager has indicated that the original message was not removed from the queue before its time-to-be-received timer expired.

This class is an in-doubt negative acknowledgment. For example, the local queue manager will set this class when the time-to-be-received timer expires, even though a positive confirmation may be in route from the remote queue manager.

Report messages (typically generated by Message Queuing):

MQMSG_CLASS_REPORT
Sent each time the message enters or leaves an Message Queuing server.

Remarks

Acknowledgment messages are typically generated by Message Queuing whenever the sending application requests them. The acknowledgment message is returned to the administration queue that is specified by the sending application.

Note Acknowledgment messages can also be created by connector applications. When the connector application creates an acknowledgment message, it must set PROPID_M_CLASS and PROPID_M_CONNECTOR_TYPE.

Transactional messages can have two in-doubt negative acknowledgments: MQMSG_CLASS_NACK_REACH_QUEUE_TIMEOUT and MQMSG_CLASS_NACK_RECEIVE_TIMEOUT_AT_SENDER. These two classes are considered in doubt because they can be set by the local queue manager even though a confirmation notification may be in route from the remote queue manager. The only trusted negative acknowledgment is MQMSG_CLASS_NACK_RECEIVE_TIMEOUT, because this class is set by the remote queue manager.

Report messages are typically generated by Message Queuing whenever a report queue is defined at the source queue manager. For information on report queues, see Report Queues.

To retrieve the class of the message, specify PROPID_M_CLASS in the MQMSGPROPS structure. Then call MQReceiveMessage and examine the returned value. (When specifying PROPID_M_CLASS, you can set its Type Indicator to VT_NULL. When the Type Indicator is set to VT_NULL, MSMQ sets the VT field to the appropriate type indicator.)

When reading messages in an administration queue or dead-letter queue, retrieve PROPID_M_CLASS to find out why the message was sent to the queue.

For information on | See
What is in acknowledgment messages. | Acknowledgment Messages
The type of queues used as administration queues | Administration Queues
How dead-letter queues are used | Dead-letter Queues
Connector applications | Connector Applications
Retrieving the message class when you are using COM components | MSMQMessage.MsgClass

Example Code

The following example shows how PROPID_M_CLASS is specified in the MQMSGPROPS structure:

MsgProps.aPropID[i] = PROPID_M_CLASS;    //MQPROPVARIANT Field
MsgProps.aPropVar[i].vt = VT_UI2;        //Type Indicator

See Also

MQMSGPROPS, MQReceiveMessage, MQSendMessage, MSMQMessage.MsgClass, PROPID_M_ACKNOWLEDGE


PROPID_M_COMPOUND_MESSAGE

(Introduced in Whistler) The PROPID_M_COMPOUND_MESSAGE property provides the SOAP attachments associated with the message.

Property ID
PROPID_M_COMPOUND_MESSAGE
Type Indicator
VT_VECTOR | VT_UI1
MQPROPVARIANT Field
caub

Property Values

SOAP attachments (MIME binary attachments).

Remarks

The PROPID_M_COMPOUND_MESSAGE property is a read-only property that is used only when an application retrieves HTTP messages. When an HTTP message is sent, the sending queue manager attaches the SOAP attachments, along with the SOAP envelope, to the message.

This property can contain any number of SOAP attachments. It is the responsibility of the receiving application to parse the returned data and process the individual attachments.

To retrieve the SOAP envelope, see PROPID_M_SOAP_ENVELOPE.

Equivalent COM Property

When using COM components, you can retrieve the SOAP attachments using MSMQMessage.CompoundMessage.

Example Code

The following examples show how PROPID_M_COMPOUND_MESSAGE is specified in the MQMSGPROPS structure for retrieving the SOAP attachments of a message (note that the size of the attachments must be retrieved with the attachments.

MsgProps.aPropID[i] = PROPID_M_COMPOUND_MESSAGE_SIZE;
MsgProps.aPropVar[i].vt = VT_UI4;
i++;
MsgProps.aPropID[i] = PROPID_M_COMPOUND_MESSAGE;
MsgProps.aPropVar[i].vt = VT_VECTOR|VT_UI1;
MsgProps.aPropVar[i].caub.pElems = ???????;
MsgProps.aPropVar[i].caub.cElems = ???????;
i++;

See Also

MQMSGPROPS, MSMQMessage.CompoundMessage, PROPID_M_COMPOUND_MESSAGE_SIZE, PROPID_M_SOAP_ENVELOPE,


PROPID_M_COMPOUND_MESSAGE_SIZE

(Introduced in Whistler.) The PROPID_M_COMPOUND_MESSAGE_SIZE property provides the size of the SOAP attachments associated with the message.

Property ID
PROPID_M_COMPOUND_MESSAGE_SIZE
Type Indicator
VT_UI4 (or VT_NULL)
MQPROPVARIANT Field
ulVal

Property Values

The size (in bytes) of the of the SOAP attachments provided by PROPID_M_COMPOUND_MESSAGE.

Remarks

The PROPID_M_COMPOUND_MESSAGE_SIZE property is a read-only property that is only used when retrieving SOAP attachments.

To retrieve the SOAP attachments, see PROPID_M_COMPOUND_MESSAGE.

Equivalent COM Property

There is no COM equivalent for this property.

Example Code

The following examples show how PROPID_M_COMPOUND_MESSAGE_SIZE is specified in the MQMSGPROPS structure when retrieving the SOAP attachments of the message.

To retrieve the SOAP attachments when retrieving messages

MsgProps.aPropID[i] = PROPID_M_COMPOUND_MESSAGE_SIZE;
MsgProps.aPropVar[i].vt = VT_UI4;
i++;
MsgProps.aPropID[i] = PROPID_M_COMPOUND_MESSAGE;
MsgProps.aPropVar[i].vt = VT_VECTOR|VT_UI1;
MsgProps.aPropVar[i].caub.pElems = ???????;
MsgProps.aPropVar[i].caub.cElems = ???????;
i++;

See Also

MQMSGPROPS, PROPID_M_SOAP_ENVELOPE


PROPID_M_CONNECTOR_TYPE

The PROPID_M_CONNECTOR_TYPE property indicates that some message properties that are typically set by Message Queuing were set by the sending application.

Typically, this property is set by connector applications and applications sending application-encrypted message.

Property ID
PROPID_M_CONNECTOR_TYPE
Type Indicator
VT_CLSID
MQPROPVARIANT Field
*puuid

Property Values

Pointer to a connector application identifier.

Remarks

PROPID_M_CONNECTOR_TYPE is required whenever an application sets a message property that is typically set by Message Queuing. It is typically used in the following two cases.

Whenever a connector application sends a message to a Message Queuing queue, the connector type property is required so that the receiving applications know how to interpret the security and acknowledgment properties of the messages.

Whenever an application sends an application-encrypted message, the connector type property is requires so that the Message Queuing run time knows to use the symmetric key provided in MSMQMessage.DestinationSymmetricKey to decrypt the message.

The sending application must set PROPID_M_CONNECTOR_TYPE when it sets any of the following properties. If PROPID_M_CONNECTOR_TYPE is not set, these properties will be ignored:

PROPID_M_PROV_NAME
PROPID_M_PROV_TYPE
PROPID_M_DEST_SYMM_KEY
PROPID_M_CLASS
PROPID_M_SIGNATURE
PROPID_M_SENDERID

To specify a connector type, include PROPID_M_CONNECTOR_TYPE in the MQMSGPROPS structure and then call MQSendMessage.

The following example code shows how PROPID_M_CONNECTOR_TYPE is added to the MQMSGPROPS structure to.

aMsgPropId[i] = PROPID_M_CONNECTOR_TYPE;    // Property ID
aMsgPropVar[i].vt = VT_clsid;               // Type indicator
aMsgPropVar[i].puuid = &ConnectorType;
i++;

To retrieve the connector type specified by the sending application, include PROPID_M_CONNECTOR_TYPE in the MQMSGPROPS structure, then call MQReceiveMessage and examine the returned values.

The following example code shows how PROPID_M_CONNECTOR_TYPE is added to the MQMSGPROPS structure to retrieve the journaling level.

aMsgPropId[i] = PROPID_M_CONNECTOR_TYPE;    // Property ID
aMsgPropVar[i].vt = VT_clsid;               // Type indicator
i++;

Equivalent COM Property

When using COM components, you can set and retrieve the connector type identifier using MSMQMessage.ConnectorTypeGuid.

For information on | See
Connector applications | MSMQ Connector Servers
Sending a symmetric key when encrypting messages | Application-Encrypted Messages

See Also

PROPID_M_DEST_SYMM_KEY, MSMQMessage.ConnectorTypeGuid


PROPID_M_CORRELATIONID

The PROPID_M_CORRELATIONID property specifies the correlation identifier of the message.

Property ID
PROPID_M_CORRELATIONID
Type Indicator
VT_VECTOR | VT_UI1
MQPROPVARIANT Field
caub

Property Values

Application-defined 20-byte message identifier (default is 0).

Remarks

When sending a message, PROPID_M_CORRELATIONID provides an application-defined identifier that the receiving application can use to sort messages. The correlation identifier must be a 20-byte identifier. If the correlation identifier is not 20-bytes, an MQ_ERROR_ILLEGAL_PROPERTY_SIZE error will be returned when the message is sent.

To set the correlation identifier of a message, specify PROPID_M_CORRELATIONID in the MQMSGPROPS structure and call MQSendMessage.

To retrieve the correlation identifier of a message, specify PROPID_M_CORRELATIONID in the MQMSGPROPS structure. Then call MQReceiveMessage and examine its returned value.

When sending response messages to the sending application, PROPID_M_CORRELATIONID can be set to the message identifier (PROPID_M_MSGID) of the message that is in the queue. This provides an easy mechanism that the sending application can use to match the response message with the message that was sent.

When Message Queuing generates an acknowledgment message, it uses the PROPID_M_CORRELATIONID property to specify the message identifier of the original message. The application retrieving the acknowledgment messages can then use PROPID_M_CORRELATIONID to identify the original message associated with the acknowledgment message.

When sending messages to a foreign queue, the value of PROPID_M_CORRELATIONID is used to verify the sender's signature.

For information on | See
Acknowledgment messages in administration queues | Administration Queues
Sending messages to foreign queues | MSMQ Connector Servers
Setting and retrieving the correlation identifier when you are using COM components | MSMQMessage.CorrelationId

Example Code

The following example shows how PROPID_M_CORRELATIONID is specified in the MQMSGPROPS structure.

UCHAR szCorrelationID[20];
aMsgPropId[i] = PROPID_M_CORRELATIONID;      // Property ID
aMsgPropVar[i].vt = VT_VECTOR | VT_UI1; // Type indicator
aMsgPropVar[i].caub.pElems = szCorrelationID;
aMsgPropVar[i].caub.cElems = sizeof(szCorrelationID);
i++;
For a complete example of | See
Setting the correlation identifier in a response message | Sending Response Messages

See Also

MQMSGPROPS, MQReceiveMessage, MQSendMessage, PROPID_M_MSGID


PROPID_M_DELIVERY

The PROPID_M_DELIVERY property specifies how Message Queuing delivers the message to the queue.

Property ID
PROPID_M_DELIVERY
Type Indicator
VT_UI1 (or VT_NULL)
MQPROPVARIANT Field
bVal

Property Values

This property can be set to one of the following values:

MQMSG_DELIVERY_RECOVERABLE
In every hop along its route, the message is forwarded to the next hop or stored locally in a backup file until delivered. This guarantees delivery even in case of a computer crash.
MQMSG_DELIVERY_EXPRESS
The default. The message stays in memory until it can be delivered. The message is not recovered if the computer is rebooted.

Remarks

When the delivery mode of a message is set to MQMSG_DELIVERY_EXPRESS (the default setting), the message has faster throughput. When the delivery mode is set to MQMSG_DELIVERY_RECOVERABLE, throughput may be slower, but Message Queuing guarantees that the message will be delivered, even if a computer crashes while the message is en-route to the queue.

To set the delivery mode of a message, specify PROPID_M_DELIVERY in the MQMSGPROPS structure and call MQSendMessage.

To retrieve the delivery mode of a message, specify PROPID_M_DELIVERY in the MQMSGPROPS structure. Then call MQReceiveMessage and examine its returned value. (When specifying PROPID_M_DELIVERY, you can set its Type Indicator to VT_NULL. When the Type Indicator is set to VT_NULL, Message Queuing sets the VT field to the appropriate type indicator.)

When sending messages within a transaction, Message Queuing always sets the delivery mode of the transactional message to MQMSG_DELIVERY_RECOVERABLE.

For information on | See
Sending message within a transaction | Message Queuing Transactions
Setting and retrieving the delivery mode when you are using COM components | MSMQMessage.Delivery

Example Code

The following example shows how PROPID_M_DELIVERY is specified in the MQMSGPROPS structure.

aMsgPropId[i] = PROPID_M_DELIVERY;   // Property ID
aMsgPropVar[i].vt = VT_UI1;             // Type indicator
aMsgPropVar[i].bVal = DELIVERY_MODE;
i++;
For a complete example of | See
Sending messages with different delivery modes | Sending Express and Recoverable Messages

See Also

MQMSGPROPS, MQReceiveMessage, MQSendMessage


PROPID_M_DEST_FORMAT_NAME

(Read-only, introduced in MSMQ 3.0) The PROPID_M_DEST_FORMAT_NAME property indicates the destination queues that the message was sent to.

Property ID
PROPID_M_DEST_FORMAT_NAME
Type Indicator
VT_LPWSTR
MQPROPVARIANT Field
pwszVal

Property Values

String that contains a public, private, direct, distribution list, or multiple-element format name.

Remarks

The PROPID_M_DEST_FORMAT_NAME property is set by the queue manager on the source computer. The PROPID_M_DEST_FORMAT_NAME and PROPID_M_DEST_QUEUE properties are used together to specify all the queues that the message was sent to and the specific queue that this copy of the message was sent to.

When acknowledgment message are returned by Message Queueing or a connector application, the PROPID_M_RESP_FORMAT_NAME property of the acknowledgment message is set to the value of the PROPID_M_DEST_FORMAT_NAME property of the original message.

When returning response messages, the receiving application can return the destination of the original message by setting the PROPID_M_RESP_FORMAT_NAME property of the response message to the value of PROPID_M_DEST_FORMAT_NAME or PROPID_M_DEST_QUEUE.

To retrieve the destination queue set, include the following two properties in the MQMSGPROPS structure, then call MQReceiveMessage and examine the returned values.

  • PROPID_M_DEST_FORMAT_NAME_LEN
  • PROPID_M_DEST_FORMAT_NAME

The following example code shows how PROPID_M_DEST_FORMAT_NAME and PROPID_M_DEST_FORMAT_NAME_LEN is specified in the MQMSGPROPS structure for retrieving the destination queue set.

aMsgPropId[i] = PROPID_M_DEST_FORMAT_NAME;     // Property ID
aMsgPropVar[i].vt = VT_LPWSTR;                 // Type indicator
aMsgPropVar[i].pwszVal = wszDestBuffer;
i++;

aMsgPropId[i] = PROPID_M_DEST_FORMAT_NAME_LEN;  // Property ID
aMsgPropVar[i].vt = VT_UI4;                     // Type indicator
aMsgPropVar[i].ulVal = dwDestBufferLength;
i++;

Equivalent COM Property

When using COM components, you can retrieve the destination queue set using the MSMQMessage.Destination property.

See Also

MQMSGPROPS, MQReceiveMessage, MSMQMessage.Destination, PROPID_M_DEST_FORMAT_NAME_LEN, PROPID_M_RESP_FORMAT_NAME


PROPID_M_DEST_FORMAT_NAME_LEN

(Introduced in MSMQ 3.0.) The PROPID_M_DEST_FORMAT_NAME_LEN property indicates the length (in Unicode characters) of the format name buffer allocated by the receiving application and the length of the format name string returned in PROPID_M_DEST_FORMAT_NAME.

Property ID
PROPID_M_DEST_FORMAT_NAME_LEN
Type Indicator
VT_UI4
MQPROPVARIANT Field
ulVal

Property Values

On input: The length of the format name buffer (in Unicode characters) allocated by the receiving application.

On return: The length (in Unicode characters) of the format name string (including the null-terminating character) returned in PROPID_M_DEST_FORMAT_NAME.

Remarks

The PROPID_M_DEST_FORMAT_NAME_LEN property is only used by the receiving application to allocate a buffer for the destination queue set. The queue manager of the source computer sets the destination properties of the message when the message is sent.

To retrieve the destination set, include the following two message properties in the MQMSGPROPS structure and then call MQReceiveMessage.

  • PROPID_M_DEST_FORMAT_NAME_LEN
  • PROPID_M_DEST_FORMAT_NAME

The following example code shows how PROPID_M_DEST_FORMAT_NAME and PROPID_M_DEST_FORMAT_NAME_LEN are specified in the MQMSGPROPS structure.

aMsgPropId[i] = PROPID_M_DEST_FORMAT_NAME_LEN;  // Property ID
aMsgPropVar[i].vt = VT_UI4;                     // Type indicator
aMsgPropVar[i].ulVal = dwDestinationBufferLength;
i++;

aMsgPropId[i] = PROPID_M_DEST_FORMAT_NAME;     // Property ID
aMsgPropVar[i].vt = VT_LPWSTR;                 // Type indicator
aMsgPropVar[i].pwszVal = wszDestinationBuffer;
i++;

If MQReceiveMessage fails, returning an MQ_ERROR_FORMATNAME_BUFFER_TOO_SMALL error, use the returned value of PROPID_M_DEST_FORMAT_NAME_LEN to reallocate the buffer, and call MQReceiveMessage again.

Equivalent COM Property

There is no equivalent COM property for this property.

See Also

MQMSGPROPS, MQReceiveMessage, PROPID_M_DEST_FORMAT_NAME


PROPID_M_DEST_QUEUE

The PROPID_M_DEST_QUEUE property identifies the original destination queue of a message.

Property ID
PROPID_M_DEST_QUEUE
Type Indicator
VT_LPWSTR
MQPROPVARIANT Field
pwszVal

Property Values

Format name of the destination queue.

Remarks

The PROPID_M_DEST_QUEUE property is only used by the receiving application. Message Queuing attaches this property to the message according to the destination queue specified in the call to MQSendMessage. It is typically retrieved in the following cases.

  • To determine the original destination queue of a message that Message Queuing puts in a journal queue.
  • To determine the original destination queue of a message that Message Queuing puts in a dead-letter queue.
  • To provide the original destination queue when returning response message back to a response queue.

When a message is sent to multiple destinations, Message Queuing sets this property to the specific destination of each copy of the message.

To retrieve the format name of the destination queue for a message, specify PROPID_M_DEST_QUEUE and PROPID_M_DEST_QUEUE_LEN in the MQMSGPROPS structure. Then call MQReceiveMessage and examine the returned values.

If MQReceiveMessage fails, returning an MQ_ERROR_BUFFER_OVERFLOW error, use the returned value of PROPID_M_DEST_QUEUE_LEN to reallocate the format name buffer. Then, call MQReceiveMessage again.

Equivalent COM Property

When using COM components, you can retrieve the destination queue of the message using MSMQMessage.DestinationQueueInfo.

Example Code

The following example shows how PROPID_M_DEST_QUEUE is specified in the MQMSGPROPS structure for retrieving the destination queue format name.

DWORD dwDestFormatNameBufferLength = 256;
WCHAR szDestFormatNameBuffer[256];
aMsgPropId[i] = PROPID_M_DEST_QUEUE;        // Property ID
aMsgPropVar[i].vt = VT_LPWSTR;              // Type indicator
aMsgPropVar[i].pwszVal = wszDestFormatNameBuffer;
i++;

aMsgPropId[i] = PROPID_M_DEST_QUEUE_LEN;    // Property ID
aMsgPropVar[i].vt = VT_UI4;                 // Type indicator
aMsgPropVar[i].ulVal = dwDestFormatNameBufferLength;
i++;

See Also

MQMSGPROPS, MQReceiveMessage, MQSendMessage, PROPID_M_DEST_QUEUE_LEN


PROPID_M_DEST_QUEUE_LEN

The PROPID_M_DEST_QUEUE_LEN property indicates the length (in Unicode characters) of the supplied format name buffer and the length of the returned format name string for the destination queue.

Property ID
PROPID_M_DEST_QUEUE_LEN
Type Indicator
VT_UI4
MQPROPVARIANT Field
ulVal

Property Values

On input: The length of the format name buffer (in Unicode characters) allocated by the receiving application.

On return: The length (in Unicode characters) of the format name string (including the null-terminating character) returned by PROPID_M_DEST_QUEUE.

Remarks

PROPID_M_DEST_QUEUE_LEN is required whenever PROPID_M_DEST_QUEUE is specified in the MQMSGPROPS structure.

To retrieve the format name of the destination queue, specify PROPID_M_DEST_QUEUE and PROPID_M_DEST_QUEUE_LEN in the MQMSGPROPS structure. Then call MQReceiveMessage and examine the returned values.

When MQReceiveMessage succeeds, the format name of the destination queue is returned in PROPID_M_DEST_QUEUE.

If MQReceiveMessage fails, returning an MQ_ERROR_FORMATNAME_BUFFER_TOO_SMALL error, use the returned value of PROPID_M_DEST_QUEUE_LEN to reallocate the format name buffer and call MQReceiveMessage again.

This property is not needed when you are using COM components.

Example Code

The following example shows how PROPID_M_DEST_QUEUE_LEN and PROPID_M_DEST_QUEUE are specified in the MQMSGPROPS structure.

DWORD dwDestFormatNameBufferLength = 256;
WCHAR szDestFormatNameBuffer[256];
aMsgPropId[i] = PROPID_M_DEST_QUEUE;        // Property ID
aMsgPropVar[i].vt = VT_LPWSTR;              // Type indicator
aMsgPropVar[i].pwszVal = wszDestFormatNameBuffer;
i++;

aMsgPropId[i] = PROPID_M_DEST_QUEUE_LEN;   // Property ID
aMsgPropVar[i].vt = VT_UI4;                // Type indicator
aMsgPropVar[i].ulVal = dwDestFormatNameBufferLength;
i++;
For a complete example of | See
Retrieving the destination queue when creating a response message | Sending Response Messages

See Also

MQMSGPROPS, MQReceiveMessage, PROPID_M_DEST_QUEUE


PROPID_M_DEST_SYMM_KEY

The PROPID_M_DEST_SYMM_KEY property specifies the symmetric key used to encrypt messages.

Property ID
PROPID_M_DEST_SYMM_KEY
Type Indicator
VT_UI1 | VT_VECTOR
MQPROPVARIANT Field
caub

Property Values

Encrypted symmetric key

Remarks

PROPID_M_DEST_SYMM_KEY is required when you send application-encrypted messages, or when you send encrypted messages to a foreign queue. The symmetric key must be encrypted with the public key of the receiving queue manager before this property is set.

When you send application-encrypted messages, the symmetric key is used by the receiving queue manager to decrypt the message before it is sent on to its destination queue.

Messages sent to a foreign queues are first received by the appropriate connector application. When the connector application receives the message, it forwards the encrypted message with the attached symmetric key to the receiving application. It is the responsibility of the receiving application to decrypt the symmetric key and the body of the message.

To send the symmetric key with a message, specify PROPID_M_DEST_SYMM_KEY and PROPID_M_CONNECTOR_TYPE in the MQMSGPROPS structure and call MQSendMessage. PROPID_M_CONNECTOR_TYPE must be set to tell Message Queuing to use the symmetric key provided by the sending application.

To retrieve the symmetric key from a message, specify PROPID_M_DEST_SYMM_KEY and PROPID_M_DEST_SYMM_KEY_LEN in the MQMSGPROPS structure (the length property is used to verify that the symmetric key was sent). Then call MQReceiveMessage and examine the returned values.

Before using the returned symmetric key, always check the length property PROPID_M_DEST_SYMM_KEY_LEN to see if a symmetric key was sent. If the returned value of the length property is 0, no key was sent. If the returned value is nopn-0, PROPID_M_DEST_SYMM_KEY contains the symmetric key.

For information on | See
Connector applications | MSMQ Connector Servers
Encrypting messages | Application-Encrypted Messages
Testing the returned length of the symmetric key | PROPID_M_DEST_SYMM_KEY_LEN
Setting and retrieving the destination symmetric key when you are using COM components | MSMQMessage.DestinationSymmetricKey

Example Code

The following examples show how PROPID_M_DEST_SYMM_KEY is specified in the MQMSGPROPS structure when sending and retrieving the symmetric key.

To send the destination symmetric key

aMsgPropId[i] = PROPID_M_DEST_SYMM_KEY;     // Property ID
aMsgPropVar[i].vt = VT_UI1 | VT_VECTOR;     // Type indicator
aMsgPropVar[i].caub.pElems = DestSymmetricKey;
aMsgPropVar[i].caub.cElems = sizeof(DestSymmetricKey);
i++;

aMsgPropId[i] = PROPID_M_CONNECTOR_TYPE;     // Property ID
aMsgPropVar[i].vt = VT_clsid;     // Type indicator
aMsgPropVar[i].puuid = &ConnectorType;
i++;

To retrieve the destination symmetric key

aMsgPropId[i] = PROPID_M_DEST_SYMM_KEY_LEN; // Property ID
aMsgPropVar[i].vt = VT_UI4;                 // Type indicator
i++;

aMsgPropId[i] = PROPID_M_DEST_SYMM_KEY;     // Property ID
aMsgPropVar[i].vt = VT_UI1 | VT_VECTOR;     // Type indicator
aMsgPropVar[i].caub.pElems = DestSymmetricKey;
aMsgPropVar[i].caub.cElems = sizeof(DestSymmetricKey);
i++;

See Also

MQMSGPROPS, MQReceiveMessage, MQSendMessage, PROPID_M_DEST_SYMM_KEY_LEN, MSMQMessage.DestinationSymmetricKey


PROPID_M_DEST_SYMM_KEY_LEN

The PROPID_M_DEST_SYMM_KEY_LEN property specifies the length of the symmetric key used to encrypt the message. It is set by Message Queuing when the message is sent.

Property ID
PROPID_M_DEST_SYMM_KEY_LEN
Type Indicator
VT_UI4 (or VT_NULL)
MQPROPVARIANT Field
ulVal

Property Values

The length of the symmetric key.

Remarks

PROPID_M_DEST_SYMM_KEY_LEN is only used by the receiving application. It is required whenever the receiving application specifies PROPID_M_DEST_SYMM_KEY to MQReceiveMessage.

To retrieve the symmetric key from a message, specify PROPID_M_DEST_SYMM_KEY_LEN and PROPID_M_DEST_SYMM_KEY in the MQMSGPROPS structure. Then call MQReceiveMessage and examine the returned values. (When specifying PROPID_M_DEST_SYMM_KEY_LEN, you can set its Type Indicator to VT_NULL. When the Type Indicator is set to VT_NULL, Message Queuing sets the VT field to the appropriate type indicator.)

When MQReceiveMessage succeeds, first test the returned value of PROPID_M_DEST_SYMM_KEY_LEN to see if a symmetric key exists. A returned value of 0 indicates that no key was sent by the sending application. A non-0 returned value indicates that a symmetric key was returned by PROPID_M_DEST_SYMM_KEY.

If MQReceiveMessage fails, returning an MQ_ERROR_SYMM_KEY_BUFFER_TOO_SMALL error, use the returned value of PROPID_M_DEST_SYMM_KEY_LEN to reallocate the symmetric key buffer and call MQReceiveMessage again.

This property is not needed when you are using COM components.

Example Code

The following example shows how PROPID_M_DEST_SYMM_KEY_LEN and PROPID_M_DEST_SYMM_KEY are specified in the MQMSGPROPS structure when retrieving the symmetric key.

aMsgPropId[i] = PROPID_M_DEST_SYMM_KEY_LEN; // Property ID
aMsgPropVar[i].vt = VT_UI4;                 // Type indicator
i++;

aMsgPropId[i] = PROPID_M_DEST_SYMM_KEY;     // Property ID
aMsgPropVar[i].vt = VT_UI1 | VT_VECTOR;     // Type indicator
aMsgPropVar[i].caub.pElems = DestSymmetricKey;
aMsgPropVar[i].caub.cElems = sizeof(DestSymmetricKey);
i++;

See Also

MQMSGPROPS, MQReceiveMessage, PROPID_M_DEST_SYMM_KEY


PROPID_M_ENCRYPTION_ALG

The PROPID_M_ENCRYPTION_ALG property specifies the encryption algorithm used to encrypt the message body of a private message.

Property ID
PROPID_M_ENCRYPTION_ALG
Type Indicator
VT_UI4
MQPROPVARIANT Field
ulVal

Property Values

This property can be set to one of the following values:

  • CALG_RC2 (the default)
  • CALG_RC4

Remarks

When you send private messages, the algorithm specified by PROPID_M_ENCRYPTION_ALG is used to encrypt the body of the message (this can be done by your application or by the sending queue manager) and to decrypt the message body when it is received by the receiving queue manager.

To set the encryption algorithm, specify PROPID_M_ENCRYPTION_ALG in the MQMSGPROPS structure and call MQSendMessage.

To retrieve the encryption algorithm, specify PROPID_M_ENCRYPTION_ALG in the MQMSGPROPS structure. Then call MQReceiveMessage and examine the returned value. (When specifying PROPID_M_ENCRYPTION_ALG, you can set its Type Indicator to VT_NULL. When the Type Indicator is set to VT_NULL, Message Queuing sets the VT field to the appropriate type indicator.)

The algorithm identifiers CALG_RC2 and CALG_RC4 are defined by the ALG_ID data type in wincrypt.h.

For information on | See
Letting Message Queuing encrypt messages | Message Queuing–Encrypted Messages
Having your application encrypt messages | Application-Encrypted Messages
Authenticated messages | How Message Queuing Authenticates Messages
Setting and retrieving the encryption algorithm when you are using COM components | MSMQMessage.EncryptAlgorithm

Example Code

The following example shows how PROPID_M_ENCRYPTION_ALG is specified in the MQMSGPROPS structure:

MsgProps.aPropID[i] = PROPID_M_ENCRYPTION_ALG ;  //PropId
MsgProps.aPropVar[i].vt = VT_UI4;                //Type
MsgProps.aPropVar[i].ulVal = CALG_RC4;           //Value
For a complete example of | See
Sending Message Queuing–encrypted private messages | Sending Private Messages

See Also

MQMSGPROPS, MQReceiveMessage, MQSendMessage, PROPID_M_PRIV_LEVEL


PROPID_M_EXTENSION

The PROPID_M_EXTENSION property provides a place to put additional application-defined information that is associated with the message.

Property ID
PROPID_M_EXTENSION
Type Indicator
VT_UI1 | VT_VECTOR
MQPROPVARIANT Field
caub

Property Values

Array of bytes

Remarks

The PROPID_M_EXTENSION property is typically used by applications that need to specify or read non-Message Queuing message properties when working with foreign queues. It is the responsibility of the application to understand the content of this property.

Sending Extension Information

To send extension information, specify PROPID_M_EXTENSION in the MQMSGPROPS structure, and call MQSendMessage.

Retrieving Extension Information

To retrieve extension information from a message, specify PROPID_M_EXTENSION and PROPID_M_EXTENSION_LEN in the MQMSGPROPS structure (the length property is used to verify that extension information was sent). Then call MQReceiveMessage and examine the returned values.

Before using the returned extension information, always check the length property PROPID_M_EXTENSION_LEN to see if extension information was sent. If the returned value of the length property is 0, no information was sent. If the returned value is non-0, PROPID_M_EXTENSION contains extension information.

For information on | See
Sending or receiving messages from foreign queues | MSMQ Connector Servers
Testing to see if extension information exists | PROPID_M_EXTENSION_LEN
Setting and retrieving extension information when you are using COM components | MSMQMessage.Extension

Example Code

The following examples show how PROPID_M_EXTENSION is specified in the MQMSGPROPS structure for sending and retrieving extension information.

To send extension information

aMsgPropId[i] = PROPID_M_EXTENSION;         // Property ID
aMsgPropVar[i].vt = VT_UI1 | VT_VECTOR;     // Type indicator
aMsgPropVar[i].caub.pElems = ExtensionInformation;
aMsgPropVar[i].caub.cElems = sizeof(ExtensionInformation);
i++;

To retrieve extension information

aMsgPropId[i] = PROPID_M_EXTENSION_LEN;     // Property ID
aMsgPropVar[i].vt = VT_UI4;                 // Type indicator
i++;

aMsgPropId[i] = PROPID_M_EXTENSION;         // Property ID
aMsgPropVar[i].vt = VT_UI1 | VT_VECTOR;     // Type indicator
i++;

See Also

MQMSGPROPS, MQReceiveMessage, MQSendMessage, MSMQMessage.Extension, PROPID_M_EXTENSION_LEN


PROPID_M_EXTENSION_LEN

The PROPID_M_EXTENSION_LEN property specifies the length of the information in the PROPID_M_EXTENSION property.

Property ID
PROPID_M_EXTENSION_LEN
Type Indicator
VT_UI4 (or VT_NULL)
MQPROPVARIANT Field
ulVal

Property Values

The size (in bytes) of the extension information specified by PROPID_M_EXTENSION.

Remarks

PROPID_M_EXTENSION_LEN is used only by the receiving application. It is used whenever the receiving application specifies PROPID_M_EXTENSION in the MQMSGPROPS structure.

To retrieve extension information, set PROPID_M_EXTENSION and PROPID_M_EXTENSION_LEN in the MQMSGPROPS structure. Then call MQReceiveMessage and examine the returned values. (When specifying PROPID_M_EXTENSION_LEN, you can set its Type Indicator to VT_NULL. When the Type Indicator is set to VT_NULL, Message Queuing sets the VT field to the appropriate type indicator.)

When MQReceiveMessage succeeds, first test the returned value of PROPID_M_EXTENSION_LEN to see if any extension information exists. A returned value of 0 indicates that no information was sent by the sending application. A non-0 returned value indicates the extension information was returned by PROPID_M_EXTENSION.

If MQReceiveMessage fails, returning an MQ_ERROR_BUFFER_OVERFLOW error, use the returned value of PROPID_M_EXTENSION_LEN to reallocate the extension information buffer and call MQReceiveMessage again.

This property is not needed when you are using COM components.

Example Code

The following example shows how PROPID_M_EXTENSION_LEN and PROPID_M_EXTENSION are specified in the MQMSGPROPS structure.

aMsgPropId[i] = PROPID_M_EXTENSION_LEN;     // Property ID
aMsgPropVar[i].vt = VT_UI4;                 // Type indicator
i++;

aMsgPropId[i] = PROPID_M_EXTENSION;         // Property ID
aMsgPropVar[i].vt = VT_UI1 | VT_VECTOR;     // Type indicator
i++;

See Also

MQMSGPROPS, MQReceiveMessage, PROPID_M_EXTENSION


PROPID_M_FIRST_IN_XACT

(Read-only. MSMQ 2.0 only.) The PROPID_M_FIRST_IN_XACT property indicates whether the message was the first message sent in a transaction.

Property ID
PROPID_M_FIRST_IN_XACT
Type Indicator
VT_UI1
MQPROPVARIANT Field
bVal

Property Values

One of the following:

MQMSG_FIRST_IN_XACT
The message was the first message sent in the transaction.
MQMSG_NOT_FIRST_IN_XACT
The message was not the first message sent in the transaction.

Remarks

This property is available for MSMQ 2.0 and later. It is used by receiving applications to verify that a message was the first message sent in a single transaction to a single queue.

You can use PROPID_M_FIRST_IN_XACT along with two other properties to verify transaction boundaries. These two properties are a property for checking the last message sent in a transaction and a property for retrieving the identifier of the transaction: PROPID_M_LAST_IN_XACT and PROPID_M_XACTID.

If only one message is sent in a transaction, both PROPID_M_FIRST_XACT and PROPID_M_LAST_XACT are set.

For information on | See
How transaction boundaries can be used | Checking for Transaction Boundaries when Receiving Messages
Checking the last message in the transaction | PROPID_M_LAST_IN_XACT
Retrieving the identifier of the transaction | PROPID_M_XACTID
Checking the first message using COM components | MSMQMessage.IsFirstInTransaction

Example Code

The following example shows how PROPID_M_FIRST_IN_XACT is specified in the MQMSGPROPS structure.

aMsgPropId[i] = PROPID_M_FIRST_IN_XACT; // Property ID
aMsgPropVar[i].vt = VT_UI1;             // Type indicator
aMsgPropVar[i].bVal;                    // Type indicator
i++;
For a complete example of | See
Checking first and last messages in a transaction | Checking Transaction Boundaries

See Also

PROPID_M_LAST_IN_XACT, PROPID_M_XACTID


PROPID_M_HASH_ALG

The PROPID_M_HASH_ALG property identifies the hashing algorithm Message Queuing uses when authenticating messages.

Property ID
PROPID_M_HASH_ALG
Type Indicator
VT_UI4
MQPROPVARIANT Field
ulVal

Property Values

This property can be set to any of the values defined by the ALG_ID data type in wincrypt.h (the default is CALG_MD5).

Remarks

To authenticate messages, the Message Queuing run-time DLL on the source computer uses the hashing algorithm when creating a digital signature for a message. The target queue manager then uses the same hashing algorithm to authenticate the message when it is received.

To set the hash algorithm, specify PROPID_M_HASH_ALG in the MQMSGPROPS structure and call MQSendMessage.

To retrieve the hash algorithm, specify PROPID_M_HASH_ALG in the MQMSGPROPS structure. Then call MQReceiveMessage and examine the returned value. (When specifying PROPID_M_HASH_ALG, you can set its Type Indicator to VT_NULL. When the Type Indicator is set to VT_NULL, Message Queuing sets the VT field to the appropriate type indicator.)

For information on | See
What Message Queuing does to authenticate messages | How Message Queuing Authenticates Messages
Setting and retrieving the hash algorithm when you are using COM components | MSMQMessage.HashAlgorithm

Example Code

The following example shows how PROPID_M_HASH_ALG is specified in the MQMSGPROPS structure.

aMsgPropId[i] = PROPID_M_HASH_ALG;         // Property ID
aMsgPropVar[i].vt = VT_UI4;                // Type indicator
MsgProps.aPropVar[i].ulVal = CALG_MD5;     //Value
i++;

See Also

MQMSGPROPS, MQReceiveMessage, MQSendMessage


PROPID_M_JOURNAL

The PROPID_M_JOURNAL property specifies how Message Queuing tracks messages as they are routed to the destination queue. This property can specify positive source journaling, negative source journaling, or both.

Property ID
PROPID_M_JOURNAL
Type Indicator
VT_UI1
MQPROPVARIANT Field
bVal

Property Values

Set PROPID_M_JOURNAL to one or more of the following values:

MQMSG_DEADLETTER
Negative source journaling is requested. Messages are stored in dead-letter queues on failure.

For non-transactional messages, failure means that the computer was not able to deliver the message to the next computer (for example, if a message timer expires).

For transactional messages, failure means that the source queue manager did not receive a confirmation that the message was removed from its destination queue.

MQMSG_JOURNAL
Positive source journaling is requested. A copy of the message is stored in computer journal on the computer if the message was successfully delivered to the next computer.
MQMSG_JOURNAL_NONE
The default. Message Queuing does not track the message.

Remarks

PROPID_JOURNAL can be set to the following combinations.

  • MQMSG_JOURNAL: Positive source journaling is requested. Messages are stored in computer journals on success but not in dead-letter queues on failure.
  • MQMSG_DEADLETTER: Negative source journaling is requested. Messages are stored in dead-letter queues on failure, but not in computer journals on success.
  • MQMSG_JOURNAL | MQMSG_DEADLETTER: Positive and negative source journaling is requested. Messages are stored in computer journals on success and stored in dead-letter queues on failure.
  • MQMSG_JOURNAL_NONE: Source journaling is disabled (default). Copies of messages are not stored in computer journals on success nor in dead-letter queues on failure.

Negative source journaling uses a transactional and non-transaction dead-letter queues to store message that fail. For non-transactional messages, failure means that a computer could not deliver the message. For transactional messages, failure means that the source queue manager did not receive a confirmation that the transactional message was removed from the destination queue. Copies of failed transactional messages are placed only in the transactional dead-letter queue of the source computer.

For transactional messages, the default semantics for the source computer can be changed by setting the following registry to one of two setting.

XactDeadLetterAlways

The default negative source journaling semantics for transactional messages are:

  • Negative source journaling always: The XactDeadLetterAlways registry key is set to 1.

    When this default is used, Message Queuing puts a copy of every unconfirmed message in the transactional dead-letter queue of the source computer regardless of what the journaling property of the transactional messages are set to. These are the default semantics for MSMQ 1.0 and MSMQ 3.0.

  • Negative source journaling optional: The XactDeadLetterAlways registry key is set to 0.

    When this default is used, Message Queueing places a copy of unconfirmed transactional messages in the transactional dead-letter queue of the source computer only when the journaling property of the message specifies MQMSG_DEADLETTER. This is the default semantics for MSMQ 2.0.

Processing messages in computer journals and dead-letter queues is the responsibility of the application or the Message Queuing administrator. Messages should be removed from these queues on a regular basis so that they do not consume the resources of the computer. Messages stored in dead-letter queues count against the quota of the computer (the computer quota is set by Message Queuing administrator).

PROPID_M_JOURNAL does not create a computer journal or dead-letter queue. Computer journal and dead-letter queues are system queues generated by Message Queuing.

To specify journaling, include PROPID_M_JOURNAL in the MQMSGPROPS structure and then call MQSendMessage.

The following example code shows how PROPID_M_JOURNAL is added to the MQMSGPROPS structure to set the journaling level.

aMsgPropId[i] = PROPID_M_JOURNAL;           // Property ID
aMsgPropVar[i].vt = VT_UI1;                 // Type indicator
MsgProps.aPropVar[i].bVal = MQMSG_JOURNAL;  // Value
i++;

To retrieve the journaling level specified by the sending application, include PROPID_M_JOURNAL in the MQMSGPROPS structure, then call MQReceiveMessage and examine the returned values.

The following example code shows how PROPID_M_JOURNAL is added to the MQMSGPROPS structure to retrieve the journaling level.

aMsgPropId[i] = PROPID_M_JOURNAL;           // Property ID
aMsgPropVar[i].vt = VT_UI1;                 // Type indicator
i++;

Equivalent COM Property

When using COM components, you can set the journaling level of the message using the MSMQMessage.Journal property.

For information on | See
How messages are stored when positive source journaling is enabled | Positive Source Journaling
How messages are stored when negative source journaling is enabled | Negative Source Journaling
What are computer journal and dead-letter queues | Journal Queues

See Also

MQMSGPROPS, MQReceiveMessage, MQSendMessage


PROPID_M_LABEL

The PROPID_M_LABEL property specifies a label of the message.

Property ID
PROPID_M_LABEL
Type Indicator
VT_LPWSTR
MQPROPVARIANT Field
pwszVal

Property Values

Arbitrary string (the default is none). Maximum length is 250 Unicode characters (including the end-of-string character).

Remarks

If the sending application specifies a message label longer than 250 Unicode characters, Message Queuing returns an MQ_ERROR_LABEL_TOO_LONG error to the aStatus array.

To send a label with a message, specify PROPID_M_LABEL in the MQMSGPROPS structure and call MQSendMessage.

To retrieve the label of a message, specify PROPID_M_LABEL and PROPID_M_LABEL_LEN in the MQMSGPROPS structure. Then call MQReceiveMessage and examine the returned values.

Before using the message label, always check the length property PROPID_M_LABEL_LEN to see if the label was sent with the message. If the returned value of PROPID_M_LABEL_LEN is 0, no label was sent with the message. If the returned value is non-0, PROPID_M_LABEL contains the label of the message.

For information on | See
Testing to see if a label exists | PROPID_M_LABEL_LEN
Setting and retrieving the message label when you are using COM components | MSMQMessage.Label

Example Code

The following examples show how PROPID_M_LABEL is specified in the MQMSGPROPS structure for setting and retrieving the message label:

To send a message label

aMsgPropId[i] = PROPID_M_LABEL;            // PropId
aMsgPropVar[i].vt = VT_LPWSTR;             // Type
aMsgPropVar[i].pwszVal = L"Test Message";  // Value
i++;

To retrieve the message label

aMsgPropId[i] = PROPID_M_LABEL_LEN;        // Property ID
aMsgPropVar[i].vt =VT_UI4;                 // Type indicator
aMsgPropVar[i].ulVal = 250;                // Label buffer size
i++;

aMsgPropId[i] = PROPID_M_LABEL;            // Property ID
aMsgPropVar[i].vt = VT_LPWSTR;             // Type indicator
aMsgPropVar[i].pwszVal = wszLabelBuffer;   // Label buffer
i++;

See Also

aStatus, MQMSGPROPS, MQReceiveMessage, MQSendMessage, PROPID_M_LABEL_LEN


PROPID_M_LABEL_LEN

The PROPID_M_LABEL_LEN property identifies the length (in Unicode characters) of the message label buffer.

Property ID
PROPID_M_LABEL_LEN
Type Indicator
VT_UI4
MQPROPVARIANT Field
ulVal

Property Values

Input: The size (in Unicode characters) of the message label buffer allocated by the receiving application.

Return: The length (in Unicode characters) of the label string plus the end-of-string character.

Remarks

PROPID_M_LABEL_LEN is only used by the receiving application. It is required whenever PROPID_M_LABEL is specified in the MQMSGPROPS structure.

On input, the message label buffer should be large enough to hold the complete label string including the end-of-string character. MQReceiveMessage succeeds if the buffer is large enough to hold the message label. If the buffer is too small, MQReceiveMessage fails and PROPID_M_LABEL_LEN can be used to obtain the required buffer length of the message label string.

To retrieve the label of a message, specify PROPID_M_LABEL_LEN and PROPID_M_LABEL in the MQMSGPROPS structure. Then call MQReceiveMessage and examine the returned values.

When MQReceiveMessage succeeds, first test the returned value of PROPID_M_LABEL_LEN to see if a message label exists. A returned value of 0 indicates that no label was specified by the sending application. A non-0 returned value indicates that the label was returned by PROPID_M_LABEL.

If MQReceiveMessage fails, returning an MQ_ERROR_BUFFER_TOO_SMALL error, use the returned value of PROPID_M_LABEL_LEN to reallocate the message label buffer and call MQReceiveMessage again.

When retrieving the label of several messages, make sure you reset the value of PROPID_M_LABEL_LEN to the maximum label size allowed by Message Queuing (250 Unicode characters) before retrieving the next label. If it is not reset, an error will be returned if the new label is longer than the previous label.

This property is not needed when you are using COM components.

Example Code

The following example shows how PROPID_M_LABEL_LEN is specified in the MQMSGPROPS structure when retrieving the message label:

aMsgPropId[i] = PROPID_M_LABEL_LEN;        // Property ID
aMsgPropVar[i].vt =VT_UI4;                 // Type indicator
aMsgPropVar[i].ulVal = 250;                // Label buffer size
i++;

aMsgPropId[i] = PROPID_M_LABEL;            // Property ID
aMsgPropVar[i].vt = VT_LPWSTR;             // Type indicator
aMsgPropVar[i].pwszVal = wszLabelBuffer;   // Label buffer
i++;

See Also

MQMSGPROPS, MQReceiveMessage, PROPID_M_LABEL


PROPID_M_LAST_IN_XACT

(Read-only. MSMQ 2.0 only.) The PROPID_M_LAST_IN_XACT property indicates whether the message was the last message sent in a transaction.

Property ID
PROPID_M_LAST_IN_XACT
Type Indicator
VT_UI1
MQPROPVARIANT Field
bVal

Property Values

One of the following:

MQMSG_LAST_IN_XACT
The message was the last message sent in the transaction.
MQMSG_NOT_LAST_IN_XACT
the message was not the last message sent in the transaction.

Remarks

This property is available for MSMQ 2.0 and later. It is used by receiving applications to verify that a message was the last message sent from a single transaction to a single queue.

You can use PROPID_M_LAST_IN_XACT along with two other properties to verify transaction boundaries. These two properties are a property for checking the first message sent in a transaction and a property for retrieving the identifier of the transaction: PROPID_M_FIRST_IN_XACT and PROPID_M_XACTID.

If only one message is sent in a transaction, both PROPID_M_FIRST_XACT and PROPID_M_LAST_XACT are set.

For information on | See
How transaction boundaries can be used | Checking for Transaction Boundaries when Receiving Messages
Checking the first message in the transaction | PROPID_M_FIRST_IN_XACT
Retrieving the identifier of the transaction | PROPID_M_XACTID
Checking the last message using COM components | MSMQMessage.IsLastInTransaction

Example Code

The following example shows how PROPID_M_LAST_IN_XACT is specified in the MQMSGPROPS structure.

aMsgPropId[i] = PROPID_M_LAST_IN_XACT; // Property ID
aMsgPropVar[i].vt = VT_UI1;             // Type indicator
aMsgPropVar[i].bVal;                    // Type indicator
i++;
For a complete example of | See
Checking first and last messages in a transaction | Checking Transaction Boundaries

See Also

PROPID_M_FIRST_IN_XACT, PROPID_M_XACTID


PROPID_M_LOOKUPID

(Read-only, introduced in MSMQ 5.0.) The PROPID_M_LOOKUPID property indicates the lookup identifier of the message.

Property ID
PROPID_M_LOOKUPID
Type Indicator
VT_UI8
MQPROPVARIANT Field
uhVal

Property Values

A 64-bit local number that is unique to the queue where the message resides.

Remarks

The PROPID_M_LOOKUPID property is a 64-bit, local number that is set by the target queue manager when the queue manager places the message in the queue. The receiving application can use the lookup identifier when calling the MQReceiveMessageByLookupId function to peek at or retrieve the message from the queue without navigating the queue. For information on peeking at or retrieving messages based on their lookup identifiers, see Message Lookup Identifier.

Obtaining the lookup identifiers of the messages in the queue is the responsibility of the application. One possible way to obtain the lookup identifiers is to create a trigger for the destination queue that invokes a component that caches the identifiers of each message as it is placed in the queue.

To retrieve the lookup identifier of a message, include PROPID_M_LOOKUPID in the MQMSGPROPS structure, then call MQReceiveMessage and examine the returned values.

The following example shows how PROPID_M_LOOKUPID is specified in the MQMSGPROPS structure for retrieving the lookup identifier.

ULONGLONG ullLookupId;
aPropID[i] = PROPID_Q_LOOKUPID;             // Property identifier
aVariant[i].vt = VT_UI8;                    // Type indicator
aVariant[i].uhVal = &ullLookupId;
i++;

Equivalent COM Property

When using COM components, you can look at the lookup identifier of a message using the MSMQMessage.LookupId property.

See Also

MQReceiveMessageByLookupId, MSMQMessage.LookupId


PROPID_M_MSGID

The PROPID_M_MSGID property indicates the Message Queuing–generated identifier of the message.

Property ID
PROPID_M_MSGID
Type Indicator
VT_VECTOR | VT_UI1
MQPROPVARIANT Field
caub

Property Values

20-byte Message Queuing–generated message identifier.

Remarks

Message Queuing generates a 20-byte message identifier when the message is sent. This identifier is composed of the machine GUID of the computer that sent the message plus an identifier that uniquely identifies each message on the computer. By combining these two components, the message identifier is unique within your enterprise.

Message Queuing generates message identifiers for all messages, including acknowledgment messages generated by Message Queuing and connector applications. When an acknowledgment message is created, the identifier of the original message can be found in the PROPID_M_CORRELATIONID property of the acknowledgment message.

The message identifier is an array of bytes that can be read by either the sending or receiving application. To retrieve the identifier of a message, specify PROPID_M_MSGID in the MQMSGPROPS structure. Then call MQSendMessage or MQReceiveMessage and examine the returned identifier.

This property can also be used when sending response messages. For example, the application creating the response message can set the correlation identifier (PROPID_M_CORRELATIONID) of the response message to the identifier of the message it read from the queue. This gives the application reading the response message a way to know which message the response is referring to.

For information on | See
Retrieving the message identifier when you are using COM components | MSMQMessage.Id

Example Code

The following example shows how PROPID_M_MSGID is specified in the MQMSGPROPS structure for retrieving the identifier of a message.

MsgProps.aPropID[i] = PROPID_M_MSGID;                 // Property ID
MsgProps.aPropVar[i].vt = VT_VECTOR|VT_UI1;          // Type indicator
MsgProps.aPropVar[i].caub.pElems = MessageID;
MsgProps.aPropVar[i].caub.cElems = sizeof(MessageID);
i++
For a complete example of | See
Retrieving the message identifier when creating a response message | Sending Response Messages

See Also

MQMSGPROPS, MQReceiveMessage, MQSendMessage, PROPID_M_CORRELATIONID


PROPID_M_PRIORITY

The PROPID_M_PRIORITY property specifies the priority of the message. A lower number means a lower-priority message.

Property ID
PROPID_M_PRIORITY
Type Indicator
VT_UI1 (or VT_NULL)
MQPROPVARIANT Field
bVal

Property Values

An integer value between 7 and 0 (the default is 3).

Remarks

Message priority effects how Message Queuing handles the message while it is in route, as well as where the message is placed in the queue. Higher-priority messages are given preference during routing, and inserted toward the front of the queue. For example, when routing messages, Message Queuing handles messages with a priority of 7 before it handles messages with a priority of 0, and when the message is delivered to the destination queue, Message Queuing places the priority 7 messages closer to the front of the queue.

Messages with the same priority are placed in the queue according to their arrival time.

When Message Queuing routes a message to a public queue, the priority level of the message is added to the priority level of the public queue (the priority level of the queue is specified by the PROPID_Q_BASEPRIORITY property of the queue). Message Queuing uses this combined priority for routing only. The priority level of the queue has no effect on the order in which messages are placed in the queue.

Message Queuing automatically sets the priority level of transactional messages to 0: PROPID_M_PRIORITY is ignored by the transaction.

To specify the priority level of a message, include PROPID_M_PRIORITY in the MQMSGPROPS structure and then call MQSendMessage.

The following example code shows how PROPID_M_PRIORITY is specified the MQMSGPROPS structure.

aMsgPropID[i] = PROPID_M_PRIORITY;          // Property ID
aMsgPropVar[i].vt = VT_UI1;                 // Type indicator
aMsgPropVar[i].bVal = 7;
i++;

To retrieve the priority level specified by the sending application, include PROPID_M_PRIORITY in the MQMSGPROPS structure, then call MQReceiveMessage and examine the returned values. When specifying PROPID_M_PRIORITY, you can set its Type Indicator to VT_UI1 or VT_NULL. When the Type Indicator is set to VT_NULL, Message Queuing sets the VT field to the appropriate type indicator.

The following examples show how PROPID_M_PRIORITY is specified in the MQMSGPROPS structure for retrieving the priority level of the message.

aMsgPropID[i] = PROPID_M_PRIORITY;          // Property ID
aMsgPropVar[i].vt = VT_NULL;                // Type indicator
i++;

Equivalent COM Property

When using COM components, you can specify the priority leve4l of a message using MSMQMessage.Priority.

For information on | See
How messages are sent and retrieved in transactions | Message Queuing Transactions

See Also

MQMSGPROPS, MQReceiveMessage, MQSendMessage, PROPID_Q_BASEPRIORITY


PROPID_M_PRIV_LEVEL

The PROPID_M_PRIV_LEVEL property specifies the privacy level of the message.

Property ID
PROPID_M_PRIV_LEVEL
Type Indicator
VT_UI4 (or VT_NULL)
MQPROPVARIANT Field
ulVal

Property Values

This property can be set to one or more of the following values:

MQMSG_PRIV_LEVEL_BODY
Privacy is enforced. 40-bit end-to-end encryption of the message body is used.
MQMSG_PRIV_LEVEL_BODY_BASE
(MSMQ 2.0 only) Privacy is enforced. 40-bit end-to-end encryption of the message body is used.
MQMSG_PRIV_LEVEL_BODY_ENHANCED
(MSMQ 2.0 only) Privacy is enforced. 128-bit end-to-end encryption of the message body is used.
MQMSG_PRIV_LEVEL_NONE
The default. No privacy. The message body is sent as clear text.

Remarks

To have Message Queuing encrypt a private message, specify PROPID_M_PRIV_LEVEL in the MQMSGPROPS structure and call MQSendMessage. If PROPID_M_PRIV_LEVEL is set to MQMSG_PRIV_LEVEL_BODY, MQMSG_PRIV_LEVEL_BODY_BASE, or MQMSG_PRIV_LEVEL_BODY_ENHANCED, Message Queuing encrypts the body of the message using the algorithm specified by PROPID_M_ENCRYPTION_ALG.

Note MSMQ 2.0 applications can use MQMSG_PRIV_LEVEL_BODY or MQMSG_PRIV_LEVEL_BODY_BASE for 40-bit encryption.

To find out if a message was sent encrypted, specify PROPID_M_PRIV_LEVEL in the MQMSGPROPS structure. Then call MQReceiveMessage and examine the returned value. (When specifying PROPID_M_PRIV_LEVEL, you can set its Type Indicator to VT_NULL. When the Type Indicator is set to VT_NULL, Message Queuing sets the VT field to the appropriate type indicator.)

Messages can also be encrypted by applications. If your application is encrypting the message body with a 40-bit key, ignore the PROPID_M_PRIV_LEVEL property when sending messages. If your application is using a 128-bit key, set PROPID_M_PRIV_LEVEL to MQMSG_PRIV_LEVEL_BODY_ENHANCED and include it with the message.

The destination queue can also have its own privacy level (PROPID_Q_PRIV_LEVEL), indicating that it will only receive private (encrypted) messages. If the target queue forces privacy, non-encrypted messages will be rejected.

For information on | See
Letting Message Queuing encrypt messages | Message Queuing–Encrypted Messages
Having your application encrypt messages | Application-Encrypted Messages
Setting and retrieving the privacy level when you are using COM components | MSMQMessage.Priv_Level

Example Code

The following example shows how PROPID_M_PRIV_LEVEL is specified in the MQMSGPROPS structure:

MsgProps.aPropID[i] = PROPID_M_PRIV_LEVEL;               // PropId
MsgProps.aPropVar[i].vt = VT_UI4;                        // Type
MsgProps.aPropVar[i].ulVal = MQMSG_PRIV_LEVEL_BODY_BASE; // Value
For a complete example of | See
Sending private messages (including creating a queue that can only accept private messages) | Sending Private Messages

See Also

MQMSGPROPS, MQReceiveMessage, MQSendMessage, PROPID_M_ENCRYPTION_ALG, PROPID_Q_PRIV_LEVEL


PROPID_M_PROV_NAME

The PROPID_M_PROV_NAME property specifies the name of the cryptographic provider used to generate the digital signature of the message.

Property ID
PROPID_M_PROV_NAME
Type Indicator
VT_LPWSTR
MQPROPVARIANT Field
pwszVal

Property Values

Unicode string of the provider name (the default is "Microsoft Base Cryptographic Provider, Ver. 1.0").

Remarks

The PROPID_M_PROV_NAME property is typically used when working with foreign queues. The name and type (PROPID_M_PROV_TYPE) of the cryptographic provider are required to validate the digital signature of messages sent to a foreign queue or messages passed to Message Queuing from a foreign queue.

To send the name of the cryptographic provider with the message, specify PROPID_M_PROV_NAME and PROPID_M_PROV_TYPE in the MQMSGPROPS structure and call MQSendMessage.

When PROPID_M_PROV_NAME is specified, Message Queuing automatically sets PROPID_M_PROV_NAME_LEN to the length of the provider name.

To retrieve the name of the cryptographic provider from a message, specify PROPID_M_PROV_NAME and PROPID_M_PROV_NAME_LEN in the MQMSGPROPS structure (the length property is used to verify that the cryptographic provider name was sent). Then call MQReceiveMessage and examine the returned values.

Before using the cryptographic provider name, always check the length property PROPID_M_PROV_NAME_LEN to see if the cryptographic provider name was sent with the message. If the returned value of PROPID_M_PROV_NAME_LEN is 0, no format name was sent with the message. If the returned value is non-0, PROPID_M_PROV_NAME contains the name of the cryptographic provider.

For information on | See
Working with foreign queues | MSMQ Connector Servers
Testing to see if a provider name was sent | PROPID_M_PROV_NAME_LEN
Setting and retrieving the provider name when you are using COM components | MSMQMessage.AuthenticationProviderName

Example Code

The following examples show how PROPID_M_PROV_NAME is specified in the MQMSGPROPS structure for setting and retrieving the cryptographic provider.

To send the cryptographic provider name

aMsgPropId[i] = PROPID_M_PROV_NAME;         // Property ID
aMsgPropVar[i].vt = VT_LPWSTR;              // Type indicator
aMsgPropVar[i].pwszVal = wszProviderNameBuffer;
i++;

aMsgPropId[i] = PROPID_M_PROV_TYPE;         // Property ID
aMsgPropVar[i].vt = VT_UI4;                 // Type indicator
aMsgPropVar[i].pwszVal = dwProviderType;
i++;

To retrieve the cryptographic provider name

aMsgPropId[i] = PROPID_M_PROV_NAME_LEN;     // Property ID
aMsgPropVar[i].vt = VT_UI4;                 // Type indicator
aMsgPropVar[i].ulVal = dwProviderNameLength;
i++;

aMsgPropId[i] = PROPID_M_PROV_NAME;         // Property ID
aMsgPropVar[i].vt = VT_LPWSTR;              // Type indicator
aMsgPropVar[i].pwszVal = wszProviderNameBuffer;
i++;

See Also

MQMSGPROPS, MQReceiveMessage, MQSendMessage, MSMQMessage.AuthenticationProviderName, PROPID_M_PROV_NAME_LEN, PROPID_M_PROV_TYPE


PROPID_M_PROV_NAME_LEN

The PROPID_M_PROV_NAME_LEN property identifies the length of the name of the cryptographic provider used for validating the message signature.

This property is typically used when passing authenticated messages to and from a foreign queue. For information on authenticated messages and foreign queues, see MSMQ Connector Servers.

Property ID
PROPID_M_PROV_NAME_LEN
Type Indicator
VT_UI4
MQPROPVARIANT Field
ulVal

Property Values

On input: The size (in Unicode characters) of the buffer allocated by the receiving application.

On return: The length (in Unicode characters) of the cryptographic provider name, plus the end-of-string character, returned by PROPID_M_PROV_NAME.

Remarks

PROPID_M_PROV_NAME_LEN is only used by the receiving application. It is required whenever PROPID_M_PROV_NAME is specified in the MQMSGPROPS structure.

On input, the provider name buffer should be large enough to hold the complete provider name string including the end-of-string character.

To retrieve the name of the cryptographic provider from a message, set PROPID_M_PROV_NAME and PROPID_M_PROV_NAME_LEN in the MQMSGPROPS structure. Then call MQReceiveMessage and examine the returned values.

When MQReceiveMessage succeeds, first test the returned value of PROPID_M_PROV_NAME_LEN to see if a provider name exists. A returned value of 0 indicates that provider name was not specified by the sending application. A non-0 return value indicates that a provider name was returned by PROPID_M_PROV_NAME.

If MQReceiveMessage fails, returning an MQ_ERROR_PROV_NAME_BUFFER_TOO_SMALL error, use the returned value of PROPID_M_PROV_NAME_LEN to reallocate the provider name buffer and call MQReceiveMessage again.

This property is not needed when you are using COM components.

Example Code

The following example shows how PROPID_M_PROV_NAME_LEN is specified in the MQMSGPROPS structure when retrieving the name of the cryptographic provider.

aMsgPropId[i] = PROPID_M_PROV_NAME_LEN;     // Property ID
aMsgPropVar[i].vt = VT_UI4;                // Type indicator
aMsgPropVar[i].ulVal = dwProviderNameLength;
i++;

aMsgPropId[i] = PROPID_M_PROV_NAME;         // Property ID
aMsgPropVar[i].vt = VT_LPWSTR;              // Type indicator
aMsgPropVar[i].pwszVal = wszProviderNameBuffer;
i++;

See Also

MQMSGPROPS, MQReceiveMessage, PROPID_M_PROV_NAME


PROPID_M_PROV_TYPE

The PROPID_M_PROV_TYPE property specifies the type of cryptographic provider used to generate the digital signature of the message.

Property ID
PROPID_M_PROV_TYPE
Type Indicator
VT_UI4 (or VT_NULL)
MQPROPVARIANT Field
ulVal

Property Values

Possible values provided in wincrypt.h (the default is PROV_RSA_FULL).

Remarks

The PROPID_M_PROV_TYPE property is typically used when working with foreign queues. The type and name (PROPID_M_PROV_NAME) of the cryptographic provider is required to validate the digital signature of a message sent to a foreign queue or messages passed to Message Queuing from a foreign queue.

To specify the type of cryptographic provider, specify PROPID_M_PROV_TYPE in the MQMSGPROPS and call MQSendMessage.

To retrieve the type of cryptographic provider, specify PROPID_M_PROV_TYPE in the MQMSGPROPS structure. Then call MQReceiveMessage and examine the returned value. (When specifying PROPID_M_PROV_TYPE, you can set its Type Indicator to VT_NULL. When the Type Indicator is set to VT_NULL, Message Queuing sets the VT field to the appropriate type indicator.)

For information on | See
Working with foreign queues | MSMQ Connector Servers
Setting and retrieving the provider type when you are using COM components | MSMQMessage.AuthenticationProviderType

Example Code

The following examples show how PROPID_M_PROV_TYPE is specified in the MQMSGPROPS structure for setting the cryptographic provider name and type.

To send the cryptographic provider name

aMsgPropId[i] = PROPID_M_PROV_NAME;         // Property ID
aMsgPropVar[i].vt = VT_LPWSTR;              // Type indicator
aMsgPropVar[i].pwszVal = wszProviderNameBuffer;
i++;

aMsgPropId[i] = PROPID_M_PROV_TYPE;         // Property ID
aMsgPropVar[i].vt = VT_UI4;                 // Type indicator
aMsgPropVar[i].pwszVal = dwProviderType;
i++;

See Also

MQReceiveMessage, MQMSGPROPS, MSMQMessage.AuthenticationProviderType, PROPID_M_PROV_NAME


PROPID_M_RESP_FORMAT_NAME

(Introduced in MSMQ 3.0) The PROPID_M_RESP_FORMAT_NAME property supersedes the PROPID_M_RESP_QUEUE property (both properties cannot be set at the same time for the message). This property specifies the response queues used for returned application-generated response messages.

Property ID
PROPID_M_RESP_FORMAT_NAME
Type Indicator
VT_LPWSTR
MQPROPVARIANT Field
pwszVal

Property Values

String that contains a public, private, direct, distribution list, or multiple-element format name.

Remarks

The PROPID_M_RESP_FORMAT_NAME property is set by the sending application when requesting response messages from the receiving application. Response messages are application defined messages that must be understood by the application sending the response and the application reading the response. Message Queuing has no control over the content of the response message.

Response queues can be any transactional or non-transactional queue.

Sets of response queues can be specified using the following format names.

  • Distribution list format names are used to reference response queues based on a public distribution list that is published in Active Directory. For information on the syntax of distribution list format names, see Distribution List Format Names.
  • Multicast address format names are used to reference response queues that are associated with a specific multicast address. For information on the syntax of multicast address format names, see Multicast Address Format Names.
  • Multiple-element format names are used to reference response queues based on a private list of destination queues. For information on the syntax of multiple element format names, see Multiple-Element Format Names.

Message Queuing provides backwards compatibility for sending applications that send message to MSMQ 2.0 computers, and for receiving applications that read messages sent from MSMQ 2.0 computers.

When sending messages, the queue manager sets the PROPID_M_RESP_QUEUE property of the message to one of the following values.

  • If the PROPID_M_RESP_FORMAT_NAME property contains a single public, private, or direct format name, the PROPID_M_RESP_QUEUE property is set to the format name string specified by PROPID_M_RESP_FORMAT_NAME.
  • If the PROPID_M_RESP_FORMAT_NAME property contains a multiple-element format name, the PROPID_M_RESP_QUEUE property is set to the first non-distribution list element in the format name string.
  • If PROPID_M_RESP_FORMAT_NAME contains a distribution list, the PROPID_M_RESP_QUEUE property is set to NULL.

When receiving MSMQ 1.0 or MSMQ 2.0 message, the receiving queue manager sets PROPID_M_RESP_FORMAT_NAME to the format name specified by the PROPID_M_RESP_QUEUE property.

When acknowledgment message are returned by Message Queueing or a connector application, the PROPID_M_RESP_FORMAT_NAME property of the acknowledgment message is set to the value of the PROPID_M_DEST_FORMAT_NAME property of the original message.

To set response queues, include PROPID_M_RESP_FORMAT_NAME in the MQMSGPROPS structure and then call MQSendMessage.

The following example code shows how PROPID_M_RESP_FORMAT_NAME is specified in the MQMSGPROPS structure.

aMsgPropId[i] = PROPID_M_RESP_FORMAT_NAME;     // Property ID
aMsgPropVar[i].vt = VT_LPWSTR;                 // Type indicator
aMsgPropVar[i].pwszVal = wszRespQueueBuffer;
i++;

To retrieve the response queues specified by the sending application, include the following two properties in the MQMSGPROPS structure, then call MQReceiveMessage and examine the returned values.

  • PROPID_M_RESP_FORMAT_NAME
  • PROPID_M_RESP_FORMAT_NAME_LEN

The following example code shows how PROPID_M_RESP_FORMAT_NAME and PROPID_M_RESP_FORMAT_NAME_LEN are added to the MQMSGPROPS structure.

aMsgPropId[i] = PROPID_M_RESP_FORMAT_NAME;     // Property ID
aMsgPropVar[i].vt = VT_LPWSTR;                 // Type indicator
aMsgPropVar[i].pwszVal = wszRespQueueBuffer;
i++;

aMsgPropId[i] = PROPID_M_RESP_FORMAT_NAME_LEN;  // Property ID
aMsgPropVar[i].vt = VT_UI4;                     // Type indicator
aMsgPropVar[i].ulVal = dwRespQueueBufferLength;
i++;

When retrieving the response queue set, always check the PROPID_M_RESP_FORMAT_NAME_LEN property first to see if the response queues were specified by the sending application. If the returned value of PROPID_M_RESP_FORMAT_NAME_LEN is 0, no response queues were sent with the message. If the returned value is non-0, PROPID_M_RESP_FORMAT_NAME contains the format name, MQF, or distribution list of the response queue set.

Equivalent COM Property

When using COM components, you can specify a set of response queues using MSMQMessage.ResponseDestination.

See Also

MSMQMessage.ResponseDestination, MQMSGPROPS, MQReceiveMessage, MQSendMessage, PROPID_M_DEST_FORMAT_NAME, PROPID_M_RESP_QUEUE, PROPID_M_RESP_FORMAT_NAME_LEN


PROPID_M_RESP_FORMAT_NAME_LEN

(Introduced in MSMQ 3.0) The PROPID_M_RESP_FORMAT_NAME_LEN property indicates the length (in Unicode characters) of the format name buffer allocated by the receiving application and the length of format name string returned in PROPID_M_RESP_FORMAT_NAME.

Property ID
PROPID_M_RESP_FORMAT_NAME_LEN
Type Indicator
VT_UI4
MQPROPVARIANT Field
ulVal

Property Values

On input: The length of the format name buffer (in Unicode characters) allocated by the receiving application.

On return: The length (in Unicode characters) of the format name string (including the null-terminating character) returned in PROPID_M_RESP_FORMAT_NAME.

Remarks

The PROPID_M_RESP_FORMAT_NAME_LEN property is only used by the receiving application to allocate a buffer for the response queue set specified by the sending application. The sending application specifies response queues when it expects the receiving application to return response messages.

To retrieve the response queue set, include the following two message properties in the MQMSGPROPS structure and then call MQReceiveMessage.

  • PROPID_M_RESP_FORMAT_NAME_LEN
  • PROPID_M_RESP_FORMAT_NAME

The following example code shows how PROPID_M_RESP_FORMAT_NAME and PROPID_M_RESP_FORMAT_NAME_LEN are specified in the MQMSGPROPS structure.

aMsgPropId[i] = PROPID_M_RESP_FORMAT_NAME;     // Property ID
aMsgPropVar[i].vt = VT_LPWSTR;              // Type indicator
aMsgPropVar[i].pwszVal = wszRespQueueBuffer;
i++;

aMsgPropId[i] = PROPID_M_RESP_FORMAT_NAME_LEN;  // Property ID
aMsgPropVar[i].vt = VT_UI4;                  // Type indicator
aMsgPropVar[i].ulVal = dwRespQueueBufferLength;
i++;

When MQReceiveMessage succeeds, first test the returned value of PROPID_M_RESP_FORMAT_NAME_LEN to see if a set of response queues was specified by the sending application. A returned value of 0 indicates that no response queues were specified. A non-0 returned value indicates that the response queue set was returned by PROPID_M_RESP_FORMAT_NAME.

If MQReceiveMessage fails, returning an MQ_ERROR_FORMATNAME_BUFFER_TOO_SMALL error, use the returned value of PROPID_M_RESP_FORMAT_NAME_LEN to reallocate the buffer, and call MQReceiveMessage again.

Equivalent COM Property

There is no equivalent COM property for this property.

See Also

MQMSGPROPS, MQReceiveMessage, PROPID_M_RESP_FORMAT_NAME, PROPID_M_RESP_QUEUE_LEN


PROPID_M_RESP_QUEUE

The PROPID_M_RESP_QUEUE property specifies the queue to which application-generated response messages are returned.

Property ID
PROPID_M_RESP_QUEUE
Type Indicator
VT_LPWSTR
MQPROPVARIANT Field
pwszVal

Property Values

Format name of the response queue (the default is none).

Remarks

PROPID_M_RESP_QUEUE is used to send the format name of a queue to the receiving application. Typically, this is done so that the receiving application can send a response message back to the sending application.

Note Response messages are application-defined. The sending and receiving application must define what is in the message, as well as what is to be done when the response message arrives in the response queue.

This property can also be used to send the format name of other queues. For example, when sending response messages you can set this property to the format name of the destination queue of the original message. Or you can use this property to send the format name of a local private queue (which would be inaccessible otherwise) to another application.

To set the format name of a response queue, specify PROPID_M_RESP_QUEUE in the MQMSGPROPS structure and call MQSendMessage.

To find out where to send a response message, specify PROPID_M_RESP_QUEUE and PROPID_M_RESP_QUEUE_LEN in the MQMSGPROPS structure (the length property is used to verify that the format name was sent). Then call MQReceiveMessage and examine the returned values.

Before using the returned format name, always check the length property PROPID_M_RESP_QUEUE_LEN to see if the format name was sent with the message. If the returned value of PROPID_M_RESP_QUEUE_LEN is 0, no format name was sent with the message. If the returned value is non-0, PROPID_M_RESP_QUEUE contains the format name of the queue.

For information on | See
The type of queues used as response queues | Response Queues
Testing to see if a response is needed | PROPID_M_RESP_QUEUE_LEN
Setting and retrieving the response queue when you are using COM components | MSMQMessage.ResponseQueueInfo

Example Code

The following examples show how PROPID_M_RESP_QUEUE is specified in the MQMSGPROPS structure for setting and retrieving the response queue format name.

To send the format name

aMsgPropId[i] = PROPID_M_RESP_QUEUE;        // Property ID
aMsgPropVar[i].vt = VT_LPWSTR;              // Type indicator
aMsgPropVar[i].pwszVal = wszRespFormatNameBuffer;
i++;

To retrieve the format name

aMsgPropId[i] = PROPID_M_RESP_QUEUE_LEN;    // Property ID
aMsgPropVar[i].vt = VT_UI4;                 // Type indicator
aMsgPropVar[i].ulVal = dwRespFormatNameBufferLength;
i++;

aMsgPropId[i] = PROPID_M_RESP_QUEUE;       // Property ID
aMsgPropVar[i].vt = VT_LPWSTR;              // Type indicator
aMsgPropVar[i].pwszVal = wszRespFormatNameBuffer;
i++;
For a complete example of | See
Setting PROPID_M_RESP_QUEUE to request a response message | Requesting Response Messages
Retrieving PROPID_M_RESP_QUEUE to send a response message | Sending Response Messages

See Also

MQMSGPROPS, MQReceiveMessage, MQSendMessage, PROPID_M_RESP_QUEUE_LEN


PROPID_M_RESP_QUEUE_LEN

The PROPID_M_RESP_QUEUE_LEN property indicates the length (in Unicode characters) of the response queue format name buffer.

Property ID
PROPID_M_RESP_QUEUE_LEN
Type Indicator
VT_UI4
MQPROPVARIANT Field
ulVal

Property Values

On input: The length of the format name buffer (in Unicode characters) allocated by the receiving application.

On return: The length (in Unicode characters) of the format name string (including the null-terminating character) returned by PROPID_M_RESP_QUEUE.

Remarks

The PROPID_M_RESP_QUEUE_LEN property is only used by the receiving application to determine if a response message is needed and to determine the format name of a response queue.

On input, PROPID_M_RESP_QUEUE_LEN should be large enough to hold the format name string including the null-terminating character.

To retrieve the format name of the response queue, set PROPID_M_RESP_QUEUE and PROPID_M_RESP_QUEUE_LEN in the MQMSGPROPS structure. Then call MQReceiveMessage and examine the returned values.

When MQReceiveMessage succeeds, first test the returned value of PROPID_M_RESP_QUEUE_LEN to see if a response queue was specified. A returned value of 0 indicates that a response queue was not specified by the sending application and no response message is needed. A non-0 return value indicates that the format name of a response queue was returned by PROPID_M_RESP_QUEUE.

If MQReceiveMessage fails, returning an MQ_ERROR_FORMATNAME_BUFFER_TOO_SMALL error, use the returned value of PROPID_M_RESP_QUEUE_LEN to reallocate the format name buffer and call MQReceiveMessage again.

This property is not needed when you are using COM components.

Example Code

The following example shows how PROPID_M_RESP_QUEUE_LEN is specified in the MQMSGPROPS structure when retrieving the format name of the response queue.

aMsgPropId[i] = PROPID_M_RESP_QUEUE_LEN;    // Property ID
aMsgPropVar[i].vt = VT_UI4;                 // Type indicator
aMsgPropVar[i].ulVal = dwRespFormatNameBufferLength;
i++;

aMsgPropId[i] = PROPID_M_RESP_QUEUE;        // Property ID
aMsgPropVar[i].vt = VT_LPWSTR;              // Type indicator
aMsgPropVar[i].pwszVal = wszRespFormatNameBuffer;
i++;
For a complete example of | See
Sending a response messages to the sending application | Sending Response Messages

See Also

MQMSGPROPS, MQReceiveMessage, PROPID_M_RESP_QUEUE


PROPID_M_SECURITY_CONTEXT

The PROPID_M_SECURITY_CONTEXT property specifies security information needed to attach a security certificate to a message.

Property ID
PROPID_M_SECURITY_CONTEXT
Type Indicator
VT_UI4
MQPROPVARIANT Field
ulVal

Property Values

Handle to the security context buffer returned by MQGetSecurityContext.

Remarks

The sending application should use PROPID_SECURITY_CONTEXT when using the same certificate to send a large number of authenticated messages. Message Queuing run-time uses the security context information specified by PROPID_SECURITY_CONTEXT to attach the certificate to the messages for you.

Security context information is stored locally, and has no meaning to the receiving application.

To obtain security context information call MQGetSecurityContext. This information includes details about the user as well as information about the user's security certificate. Security context information can be taken from an internal or external certificate.

When using security context information to attach a certificate, do not set PROPID_M_SENDER_CERT. Message Queuing run-time will attach the certificate for you. If Message Queuing run-time finds a certificate in PROPID_M_SENDER_CERT, it will discard any information in PROPID_M_SECURITY_CONTEXT

When the sending application is impersonating a user, it must use the security context of the impersonated user.

When the current security context information is no longer needed, call MQFreeSecurityContext to clear the resources used to store this information.

For information on | See
Attaching the security context using a COM method | MSMQMessage.AttachCurrentSecurityContext

See Also

MQFreeSecurityContext, MQGetSecurityContext, MQSendMessage, PROPID_M_SENDER_CERT


PROPID_M_SENDER_CERT

The PROPID_M_SENDER_CERT property specifies the security certificate used to authenticate messages.

Property ID
PROPID_M_SENDER_CERT
Type Indicator
VT_VECTOR | VT_UI1
MQPROPVARIANT Field
caub

Property Values

Security certificate (the default is the internal certificate provided by Message Queuing).

Remarks

Use PROPID_M_SENDER_CERT when you want to authenticate a small number of messages with the same certificate.

Note When sending a large number of messages using the same certificate, use security context information to attach the certificate. Security context information is obtained by calling MQGetSecurityContext.

Sending the Sender Certificate

To attach a certificate to a message, specify PROPID_M_SENDER_CERT in the MQMSGPROPS structure and call MQSendMessage. (When using an internal certificate, Message Queuing includes the internal certificate in this property and attaches the property to the message for you.)

Message Queuing uses the certificate to authenticate the message. However, the receiving application can also use the information in an external certificate to verify who sent the message. (When an internal certificate is used, the information in the certificate is not useful to the receiving application.)

Retrieving the Sender Certyificate

The receiving application should retrieve PROPID_M_SENDER_CERT only when an external certificate was sent with the message. After retrieving the certificate, use the CryptoAPI to validate the information in the certificate. (If you don't know whether an external or internal certificate was sent, retrieve the certificate and look at its locality attribute. If the locality attribute was set by Message Queuing, then the certificate is an Message Queuing internal certificate.)

To retrieve the sender certificate, specify PROPID_M_SENDER_CERT and PROPID_M_SENDER_CERT_LEN in the MQMSGPROPS structure (the length property is used to verify that the sender certificate was sent). Then call MQReceiveMessage and examine the returned values.

Before using the returned sender certificate, always check the length property PROPID_M_SENDER_CERT_LEN to see if the sender certificate was sent with the message. If the returned value of PROPID_M_SENDER_CERT_LEN is 0, no certificate was sent with the message. If the returned value is non-0, PROPID_M_SENDER_CERT contains the certificate used when sending the message.

For information on | See
What it means to authenticate a message | Message Authentication
Registering internal and external certificates | Registering a Certificate
How messages are authenticated | Message Authentication
Setting and retrieving the security certificate when you are using COM components | MSMQMessage.SenderCertificate

Example Code

The following examples show how PROPID_M_SENDER_CERT is specified in the MQMSGPROPS structure for setting and retrieving the sender certificate.

To send the sender certificate

aMsgPropId[i] = PROPID_M_SENDER_CERT;       // Property ID
aMsgPropVar[i].vt = VT_VECTOR | VT_UI1;     // Type indicator
aMsgPropVar[i].caub.pElems = SenderCertificate;
aMsgPropVar[i].caub.cElems = SenderCertificateSize;
i++;

To retrieve the sender certificate

aMsgPropId[i] = PROPID_M_SENDER_CERT;       // Property ID
aMsgPropVar[i].vt = VT_VECTOR | VT_UI1;     // Type indicator
aMsgPropVar[i].caub.pElems = SenderCertificateBuffer;
aMsgPropVar[i].caub.cElems = Sizeof(SenderCertificateBuffer);
i++;
aMsgPropId[i] = PROPID_M_SENDER_CERT_LEN;   // Property ID
aMsgPropVar[i].vt = VT_UI4;                 // Type indicator
i++;

See Also

MQMSGPROPS, MQGetSecurityContext, MQReceiveMessage, MQSendMessage, PROPID_M_SENDER_CERT_LEN


PROPID_M_SENDER_CERT_LEN

The PROPID_M_SENDER_CERT_LEN property specifies the length of the sender certificate buffer.

Property ID
PROPID_M_SENDER_CERT_LEN
Type Indicator
VT_UI4 (or VT_NULL)
MQPROPVARIANT Field
ulVal

Property Values

The length (in bytes) of the sender certificate returned by PROPID_M_SENDER_CERT.

Remarks

PROPID_M_SENDER_CERT_LEN is only used by the receiving application. It is required when PROPID_M_SENDER_CERT is specified in the MQMSGPROPS structure.

To retrieve the sender certificate from a message, specify PROPID_M_SENDER_CERT and PROPID_M_SENDER_CERT_LEN in the MQMSGPROPS structure. Then call MQReceiveMessage and examine the returned values.

When MQReceiveMessage succeeds, first test the returned value of PROPID_M_SENDER_CERT_LEN to see if a sender certificate exists. A returned value of 0 indicates that a sender certificate was not included in the message. A non-0 return value indicates that a sender certificate was returned by PROPID_M_SENDER_CERT.

If MQReceiveMessage fails, returning an MQ_ERROR_SENDER_CERT_BUFFER_TOO_SMALL error, use the returned value of PROPID_M_SENDER_CERT_LEN to reallocate the sender certificate buffer and call MQReceiveMessage again.

This property is not needed when you are using COM components.

Example Code

The following example shows how PROPID_M_SENDER_CERT_LEN is specified in the MQMSGPROPS structure when retrieving the sender certificate.

aMsgPropId[i] = PROPID_M_SENDER_CERT;       // Property ID
aMsgPropVar[i].vt = VT_VECTOR | VT_UI1;     // Type indicator
aMsgPropVar[i].caub.pElems = SenderCertificateBuffer;
aMsgPropVar[i].caub.cElems = Sizeof(SenderCertificateBuffer);
i++;
aMsgPropId[i] = PROPID_M_SENDER_CERT_LEN;   // Property ID
aMsgPropVar[i].vt = VT_UI4;                 // Type indicator
i++;

See Also

MQMSGPROPS, MQReceiveMessage, PROPID_M_SENDER_CERT


PROPID_M_SENDERID

The PROPID_M_SENDERID property identifies who sent the message.

Property ID
PROPID_M_SENDERID
Type Indicator
VT_VECTOR | VT_UI1
MQPROPVARIANT Field
caub

Property Values

An array of bytes generated by Message Queuing.

Remarks

PROPID_M_SENDERID is set by Message Queuing, and is used primarily by the receiving queue manager when authenticating a message. The receiving queue manager uses the sender identifier in this property to verify who sent the message and to verify that the sender has access rights to a queue.

By default, Message Queuing sets this property when a message is sent. However, Message Queuing will not attach the sender identifier to the message if the sending application has set PROPID_M_SENDERID_TYPE to MQMSG_SENDERID_TYPE_NONE. By setting this property to MQMSG_SENDERID_TYPE_NONE, the sending application tells Message Queuing not to validate who sent the message.

The only time the sending application can set this property is if it is sending messages to a foreign queue. An error is returned if this property is set without the connector property (PROPID_M_CONNECTOR_TYPE) set as well.

The receiving application may use PROPID_M_SENDERID to retrieve the SID of the user who sent the message. However, the information in PROPID_M_SENDERID is only trustworthy if the message was authenticated.

To retrieve the sender identifier from a message, specify PROPID_M_SENDERID and PROPID_M_SENDERID_LEN in the MQMSGPROPS structure (the length property is used to verify that the sender identifier was sent with the message). Then call MQReceiveMessage and examine the returned values.

Before using the sender identifier, always check the length property PROPID_M_SENDERID_LEN to see if the sender identifier was sent with the message. If the returned value of PROPID_M_SENDERID_LEN is 0, no identifier was sent with the message. If the returned value is non-0, PROPID_M_SENDERID contains the identifier of the sender.

For information on | See
What it means to authenticate a message: message integrity and sender authentication | Message Authentication
The process used to authenticate a messages | How Message Queuing Authenticates Messages
Retrieving the sender identifier when you are using COM components | MSMQMessage.SenderId

Example Code

The following example shows how PROPID_M_SENDERID and PROPID_M_SENDERID_LEN are specified in the MQMSGPROPS structure when retrieving the sender identifier.

aMsgPropId[i] = PROPID_M_SENDERID_LEN;      // Property ID
aMsgPropVar[i].vt = VT_UI4;                 // Type indicator
i++;

aMsgPropId[i] = PROPID_M_SENDERID;          // Property ID
aMsgPropVar[i].vt = VT_VECTOR|VT_UI1;       // Type indicator
aMsgPropVar[i].caub.pElems = SenderIdentifierBuffer;
aMsgPropVar[i].caub.cElems = sizeof(SenderIdentifierBuffer);
i++;
For a complete example of | See
Checking to see if a message was authenticated | Validating Authenticated Messages

See Also

MQMSGPROPS, MQReceiveMessage, PROPID_M_SENDERID_LEN, PROPID_M_SENDERID_TYPE


PROPID_M_SENDERID_LEN

The PROPID_M_SENDERID_LEN property indicates the length of the sender identifier.

Property ID
PROPID_M_SENDERID_LEN
Type Indicator
VT_UI4 (or VT_NULL)
MQPROPVARIANT Field
ulVal

Property Values

Length (in bytes) of the sender identifier.

Remarks

PROPID_M_SENDERID_LEN is used only by the receiving application when calling MQReceiveMessage. Message Queuing attaches this property to the message when it attaches PROPID_M_SENDERID.

To retrieve the sender identifier from a message, set PROPID_M_SENDERID_LEN and PROPID_M_SENDERID in the MQMSGPROPS structure. Then call MQReceiveMessage and examine the returned values.

When MQReceiveMessage succeeds, first test the returned value of PROPID_M_SENDERID_LEN to see if a sender identifier exists. A returned value of 0 indicates that a sender identifier was not included in the message. A non-0 return value indicates that a sender identifier was returned by PROPID_M_SENDERID.

If MQReceiveMessage fails, returning an MQ_ERROR_SENDERID_BUFFER_TOO_SMALL error, use the returned value of PROPID_M_SENDERID_LEN to reallocate the sender identifier buffer and call MQReceiveMessage again.

This property is not needed when you are using COM components.

Example Code

The following example shows how PROPID_M_SENDERID_LEN and PROPID_M_SENDERID are specified in the MQMSGPROPS structure when retrieving the sender identifier.

aMsgPropId[i] = PROPID_M_SENDERID_LEN;      // Property ID
aMsgPropVar[i].vt = VT_UI4;                 // Type indicator
i++;

aMsgPropId[i] = PROPID_M_SENDERID;          // Property ID
aMsgPropVar[i].vt = VT_VECTOR|VT_UI1;       // Type indicator
aMsgPropVar[i].caub.pElems = SenderIdentifierBuffer;
aMsgPropVar[i].caub.cElems = sizeof(SenderIdentifierBuffer);
i++;
For a complete example of | See
Retrieving the sender identifier from authenticated messages | Validating Authenticated Messages

See Also

MQMSGPROPS, MQReceiveMessage, PROPID_M_SENDERID, PROPID_M_SENDERID_TYPE


PROPID_M_SENDERID_TYPE

The PROPID_M_SENDERID_TYPE property specifies the type of sender identifier found in PROPID_M_SENDERID. It can also be used to tell Message Queuing to not attach the sender identifier to a message when the message is sent.

Property ID
PROPID_M_SENDERID_TYPE
Type Indicator
VT_UI4 (or VT_NULL)
MQPROPVARIANT Field
ulVal

Property Values

This property can have one of the following values:

MQMSG_SENDERID_TYPE_SID
The default. PROPID_M_SENDERID contains the security identifier (SID) of the user sending the message.
MQMSG_SENDERID_TYPE_NONE
No identifier is attached to the message.

Remarks

To specify the type of sender identifier you want to send with the message, set PROPID_M_SENDERID_TYPE in the MQMSGPROPS structure and call MQSendMessage.

The sending application can tell Message Queuing not to authenticate who sent a message by specifying MQMSG_SENDERID_TYPE_NONE when it sends the message. This setting tells Message Queuing to not attach the SID to PROPID_M_SENDERID. However, if the sender identifier is not sent with the message, the destination queue must be able to accept messages from everyone.

To find out what type of sender identifier was sent with the message, set PROPID_M_SENDERID_TYPE in the MQMSGPROPS structure. Then call MQReceiveMessage and examine the returned value. (When specifying PROPID_M_SENDERID_TYPE, you can set its Type Indicator to VT_NULL. When the Type Indicator is set to VT_NULL, Message Queuing sets the VT field to the appropriate type indicator.)

An SID of a local user (a user not logged in to a Microsoft Windows 2000 domain) is valid only locally. Even if a local user specifies an SID, it is not sent with the message.

For information on | See
Setting and retrieving the sender identifier type when you are using COM components | MSMQMessage.SenderIdType

Example Code

The following example shows how PROPID_M_SENDERID_TYPE is specified in the MQMSGPROPS structure.

aMsgPropId[i] = PROPID_M_SENDERID_TYPE;     // Property ID
aMsgPropVar[i].vt = VT_UI4;                 // Type indicator
aMsgPropVar[i].ulVal;
i++;
For a complete example of | See
Retrieving the sender identifier from authenticated messages | Validating Authenticated Messages

See Also

MQReceiveMessage, MQSendMessage, PROPID_M_SENDERID, PROPID_M_SENDERID_LEN


PROPID_M_SENTTIME

The PROPID_M_SENTTIME property indicates the date and time that the message was sent by the source queue manager.

Property ID
PROPID_M_SENTTIME
Type Indicator
VT_UI4 (or VT_NULL)
MQPROPVARIANT Field
ulVal

Remarks

The PROPID_M_SENTTIME property is attached to the message by Message Queuing. The time returned is the number of seconds elapsed since midnight (00:00:00), January 1, 1970 (Coordinated Universal time) according to the system clock.

To see when a message was sent, specify PROPID_M_SENTTIME in the MQMSGPROPS structure. Then call MQReceiveMessage and examine the returned value. (When specifying PROPID_M_SENTTIME, you can set its Type Indicator to VT_NULL. When the Type Indicator is set to VT_NULL, Message Queuing sets the VT field to the appropriate type indicator.)

Microsoft provides several time functions that can be used to manipulate the returned Coordinated Universal time value. These functions are defined in the time.h header file.

For information on | See
Retrieving the sent time when you are using COM components | MSMQMessage.SentTime

Example Code

The following example shows how PROPID_M_SENTTIME is specified in the MQMSGPROPS structure.

aMsgPropId[i] = PROPID_M_SENTTIME;           // Property ID
aMsgPropVar[i].vt = VT_UI4;                  // Type indicator
aMsgPropVar[i].ulVal = dwSentTime;        // Value
i++;
For a complete example of | See
Filtering messages based on the time they were sent to the queue | Sent Time Filter

See Also

MQReceiveMessage, PROPID_M_ARRIVEDTIME


PROPID_M_SIGNATURE

The PROPID_M_SIGNATURE property specifies the MSMQ 1.0 signature used to authenticate the message.

Property ID
PROPID_M_SIGNATURE
Type Indicator
VT_UI1 | VT_VECTOR
MQPROPVARIANT Field
caub

Property Values

Digital signature.

Remarks

In most cases, this property is set by the Message Queuing run time when the sending application requests authentication (this property can also be set by connector applications sending messages to Message Queuing). In these cases, only the receiving application will use this property to retrieve the MSMQ 1.0 signature attached to the message.

Note that the sending application must specify MSMQ 1.0 signatures when requesting authentication.

Connector applications may also set this property when they call MQSendMessage. However, when a connector application sets this property Message Queuing does not generate the digital signature. The connector application must generate the digital signature itself based on the certificate of the user sending the message.

To set the digital signature, the connector application must specify PROPID_M_SIGNATURE and PROPID_M_SIGNATURE_LEN in the MQMSGPROPS structure and call MQSendMessage.

To retrieve the digital signature, specify PROPID_M_SIGNATURE and PROPID_M_SIGNATURE_LEN in the MQMSGPROPS structure. Then call MQReceiveMessage and examine the returned value.

Before using the retrieved digital signature, always check the length property PROPID_M_SIGNATURE_LEN to see if the digital signature was sent with the message. If the returned value of PROPID_M_SIGNATURE_LEN is 0, no signature was sent with the message. If the returned value is non-0, PROPID_M_SIGNATURE contains the digital signature.

Note If the sending application sent an MSMQ 2.0 signature, this property will contain a buffer of 4 zeroed bytes.

For information on | See
How Message Queuing creates digital signatures | How Message Queuing Authenticates Messages
MSMQ 1.0 signatures | Digital Signatures
Authenticating messages sent by a connector application | Connector Application Security
Setting or retrieving the digital signature when you are using COM components | MSMQMessage.Signature

Example Code

The following example shows how PROPID_M_SIGNATURE is specified in the MQMSGPROPS structure for setting and retrieving the digital signature.

aMsgPropId[i] = PROPID_M_SIGNATURE;         // Property ID
aMsgPropVar[i].vt = VT_UI1 | VT_VECTOR;     // Type indicator
aMsgPropVar[i].caub.pElems = Signature;
aMsgPropVar[i].caub.cElems = sizeof(Signature);
i++;

aMsgPropId[i] = PROPID_M_SIGNATURE_LEN;     // Property ID
aMsgPropVar[i].vt = VT_UI4;                 // Type indicator
aMsgPropVar[i].ulVal = SignatureLength;
i++;

See Also

MQMSGPROPS, MQReceiveMessage, MQSendMessage, MSMQMessage.Signature, PROPID_M_SIGNATURE_LEN


PROPID_M_SIGNATURE_LEN

The PROPID_M_SIGNATURE_LEN property indicates the length of the digital signature used to authenticate the message.

Property ID
PROPID_M_SIGNATURE_LEN
Type Indicator
VT_UI4 (or VT_NULL)
MQPROPVARIANT Field
ulVal

Property Values

Length (in bytes) of the digital signature.

Remarks

PROPID_M_SIGNATURE_LEN is used when retrieving the digital signature of a message, or by connector applications when they attach a digital signature to a message.

To set the digital signature length, the connector application must specify PROPID_M_SIGNATURE and PROPID_M_SIGNATURE_LEN in the MQMSGPROPS structure and call MQSendMessage.

To retrieve the digital signature, specify PROPID_M_SIGNATURE and PROPID_M_SIGNATURE_LEN in the MQMSGPROPS structure. Then call MQReceiveMessage and examine the returned value. (When specifying PROPID_M_SIGNATURE_LEN, you can set its Type Indicator to VT_NULL. When the Type Indicator is set to VT_NULL, Message Queuing sets the VT field to the appropriate type indicator.)

This property is not needed when you are using COM components.

Example Code

The following example shows how PROPID_M_SIGNATURE_LEN is specified in the MQMSGPROPS structure for setting and retrieving the digital signature.

aMsgPropId[i] = PROPID_M_SIGNATURE;         // Property ID
aMsgPropVar[i].vt = VT_UI1 | VT_VECTOR;     // Type indicator
aMsgPropVar[i].caub.pElems = Signature;
aMsgPropVar[i].caub.cElems = sizeof(Signature);
i++;

aMsgPropId[i] = PROPID_M_SIGNATURE_LEN;     // Property ID
aMsgPropVar[i].vt = VT_UI4;                 // Type indicator
aMsgPropVar[i].ulVal = SignatureLength;
i++;

See Also

MQReceiveMessage, PROPID_M_SIGNATURE


PROPID_M_SRC_MACHINE_ID

(Read-only) The PROPID_M_SRC_MACHINE_ID property provides the identifier of the computer that sent the message.

Property ID
PROPID_M_SRC_MACHINE_ID
Type Indicator
VT_CLSID
MQPROPVARIANT Field
*puuid

Property Values

Machine identifier (GUID) of source machine.

Remarks

The PROPID_M_SRC_MACHINE_ID property is used only by the receiving application when calling MQReceiveMessage.

This property returns the GUID of the computer without the enclosing brackets {}.

To retrieve the identifier of the source computer, include PROPID_M_SRC_MACHINE_ID in the MQMSGPROPS structure, then call MQReceiveMessage and examine the returned value.

Equivalent COM Property

When using COM components, you can retrieve the source computer identifier by using MSMQMessage.SourceMachineGuid.

See Also

MQMSGPROPS, MQReceiveMessage, MSMQMessage.SourceMachineGuid


PROPID_M_SOAP_ENVELOPE

(Introduced in Whistler.) The PROPID_M_SOAP_ENVELOPE property provides the SOAP envelope (not including binary attachments) attached to the message.

Property ID
PROPID_M_SOAP_ENVELOPE
Type Indicator
VT_VECTOR | VT_UI1
MQPROPVARIANT Field
caub

Property Values

SOAP envelope.

Remarks

The PROPID_M_SOAP_ENVELOPE property is a read-only property that is only used when an application retrieves HTTP messages. When an HTTP message is sent, the sending queue manager attaches the SOAP envelope, along with any SOAP attachments, to the message.

To retrieve SOAP attachments, see PROPID_M_COMPOUND_MESSAGE.

Equivalent COM Property

When using COM components, you can retrieve the SOAP envelope using MSMQMessage.SOAPEnvelope.

Example Code

The following examples show how PROPID_M_SOAP_ENVELOPE is specified in the MQMSGPROPS structure for retrieving the SOAP envelope.

MsgProps.aPropID[i] = PROPID_M_SOAP_ENVELOPE_SIZE;
MsgProps.aPropVar[i].vt = VT_UI4;
i++;
MsgProps.aPropID[i] = PROPID_M_SOAP_ENVELOPE;
MsgProps.aPropVar[i].vt = VT_VECTOR|VT_UI1;
MsgProps.aPropVar[i].caub.pElems = ???????????;
MsgProps.aPropVar[i].caub.cElems = ????????????;
i++;

See Also

MQMSGPROPS, PROPID_M_COMPOUND_MESSAGE, PROPID_M_SOAP_ENVELOPE_SIZE


PROPID_M_SOAP_ENVELOPE_SIZE

(Introduced in Whistler.) The PROPID_M_SOAP_ENVELOPE_SIZE property provides the size of the SOAP envelope associated with the message.

Property ID
PROPID_M_SOAP_ENVELOPE_SIZE
Type Indicator
VT_UI4 (or VT_NULL)
MQPROPVARIANT Field
ulVal

Property Values

The size (in bytes) of the of the SOAP envelope provided by PROPID_M_SOAP_ENVELOPE.

Remarks

The PROPID_M_SOAP_ENVELOPE_SIZE property is a read-only property that is only used when an application retrieves the SOAP envelope.

To retrieve the SOAP envelope, see PROPID_M_SOAP_ENVELOPE.

Equivalent COM Property

There is no COM equivalent for this property.

Example Code

The following examples show how PROPID_M_SOAP_ENVELOPE_SIZE is specified in the MQMSGPROPS structure when retrieving the SOAP envelope.

To retrieve the SOAP envelope when retrieving messages

MsgProps.aPropID[i] = PROPID_M_SOAP_ENVELOPE_SIZE;
MsgProps.aPropVar[i].vt = VT_UI4;
i++
MsgProps.aPropID[i] = PROPID_M_SOAP_ENVELOPE;
MsgProps.aPropVar[i].vt = VT_VECTOR|VT_UI1;
MsgProps.aPropVar[i].caub.pElems = ???????;
MsgProps.aPropVar[i].caub.cElems = ???????;
i++;

See Also

MQMSGPROPS, PROPID_M_SOAP_ENVELOPE


PROPID_M_TIME_TO_BE_RECEIVED

The PROPID_M_TIME_TO_BE_RECEIVED property specifies the total time (in seconds) the message is allowed to live. This includes the time it spends getting to the destination queue plus the time spent waiting in the queue before it is retrieved by an application.

Property ID
PROPID_M_TIME_TO_BE_RECEIVED
Type Indicator
VT_UI4 (or VT_NULL)
MQPROPVARIANT Field
ulVal

Property Values

Integer value (the default is INFINITE).

Remarks

PROPID_M_TIME_TO_BE_RECEIVED sets the time-to-be-received timer. If the timer expires before the message is removed from the queue, Message Queuing discards the message, sending it to the dead-letter queue if the PROPID_M_JOURNAL property of the message is set to MQMSG_DEADLETTER.

Message Queuing can also send a return negative acknowledgment message back to the sending application if the message is not removed in time and the PROPID_M_ACKNOWLEDGE property of the message is set accordingly.

To set the time-to-be-received timer, specify PROPID_M_TIME_TO_BE_RECEIVED in the MQMSGPROPS structure and call MQSendMessage.

To find out how much time remains in the time-to-be-received timer, specify PROPID_M_TIME_TO_BE_RECEIVED in the MQMSGPROPS structure. Then call MQReceiveMessage and examine the returned value.(When specifying PROPID_M_TIME_TO_BE_RECEIVED, you can set its Type Indicator to VT_NULL. When the Type Indicator is set to VT_NULL, Message Queuing sets the VT field to the appropriate type indicator.)

If the time-to-be-received and time-to-reach-queue timers are both specified, the time-to-be-received timer takes precedence over the time-to-reach-queue timer.

Message Queuing uses the time-to-be-received timer of the first message when several messages are sent in a transaction.

When Message Queuing creates an acknowledgment message, it always sets the time-to-be-received timer of the message to INFINITE.

When a message is sent from an independent client computer, the time-to-be-received timer starts ticking as soon as the send operation succeeds, even if the client computer is offline.

When using dependent client computers, make sure the clock on the client computer is in sync with the clock on the server running Message Queuing. If these two clocks are not synchronized, you may see unpredictable behavior when sending messages with the time-to-be-received timer set.

For information on | See
Message timers | Message Timers
Transactions | Message Queuing Transactions
Setting and retrieving the time-to-be-received timer usinng COM components | MSMQMessage.MaxTimeToReceive

Example Code

The following examples show how PROPID_M_TIME_TO_BE_RECEIVED is specified in the MQMSGPROPS structure for setting and retrieving the time-to-be-received timer. Note that the timer is set to expire in 3 minutes.

To set the time-to-be-received timer

aMsgPropId[i] = PROPID_M_TIME_TO_BE_RECEIVED;
aMsgPropVar[i].vt = VT_UI4;
aMsgPropVar[i].ulVal = 60*3;
i++;

To retrieve the time-to-be-received timer

aMsgPropId[i] = PROPID_M_TIME_TO_BE_RECEIVED;
aMsgPropVar[i].vt = VT_UI4;
i++;

See Also

MQMSGPROPS, MQReceiveMessage, MQSendMessage, PROPID_M_ACKNOWLEDGE, PROPID_M_JOURNAL, PROPID_M_TIME_TO_REACH_QUEUE


PROPID_M_TIME_TO_REACH_QUEUE

The PROPID_M_TIME_TO_REACH_QUEUE property specifies a time limit (in seconds) for the message to reach the queue.

Property ID
PROPID_M_TIME_TO_REACH_QUEUE
Type Indicator
VT_UI4
MQPROPVARIANT Field
ulVal

Property Values

Integer value (the default is LONG_LIVED).

Remarks

PROPID_M_TIME_TO_REACH_QUEUE sets the time-to-reach-queue timer of the message. If the time-to-reach-queue timer expires before the message reaches its destination, Message Queuing discards the message, sending it to the dead-letter queue if the PROPID_M_JOURNAL property of the message is set to MQMSG_DEADLETTER.

Message Queuing can also send a return negative acknowledgment message back to the sending application if the message does not arrive and the PROPID_M_ACKNOWLEDGE property of the message is set accordingly.

To set the time-to-reach-queue timer, specify PROPID_M_TIME_TO_REACH_QUEUE in the MQMSGPROPS structure and call MQSendMessage.

The default value LONG_LIVED is an enterprise-wide setting that can be adjusted by the Message Queuing administrator. Typically, LONG_LIVED is set to 90 days. Although this timer can be set to INFINITE, Message Queuing automatically uses the LONG_LIVED value in its place.

To find out how much time remains in the time-to-reach-queue timer, specify PROPID_M_TIME_TO_REACH_QUEUE in the MQMSGPROPS structure. Then call MQReceiveMessage and examine the returned value. A value of 0 indicates the timer has expired.

If the time-to-be-received and time-to-reach-queue timers are both specified, the time-to-be-received timer takes precedence over the time-to-reach-queue timer.

No matter what value PROPID_M_TIME_TO_REACH_QUEUE is set to (even if set to 0), Message Queuing always gives each message one chance to reach its destination if the queue is waiting for the message. If the queue is local, the message always reaches the queue.

Message Queuing uses the time-to-reach-queue timer of the first message when several messages are sent in a transaction. For information on transactions, see Message Queuing Transactions.

When Message Queuing creates an acknowledgment message, it always sets the time-to-reach-queue timer of the message to LONG_LIVED.

When a message is sent from an independent client computer, the time-to-reach-queue timer starts ticking as soon as the send operation succeeds, even if the client computer is currently offline.

For information on | See
Message timers | Message Timers
Transactions | Message Queuing Transactions
Setting and retrieving the time-to-reach-queue timer when you are using COM components | MSMQMessage.MaxTimeToReachQueue

See Also

MQMSGPROPS, MQReceiveMessage, MQSendMessage, PROPID_M_ACKNOWLEDGE, PROPID_M_JOURNAL, PROPID_M_TIME_TO_BE_RECEIVED


PROPID_M_TRACE

The PROPID_M_TRACE property specifies how Message Queuing traces the route of the message.

Property ID
PROPID_M_TRACE
Type Indicator
VT_UI1 (or VT_NULL)
MQPROPVARIANT Field
bVal

Property Values

This property can be set to one of the following values:

MQMSG_SEND_ROUTE_TO_REPORT_QUEUE
Tracing is requested. Each hop made by the original message generates a report message that is sent to a report queue.
MQMSG_TRACE_NONE
The default. Tracing is not requested.

Remarks

When tracing is enabled and a report queue is specified, report messages are created and sent to the report queue each time the message leaves or arrives at a Message Queuing computer. For example, report messages are generated at the following time.

  • When the message leaves the source computer one report message is generated.
  • When the message arrives at and leaves a routing server two report messages are generated.
  • When the message arrives the target computer where the destination queue resides one report message is generated.

Report queues are specified by the computer. If MQMSG_SEND_ROUTE_TO_REPORT_QUEUE is specified but the report queue is not specified, this property is ignored.

Note Message Queuing does not support tracing under the following conditions.

  • When you send messages to multiple destinations using distribution lists, multicast addresses, and multiple-element format names.
  • When you send HTTP messages.

Equivalent COM Property

When using COM components, you can set the tracing level of the message using the MSMQMessage.Trace property.

Example Code

The following example code shows how to specify PROPID_Q_TRACE in the MQMSGPROPS structure.

To set the tracing level of a message, specify PROPID_M_TRACE in the MQMSGPROPS structure.

aMsgPropId[i] = PROPID_M_TRACE;
aMsgPropVar[i].vt = VT_UI1;
aMsgPropVar[i].bVal = MQMSG_SEND_ROUTE_TO_REPORT_QUEUE;
i++;

To retrieve the tracing level of a message, specify PROPID_M_TRACE in the MQMSGPROPS structure. Then call MQReceiveMessage and examine the returned value. (When retrieving PROPID_M_TRACE, you can set its Type Indicator to VT_NULL. When the Type Indicator is set to VT_NULL, Message Queuing sets the VT field to the appropriate type indicator.)

The following example code shows how PROPID_M_TRACE is added to the MQMSGPROPS structure to retrieve the tracing level.

aMsgPropId[i] = PROPID_M_TRACE;
aMsgPropVar[i].vt = VT_UI1;
i++;

See Also

MQReceiveMessage


PROPID_M_VERSION

This property is reserved for future use.


PROPID_M_XACTID

(Read-only. MSMQ 2.0 only.) The PROPID_M_XACTID property indicates which transaction sent the message.

Property ID
PROPID_M_XACTID
Type Indicator
VT_VECTOR | VT_UI1
MQPROPVARIANT Field
caub

Property Values

Identifier of the transaction. See Remarks for a description of a transaction identifier.

Remarks

This property is available for MSMQ 2.0 and later. It is used by receiving applications to verify that a message was sent from a specific transaction. The transaction identifier is a 20-byte identifier that includes the computer identifier of the sending machine (first 16 bits) followed by a transaction sequence number (4 bytes).

Transaction identifiers are not guaranteed to be unique because the transaction sequence numbers are not persistent and they start over again at 2^20. Message Queuing guarantees only that subsequent transactions will have different transaction sequence numbers.

You can use PROPID_M_XACTID along with two other properties to verify transaction boundaries. These two properties are properties for checking the first and last message sent in a transaction: PROPID_M_FIRST_IN_XACT and PROPID_M_LAST_IN_XACT.

For information on | See
How transaction boundaries can be used | Checking for Transaction Boundaries when Receiving Messages
Checking the first message in the transaction | PROPID_M_FIRST_IN_XACT
Checking the last message in the transaction | PROPID_M_LAST_IN_XACT
Checking the transaction identifier using COM components | MSMQMessage.TransactionId

Example Code

The following example shows how PROPID_M_XACTID is specified in the MQMSGPROPS structure.

DWORD dwIdBufferSize = 1024;
UCHAR *pucIdBuffer = (UCHAR *)malloc(dwIdBufferSize);
aMsgPropId[i] = PROPID_M_XACTID;    // Property ID
aPropVar[i].vt = VT_VECTOR|VT_UI1;      // Type indicator
aPropVar[i].caub.pElems = (UCHAR*)pucIdBuffer;
aPropVar[i].caub.cElems = dwIdBufferSize;
i++;
For a complete example of | See
Checking first and last messages in a transaction | Checking Transaction Boundaries

See Also

PROPID_M_LAST_IN_XACT, PROPID_M_XACTID


PROPID_M_XACT_STATUS_QUEUE

The PROPID_M_XACT_STATUS_QUEUE property contains a format name that identifies the transaction status queue on the source computer. It is only used by connector applications when receiving transactional messages sent to a foreign queue.

Property ID
PROPID_M_XACT_STATUS_QUEUE
Type Indicator
VT_LPWSTR
MQPROPVARIANT Field
pwszVal

Property Values

Format name of transaction status queue.

Remarks

PROPID_M_XACT_STATUS_QUEUE is set by Message Queuing. Connector applications can then retrieve the format name to send positive (read receipt) or negative acknowledgment messages back to the sending application. The transaction status queue should receive these acknowledgments even if the sending application does not request other acknowledgments.

To retrieve the format name of the transaction status queue, the connector application must specify PROPID_M_XACT_STATUS_QUEUE and PROPID_M_XACT_STATUS_QUEUE_LEN in the MQMSGPROPS structure, and then call MQReceiveMessage and examine the returned values.

For information on | See
Requesting other types of acknowledgment messages | PROPID_M_ACKNOWLEDGE
Transactions and connector applications | Using the MSMQ Connector in a Transaction
Retrieving the transaction status queue when you are using COM components | MSMQMessage.TransactionStatusQueueInfo

Example Code

The following example shows how PROPID_M_XACT_STATUS_QUEUE and PROPID_M_XACT_STATUS_QUEUE_LEN are specified in the MQMSGPROPS structure when retrieving the format name of the queue.

aMsgPropId[i] = PROPID_M_XACT_STATUS_QUEUE; // Property ID
aMsgPropVar[i].vt = VT_LPWSTR;              // Type indicator
aMsgPropVar[i].pwszVal = wszStatusQueueBuffer;
i++;
aMsgPropId[i] = PROPID_M_SENDER_CERT_LEN;   // Property ID
aMsgPropVar[i].vt = VT_UI4;                 // Type indicator
aMsgPropVar[i].ulVal = dwStatusQueueLength;
i++;

See Also

MQMSGPROPS, MQReceiveMessage, MSMQMessage.TransactionStatusQueueInfo, PROPID_M_XACT_STATUS_QUEUE_LEN


PROPID_M_XACT_STATUS_QUEUE_LEN

The PROPID_M_XACT_STATUS_QUEUE_LEN property indicates the length (in Unicode characters) of the format name buffer for the transaction status queue.

Property ID
PROPID_M_XACT_STATUS_QUEUE_LEN
Type Indicator
VT_UI4
MQPROPVARIANT Field
ulVal

Property Values

On input: The length of the format name buffer (in Unicode characters) allocated by the connector application.

On return: The length (in Unicode characters) of the format name string, including the null-terminating character, returned by PROPID_M_XACT_STATUS_QUEUE.

Remarks

The PROPID_M_XACT_STATUS_QUEUE_LEN property is used only by the connector application when receiving messages sent to a foreign queue. It is required whenever PROPID_M_XACT_STATUS_QUEUE is passed in MQReceiveMessage.

To retrieve the format name of the status queue, specify PROPID_M_XACT_STATUS_QUEUE_LEN and PROPID_M_XACT_STATUS_QUEUE in the MQMSGPROPS structure. Then call MQReceiveMessage and examine the returned values.

If MQReceiveMessage fails, returning an MQ_ERROR_FORMATNAME_BUFFER_TOO_SMALL error, use the returned value of PROPID_M_XACT_STATUS_QUEUE_LEN to reallocate the format name buffer and call MQReceiveMessage again.

This property is not needed when you are using COM components.

Example Code

The following example shows how PROPID_M_XACT_STATUS_QUEUE_LEN and PROPID_M_XACT_STATUS_QUEUE are specified in the MQMSGPROPS structure when retrieving the format name of the queue.

aMsgPropId[i] = PROPID_M_XACT_STATUS_QUEUE; // Property ID
aMsgPropVar[i].vt = VT_LPWSTR;              // Type indicator
aMsgPropVar[i].pwszVal = wszStatusQueueBuffer;
i++;
aMsgPropId[i] = PROPID_M_SENDER_CERT_LEN;   // Property ID
aMsgPropVar[i].vt = VT_UI4;                 // Type indicator
aMsgPropVar[i].ulVal = dwStatusQueueLength;
i++;

See Also

MQMSGPROPS, MQReceiveMessage, PROPID_M_XACT_STATUS_QUEUE


PROPID_PC_DS_ENABLED

The PROPID_PC_DS_ENABLED property indicates whether Message Queuing is using the directory service on the computer.

Property ID
PROPID_PC_DS_ENABLED
Type Indicator
VT_BOOL (or VT_NULL)
MQPROPVARIANT Field
boolVal

Remarks

The value returned is a calculated value. Message Queuing does not access the directory service to get this information.

For information on | See
Determining if Message Queuing is using the directory service using COM components | MSMQApplication.IsDSEnabled

Example Code

The following example shows how PROPID_PC_DS_ENABLED is specified in the MQPRIVATEPROPS structure.

aQMPropId[i] = PROPID_PC_DS_ENABLED;   // Property ID
aQMPropVar[i].vt = VT_BOOL;            // Type indicator
i++;
For a complete example of | See
Checking the directory service – enabled property | Verifying Workgroup Installation

See Also

MQGetPrivateComputerInformation, MQPRIVATEPROPS


PROPID_PC_VERSION

The PROPID_PC_VERSION property specifies the version of Message Queuing running on the computer.

Property ID
PROPID_PC_VERSION
Type Indicator
VT_UI4 (or VT_NULL)
MQPROPVARIANT Field
ulVal

Remarks

The returned version is composed of the build number, the major version number, and the minor version number of Message Queuing. The format for these three numbers is as follows.

word-byte-byte    // build number, major version, minor version

The value returned is a calculated value. Message Queuing does not access the directory service to get this information.

Example Code

The following example shows how PROPID_PC_VERSION is specified in the MQPRIVATEPROPS structure.

DWORD dwMSMQVersion;
aQMPropId[i] = PROPID_PC_VERSION;   // Property ID
aQMPropVar[i].vt = VT_UI4;          // Type indicator
i++;
For information on | See
Retrieving the build number of Message Queuing when you are using COM components | MSMQApplication.MSMQVersionBuild
Retrieving the major version number of Message Queuing when you are using COM components | MSMQApplication.MSMQVersionMajor
Retrieving the minor version number of Message Queuing when you are using COM components | MSMQApplication.MSMQVersionMinor

See Also

MQGetPrivateComputerInformation, MQPRIVATEPROPS


PROPID_Q_AUTHENTICATE

Optional. The PROPID_Q_AUTHENTICATE property specifies whether or not the queue accepts only authenticated messages.

Property ID
PROPID_Q_AUTHENTICATE
Type Indicator
VT_UI1
MQPROPVARIANT Field
bVal

Property Values

This property can be set to one of the following values:

MQ_AUTHENTICATE_NONE
The default. The queue accepts authenticated and non-authenticated messages.
MQ_AUTHENTICATE
The queue only accepts authenticated messages.

Remarks

PROPID_Q_AUTHENTICATE is used to enforce authentication at the level of the queue. When this property is set to MQ_AUTHENTICVATE, messages are rejected by the queue if the sending application did not request authentication. For information on how Message Queuing authenticates messages, see Message Authentication

Note The authentication level of a message, on the other hand, is set by PROPID_M_AUTH_LEVEL.

When a message is rejected the message packet is destroyed However, if the sending application has requested negative acknowledgment messages an acknowledgment message with the message class MQMSG_CLASS_NACK_BAD_SIGNATURE is returned to the sending application to indicate the message was rejected by the queue. For information on negative acknowledgments, see Acknowledgment Messages.

To set the authentication level when creating a queue, specify PROPID_Q_AUTHENTICATE in the MQQUEUEPROPS structure and call MQCreateQueue.

To set the authentication level of an existing queue, specify PROPID_Q_AUTHENTICATE in the MQQUEUEPROPS structure and call MQSetQueueProperties. When changing the authentication level of the queue, the new setting impacts only arriving messages; it does not affect messages already in the queue.

To retrieve the authentication level of an existing queue, specify PROPID_Q_AUTHENTICATE in the MQQUEUEPROPS structure, and then call MQGetQueueProperties and examine its returned value.

The receiving application can also determine if a message was authenticated by checking the PROPID_M_AUTHENTICATED property of the message.

Equivalent COM Component

When using COM components, the authentication level of the queue can be set and retrieved using the MSMQQueueInfo.Authenticate property.

Example Code

The following examples show how PROPID_Q_AUTHENTICATE is specified in the MQQUEUEPROPS structure for setting and retrieving the authentication level of a queue.

To set the authentication level

aPropID[i] = PROPID_Q_AUTHENTICATE;   // Property identifier
aVariant[i].vt = VT_UI1;              // Type indicator
aVariant[i].bVal = MQ_AUTHENTICATE;   // Authentication level of queue
i++;

To retrieve the authentication level

aPropID[i] = PROPID_Q_AUTHENTICATE;   // Property identifier
aVariant[i].vt = VT_UI1;              // Type indicator
i++;

See Also

MQCreateQueue, MQGetQueueProperties, MQQUEUEPROPS, MQSetQueueProperties, PROPID_M_AUTH_LEVEL, PROPID_M_AUTHENTICATED


PROPID_Q_BASEPRIORITY

Optional. The PROPID_Q_BASEPRIORITY property specifies a single base priority for all messages sent to a public queue.

Property ID
PROPID_Q_BASEPRIORITY
Type Indicator
VT_I2
MQPROPVARIANT Field
iVal

Property Values

Integer value between -32768 and +32767 (the default is 0).

Remarks

The base priority of a public queue is used for routing its messages over the network. It can be used to give the messages sent to the queue a higher (or lower) priority than messages sent to other queues. For example, when the base priority of a queue is set, all the messages sent to the queue are given a higher priority than messages sent to queues with a lower base priority. The base priority of the queue has no effect on the order of the messages in the queue or how messages are read from the queue.

PROPID_Q_BASEPRIORITY applies only to public queues that can be located through the directory service (using a public format name). The base priority of private queues, as well as public queues accessed directly, is always 0.

Message Queuing combines the base priority of the queue with the priority of the message (PROPID_M_PRIORITY) to determine the overall priority of a message when it is sent to the queue.

To set the initial base priority of a public queue, specify PROPID_Q_BASEPRIORITY in the MQQUEUEPROPS structure and call MQCreateQueue.

To change the base priority of a public queue, specify PROPID_Q_BASEPRIORITY in the MQQUEUEPROPS structure and call MQSetQueueProperties.

To retrieve the base priority of a queue, specify PROPID_Q_BASEPRIORITY in the MQUEUEPROPS structure and call MQGetQueueProperties and examine its returned value.

Equivalent COM Component

When using COM components, the priority level of the queue can be set and retrieved using the MSMQQueueInfo.BasePriority property.

Example Code

The following examples show how PROPID_Q_BASEPRIORITY is specified in the MQQUEUEPROPS structure for setting and retrieving the priority level of a queue.

To set the priority level

aPropID[I] = PROPID_Q_BASEPRIORITY;    // Property identifier
aVariant[I].vt = VT_I2;                // Type indicator
aVariant[I].iVal = 1000;               // Priority level of queue
I++;

To retrieve the priority level

aPropID[I] = PROPID_Q_BASEPRIORITY;   // Property identifier
aVariant[I].vt = VT_I2;               // Type indicator
i++;

See Also

MQCreateQueue, MQGetQueueProperties, MQQUEUEPROPS, MQSetQueueProperties, PROPID_M_PRIORITY


PROPID_Q_CREATE_TIME

Optional read-only. The PROPID_Q_CREATE_TIME property indicates the time and date when the queue was created.

Property ID
PROPID_Q_CREATE_TIME
Type Indicator
VT_I4
MQPROPVARIANT Field
lVal

Property Values

Time when the queue was created.

Remarks

This property is set by Message Queuing when MQCreateQueue is called. An error is returned (MQ_ERROR_PROPERTY_NOTALLOWED) if any attempt is made to set this property. The time returned is the number of seconds elapsed since midnight (00:00:00), January 1, 1970 (Coordinated Universal time) according to the system clock.

There are several related C run-time functions that can be used to manipulate the value of PROPID_Q_CREATE_TIME. For example, ctime() can be used to display the local date and time the queue was created.

Note Details on the C run-time functions can be found in the Platform SDK. When using these functions, include time.h in your source code.

To retrieve the date and time a queue was created, specify PROPID_Q_CREATE_TIME in the MQQUEUEPROPS structure and call MQGetQueueProperties and examine its returned value.

Equivalent COM Component

When using COM components, the time the queue was created can be retrieved using the MSMQQueueInfo.CreateTime property.

Example Code

The following example shows how PROPID_Q_CREATE_TIME is specified in the MQQUEUEPROPS structure for retrieving the date and time when the queue was created.

//To retrieve the date and time
aPropID[i] = PROPID_Q_CREATE_TIME;    // Property identifier
aVariant[i].vt = VT_I4;               // Type indicator
i++;

See Also

MQCreateQueue, MQGetQueueProperties, MQQUEUEPROPS


PROPID_Q_INSTANCE

Optional read-only. The PROPID_Q_INSTANCE property identifies a specific public queue.

Property ID
PROPID_Q_INSTANCE
Type Indicator
VT_CLSID
MQPROPVARIANT Field
*puuid

Property Values

GUID (globally unique identifier) of queue.

Remarks

The PROPID_Q_INSTANCE property identifies the created public queue. (It is not an instance of an open queue.) This property is set by Message Queuing when the application calls MQCreateQueue. An MQ_ERROR_PROPERTY_NOTALLOWED error is returned if any attempt is made to set this property.

PROPID_Q_INSTANCE only applies to public queues. An MQ_INFORMATION_PROPERTY_IGNORED error is returned if an attempt is made to get this property for a private queue.

To retrieve the identifier of a public queue, specify PROPID_Q_INSTANCE in the MQQUEUEPROPS structure and call MQGetQueueProperties (or MQLocateBegin when starting a query) and examine its returned value.

Note The returned queue identifier is a binary GUID. To convert the returned GUID to a string, use UUIDToString. When using this function, include the rpc.h header file in your source code.

Equivalent COM Component

When using COM components, the identifier of the queue can be retrieved using the MSMQQueueInfo.QueueGuid property.

Example Code

The following example shows how PROPID_Q_INSTANCE is specified in the MQQUEUEPROPS structure for retrieving the identifier of the queue. Note that a buffer of type CLSID must be declared to receive the returned GUID.

//To retrieve the queue identifier
CLSID InstanceBuffer;
aPropID[i] = PROPID_Q_INSTANCE;    // Property identifier
aVariant[i].vt = VT_CLSID;         // Type indicator
avariant[i].puuid = &InstanceBuffer
i++;

See Also

MQCreateQueue, MQGetQueueProperties, MQLocateBegin, MQQUEUEPROPS


PROPID_Q_JOURNAL

The PROPID_Q_JOURNAL property specifies how Message Queuing tracks messages removed from the queue.

Property ID
PROPID_Q_JOURNAL
Type Indicator
VT_UI1
MQPROPVARIANT Field
bVal

Property Values

This property can be set to one of the following values:

MQ_JOURNAL
Target journaling is requested. Copies of messages are stored in the journal of the queue whenever a receiving application removes a message.
MQ_JOURNAL_NONE
The default. Target journaling is not requested. Messages removed from the destination queue are no longer available.

Remarks

When PROPID_Q_JOURNAL is set to MQ_JOURNAL, Message Queuing stores a copy of each message removed from the queue in the journal of the queue. For information on tracking messages that are removed from the queue, see Target Journaling.

Queue journals are not created when target journaling is requested. Queue journals are created by Message Queueing when the destination queue is created. However, applications can set the maximum size of the queue journal using the PROPID_Q_JOURNAL_QUOTA property of the destination queue.

Processing messages in queue journals

Processing the messages in queue journals is the responsibility of the application or the Message Queuing administrator. Messages should be removed from these queues on a regular basis so that they do not consume the resources of the computer. Messages stored in queues journals count against the quota of the computer (the computer quota is set by Message Queuing administrator).

To set target journaling when creating a queue, include PROPID_Q_JOURNAL in the MQQUEUEPROPS structure and call the MQCreateQueue function.

To reset target journaling, specify PROPID_Q_JOURNAL in the MQQUEUEPROPS structure and call MQSetQueueProperties. Resetting this property has no effect on messages already removed from the queue.

The following code example shows how PROPID_Q_JOURNAL is added to the MQQUEUPROPS structure when setting or resetting the journaling level of the queue.

aPropID[i] = PROPID_Q_JOURNAL;              // Property identifier
aVariant[i].vt = VT_UI1;                    // Type indicator
aVariant[i].bVal = MQ_JOURNAL;              // Queue journal is used
i++;

To retrieve the journaling level of the queue, specify PROPID_Q_JOURNAL in the MQQUEUEPROPS structure, then call the MQGetQueueProperties function and examine its returned value.

The following code example shows how PROPID_Q_JOURNAL is added to the MQQUEUPROPS structure when setting the journaling level of the queue.

aPropID[i] = PROPID_Q_JOURNAL;              // Property identifier
aVariant[i].vt = VT_UI1;                    // Type indicator
i++;

Equivalent COM Property

When using COM components, the journaling level of the queue can be set and retrieved using the MSMQQueueInfo.Journal property.

See Also

MQCreateQueue, MQGetQueueProperties, MQQUEUEPROPS, MQSetQueueProperties, PROPID_Q_JOURNAL_QUOTA


PROPID_Q_JOURNAL_QUOTA

The PROPID_Q_JOURNAL_QUOTA property specifies the maximum size (in kilobytes) of the queue journal.

Property ID
PROPID_Q_JOURNAL_QUOTA
Type Indicator
VT_UI4
MQPROPVARIANT Field
ulVal

Property Values

Size (in kilobytes) of the queue journal (the default is INFINITE).

Remarks

PROPID_Q_JOURNAL_QUOTA is used to set the maximum size of the queue journal when target journaling is enabled. Target journaling is enabled by setting the PROPID_Q_JOURNAL property of the destination queue

To set the maximum size of a queue journal when creating the application queue, include PROPID_Q_JOURNAL_QUOTA in the MQQUEUEPROPS structure and call MQCreateQueue.

To reset the size of a queue journal, specify PROPID_Q_JOURNAL_QUOTA in the MQQUEUEUPROPS structure and call MQSetQueueProperties.

The following code example shows how PROPID_Q_JOURNAL_QUOTA is added to the MQQUEUPROPS structure when setting or resetting the journaling level of the queue.

aPropID[i] = PROPID_Q_JOURNAL_QUOTA;  // Property identifier
aVariant[i].vt = VT_UI4;              // Type indicator
aVariant[i].ulVal = 1000;             // Maximum size of queue journal
i++;

To retrieve the size of a queue journal, specify PROPID_Q_JOURNAL_QUOTA in the MQQUEUEPROPS structure and call MQGetQueueProperties and examine its returned value.

The following code example shows how PROPID_Q_JOURNAL_QUOTA is added to the MQQUEUPROPS structure when setting the journaling level of the queue.

aPropID[i] = PROPID_Q_JOURNAL_QUOTA;  // Property identifier
aVariant[i].vt = VT_UI4;              // Type indicator
i++;

Equivalent COM Property

When using COM components, the maximum size of the queue journal can be set and retrieved using the MSMQQueueInfo.JournalQuota property.

See Also

MQCreateQueue, MQGetQueueProperties, MQQUEUEPROPS, MQSetQueueProperties, PROPID_Q_JOURNAL


PROPID_Q_LABEL

Optional. The PROPID_Q_LABEL property specifies a description of the queue.

Property ID
PROPID_Q_LABEL
Type Indicator
VT_LPWSTR
MQPROPVARIANT Field
pwszVal
Property Value
String (default is ""). The maximum length of the string is MQ_MAX_Q_LABEL_LEN (124 Unicode characters).

Remarks

The label of a queue is used to identify the queue.

For public queues, the label can be used as the search criteria for a query. By using the same label for several queues, the application can later run a query on the queue label and locate all the queues. (A query can also be used to retrieve the label of a public queue.)

To specify the label of a queue when creating a queue, specify PROPID_Q_LABEL in the MQQUEUEPROPS structure and call MQCreateQueue.

To change the label of a queue, specify PROPID_Q_LABEL in the MQQUEUEPROPS structure and call MQSetQueueProperties.

To retrieve the label of a queue, specify PROPID_Q_LABEL in the MQQUEUEPROPS structure and call MQGetQueueProperties and examine its returned value. When specifying PROPID_Q_LABEL, set the type indicator for PROPID_Q_LABEL to VT_NULL so that Message Queuing will allocate the memory needed for the label. Later, the allocated memory must be freed using MQFreeMemory.

Equivalent COM Property

When using COM components, the label of the queue can be set and retrieved using the MSMQQueueInfo.Label property.

Example Code

The following examples show how PROPID_Q_LABEL is specified in the MQQUEUEPROPS structure for setting and retrieving the label of a queue. Note that when retrieving the label, the type indicator is set to VT_NULL.

To set the label of a queue

LPWSTR wszQueueLabel = L"Test Queue";
aPropID[i] = PROPID_Q_LABEL;                // Property identifier
aVariant[i].vt = VT_LPWSTR;                 // Type indicator
aVariant[i].pwszVal = wszQueueLabel ;       // Label of queue

To retrieve the label of a queue

aPropID[i] = PROPID_Q_LABEL;                // Property identifier
aVariant[i].vt = VT_NULL;                   // Type indicator
i++;

See Also

MQCreateQueue, MQFreeMemory, MQGetQueueProperties, MQQUEUEPROPS, MQSetQueueProperties


PROPID_Q_MODIFY_TIME

Optional. The PROPID_Q_MODIFY_TIME property indicates the last time the properties of a queue were modified.

Property ID
PROPID_Q_MODIFY_TIME
Type Indicator
VT_I4
MQPROPVARIANT Field
lVal

Property Values

Time at which the properties of the queue were last set

Remarks

The PROPID_Q_MODIFY_TIME property is set by Message Queuing when MQCreateQueue is called and then reset by Message Queuing each time the properties of the queue are modified by calls to MQSetQueueProperties.

The time returned by Message Queuing is the number of seconds elapsed since midnight (00:00:00), January 1, 1970 (Coordinated Universal time) according to the system clock.

There are several related C run-time functions that can be used to manipulate the value of PROPID_Q_MODIFY_TIME. For example, ctime() can be used to display the local date and time when the properties of the queue were last modified.

Note Details on the C run-time functions can be found in the Platform SDK. When using these functions, include the time.h header file in your source code.

To retrieve the date and time at which the queue properties were last modified, specify PROPID_Q_MODIFY_TIME in the MQQUEUEPROPS structure, and then call MQGetQueueProperties (or MQLocateBegin when starting a query) and examine its returned value.

An MQ_ERROR_PROPERTY_NOTALLOWED error is returned if any attempt is made to set this property.

Equivalent COM Component

When using COM components, the time the queue properties were last modified can be retrieved using the MSMQQueueInfo.ModifyTime property.

Example Code

The following example shows how PROPID_Q_MODIFY_TIME is specified in the MQQUEUEPROPS structure for retrieving the date and time at which the properties of the queue were last modified.

//To retrieve the date and time
aPropID[i] = PROPID_Q_MODIFY_TIME;    // Property identifier
aVariant[i].vt = VT_I4;               // Type indicator
i++;

See Also

MQCreateQueue, MQGetQueueProperties, MQLocateBegin, MQQUEUEPROPS, MQSetQueueProperties


PROPID_Q_MULTICAST_ADDRESS

(Introduced in Whistler.) The PROPID_Q_MULTICAST_ADDRESS property specifies the multicast address associated with the queue.

Property ID
PROPID_Q_MULTICAST_ADDRESS
Type Indicator
VT_LPWSTR or VT_EMPTY
MQPROPVARIANT Field
pwszVal

Property Values

When the Type Indicator is set to VT_LPWSTR, the property value is a string containing a valid multicast address (in the form shown below).

<address>:<port>

When the Type Indicator is set to VT_EMPTY, the property value is meaningless and the queue is not associated with a multicast address.

Remarks

The PROPID_Q_MULTICAST_ADDRESS property is used to associate a queue with a multicast address that can be used when sending messages. When the sending application sends messages to a multicast address, Message Queuing sends a copy of the message to every queue associated with that address.

A queue can be associated with a multicast address when the queue is created or later. To create a queue call MQCreateQueue. To change properties of existing queues call MQSetQueueProperties.

To disassociate an existing queue from a multicast address set the type Indicator of PROPID_Q_MULTICAST_MESSAGE to VT_EMPTY and call MQSetQueueProperties.

Equivalent COM Property

When using COM components, the multicast address associated with the queue can be set or retrieved using the MSMQQueueInfo.MulticastAddress property.

Example code

The following example code shows how PROPID_Q_MULTICAST_ADDRESS is specified in the MQQUEUEPROPS structure when you specify a multicast address, disassociate a queue from a multicast address, and retrieve the multicast address associated with the queue.

To specify a multicast address

WCHAR AddressBuffer[]=L"111.222.333.444:80";
aMsgPropId[i] = PROPID_Q_MULTICAST_ADDRESS;    // Property ID
aMsgPropVar[i].vt = VT_LPWSTR;                 // Type indicator
aMsgPropVar[i].pwszVal = &AddressBuffer;       // Multicast address
i++;

To disassociate a queue from a multicast address

aMsgPropId[i] = PROPID_Q_MULTICAST_ADDRESS;    // Property ID
aMsgPropVar[i].vt = VT_EMPTY;                 // Type indicator
i++;

To retrieve PROPID_Q_MULTICAST_ADDRESS

aMsgPropId[i] = PROPID_Q_MULTICAST_ADDRESS;    // Property ID
aMsgPropVar[i].vt = VT_NULL;                   // Type indicator
i++;

See Also

MQCreateQueue, MQQUEUEPROPS, MQSetQueueProperties, MSMQQueueInfo.MulticastAddress


PROPID_Q_PATHNAME

Required (to create the queue). The PROPID_Q_PATHNAME property specifies the queue pathname of the queue. The pathname includes the name of the computer where messages belonging to the queue are stored, whether the queue is public or private, and the name of the queue.

Property ID
PROPID_Q_PATHNAME
Type Indicator
VT_LPWSTR
MQPROPVARIANT Field
pwszVal

Property Values

Message Queuing pathname.

Remarks

The PROPID_Q_PATHNAME property is the only property required when creating a queue. To specify the pathname of the queue, specify PROPID_Q_PATHNAME in the MQQUEUEPROPS structure and call MQCreateQueue. When setting this property you can specify the UNC or DNS pathname for the queue.

An MQ_ERROR_PROPERTY_NOTALLOWED error is returned if any attempt is made to set this property after the queue is created.

The pathname of a queue includes the name of the computer where the messages for the queue are stored, an optional PRIVATE$ key word indicating if the queue is private, followed by the name of the queue.

When specifying the name of the computer in the pathname, use its NetBIOS or full DNS name.

The name of the queue is case insensitive (for example, "MyQueue" and "myQueue" are treated as the same name) and can be up to 124 Unicode characters.

The maximum length of the name of the queue is 124 Unicode characters, However, using names longer than 64 Unicode characters may cause a slight reduction in performance. Furthermore, they are not easily displayed in the directory service.

Here are three examples of Message Queuing pathnames. The first two examples indicate two public queues (one on a local computer and the other on a remote computer). The third example indicates a private queue.

"myMachine\myPublicQueue"
"otherMachine\otherPublicQueue"
"myMachine\Private$\myPrivateQueue"

As a shortcut, you can substitute a period "." for the local computer. So myPublicQueue and myPrivateQueue could be specified on the local computer as:

".\myPublicQueue"
".\Private$\myPrivateQueue"

Private queues are only created on the local computer. It is the responsibility of the application to ensure that all queue names on the local computer are unique. If a queue name already exists when MQCreateQueue is called, Message Queuing returns an MQ_ERROR_QUEUE_EXISTS error to the application.

To retrieve the pathname of a queue stored in the directory service, specify PROPID_Q_PATHNAME in the MQQUEUEPROPS structure, and then call MQGetQueueProperties (or MQLocateBegin when starting a query) and examine its returned value.

Note After the queue is created, you can retrieve a DNS pathname for the queue at any time by retrieving the PROPID_Q_PATHNAME_DNS property of the queue. This property generates the DNS pathname when it is can

When specifying PROPID_Q_PATHNAME in the MQQUEUEPROPS structure, set its type indicator to VT_NULL. This tells Message Queuing to allocate the memory needed for the pathname. Later, this allocated memory must be freed using MQFreeMemory.

To create a foreign queue, specify the name of the foreign machine as it is defined in the directory service. (For information on defining foreign machines, see "To create a foreign computer" in Microsoft® Windows NT® Help.)

The set of valid characters for the queue pathname vary depending on the version of Message Queuing that is creating the queue. The following table lists the characters that cannot be used.

Message Queuing version | Invalid queue name characters
MSMQ 1.0 | \ (back slash) ; semicolons) CR (ascii 13); private queues only LF (ascii 10); private queues only
MSMQ 2.0 and later | \ (back slash) ; (semicolons) CR (ascii 13) LF (ascii 10) + (plus) , (comma) " (double quote)

Equivalent COM Property

When using COM components, the pathname of the queue can be set and retrieved using the MSMQQueueInfo.PathName property.

Example Code

The following examples show how PROPID_Q_PATHNAME is specified in the MQQUEUEPROPS structure for setting and retrieving the pathname of the queue. Note that when retrieving the pathname of the queue, the type indicator is set to VT_NULL.

To set the pathname of a queue

LPWSTR wszPathName = L".\\TestQueue";
aPropID[i] = PROPID_Q_PATHNAME;             // Property identifier
aVariant[i].vt = VT_LPWSTR;                 // Type indicator
aVariant[i].pwszVal = wszPathName;          // Pathname of queue

To retrieve the pathname of a queue

aPropID[i] = PROPID_Q_PATHNAME;             // Property identifier
aVariant[i].vt = VT_NULL;                   // Type indicator
i++;

See Also

MQCreateQueue, MQFreeMemory, MQGetQueueProperties, MQLocateBegin, MQQUEUEPROPS


PROPID_Q_PATHNAME_DNS

(Read-only. MSMQ 2.0 only.) The PROPID_Q_PATHNAME_DNS property indicates the pathname of the queue using the DNS name of the computer. Message Queuing generates the DNS pathname whenever this property is specified.

Property ID
PROPID_Q_PATHNAME_DNS
Type Indicator
VT_LPWSTR
MQPROPVARIANT Field
pwszVal

Property Values

A string containing the DNS pathname of the queue. A returned value of VT_EMPTY indicates that a DNS name of the queue is not available.

Remarks

This property can only be used to retrieve the DNS pathname of the queue. It cannot be used to specify the pathname of a queue when creating the queue, or when retrieving queue properties within a query.

To retrieve the DNS pathname of a queue, specify PROPID_Q_PATHNAME_DNS in the MQQUEUEPROPS structure, and then call MQGetQueueProperties and examine its returned value.

Equivalent COM Property

When using COM components, the DNS pathname of the queue can be retrieved using the MSMQQueueInfo.PathNameDNS property.

Example Code

The following example show how PROPID_Q_PATHNAME_DNS is specified in the MQQUEUEPROPS structure. Note that when you retrieve the DNS pathname of the queue, the type indicator is set to VT_NULL.

aPropID[i] = PROPID_Q_PATHNAME_DNS;         // Property identifier
aVariant[i].vt = VT_NULL;                   // Type indicator
i++;

See Also

MQGetQueueProperties, MQQUEUEPROPS


PROPID_Q_PRIV_LEVEL

Optional. The PROPID_Q_PRIV_LEVEL property specifies the privacy level that is required by the queue. The privacy level determines how the queue handles encrypted messages.

Property ID
PROPID_Q_PRIV_LEVEL
Type Indicator
VT_UI4
MQPROPVARIANT Field
ulVal

Property Values

This property can be set to one of the following values:

MQ_PRIV_LEVEL_NONE
The queue accepts only non-private (clear) messages.
MQ_PRIV_LEVEL_BODY
The queue accepts only private (encrypted) messages.
MQ_PRIV_LEVEL_OPTIONAL
The default. The queue does not enforce privacy. It accepts private (encrypted) messages and non-private (clear) messages.

Remarks

The application can set the privacy level of queues and messages. If the privacy level of the message (PROPID_M_PRIV_LEVEL) does not match the privacy level of the queue, the queue rejects the message. In addition, if the sending application requested a negative acknowledgment message when it sent the message, MQMSG_CLASS_BAD_ENCRYPTION will be returned to the sending application to indicate that the message was rejected.

To set the privacy level when creating the queue, specify PROPID_Q_PRIV_LEVEL in the MQQUEUEPROPS structure and call MQCreateQueue.

To change the privacy level of a queue, specify PROPID_Q_PRIV_LEVEL in the MQQUEUEPROPS structure and call MQSetQueueProperties. When changing the privacy level of the queue, the new setting affects only arriving messages; it does not affect messages already in the queue.

To retrieve the privacy level of a queue, specify PROPID_Q_PRIV_LEVEL in the MQQUEUEPROPS structure and call MQGetQueueProperties and examine its returned value.

Private messages can be encrypted by the sending queue manager or by the sending application.

For information on | See
Having Message Queuing encrypt messages | Message Queuing–Encrypted Messages
Having your application encrypt messages | Application-Encrypted Messages
Setting and retrieving the privacy level of a queue when you are using COM components | MSMQQueueInfo.PrivLevel

Equivalent COM Component

When using COM components, the privacy level of the queue can be set and retrieved using the MSMQQueueInfo.PrivLevel property.

Example Code

The following examples show how PROPID_Q_PRIV_LEVEL is specified in the MQQUEUEPROPS structure for setting and retrieving the privacy level of the queue.

To set the privacy level

DWORD dwPrivacyLevel = MQ_RIV_LEVEL_BODY;
aPropID[i] = PROPID_Q_PRIV_LEVEL;        // Property identifier
aVariant[i].vt = VT_UI4;                 // Type indicator
aVariant[i].ulVal = dwPrivacyLevel;      // Privacy level of queue
i++;

To retrieve the privacy level

aPropID[i] = PROPID_Q_PRIV_LEVEL;       // Property identifier
aVariant[i].vt = VT_UI4;                // Type indicator
i++;

See Also

MQCreateQueue, MQGetQueueProperties, MQQUEUEPROPS, MQSetQueueProperties


PROPID_Q_QUOTA

Optional. The PROPID_Q_QUOTA property specifies the maximum size (in kilobytes) of the queue.

Property ID
PROPID_Q_QUOTA
Type Indicator
VT_UI4
MQPROPVARIANT Field
ulVal

Property Values

Size (in kilobytes) of the queue. The default is INFINITE.

Remarks

The PROPID_Q_QUOTA property is typically set when calling MQCreateQueue. To set the maximum size when creating the queue, specify PROPID_Q_QUOTA in the MQQUEUEPROPS structure and call MQCreateQueue.

When the quota of a queue is reached, a negative acknowledgment message is returned to the administration queue of the sending application to indicate that the queue is full. Message Queuing continues to send negative acknowledgments until the cumulative size of messages in the queue drops below the quota.

To change the maximum size of a queue, specify PROPID_Q_QUOTA in the MQQUEUEPROPS structure and call MQSetQueueProperties with the new value. When the quota of the queue is changed, the new quota affects only arriving messages; it does not affect messages already in the queue.

To retrieve the maximum size of a queue, specify PROPID_Q_QUOTA in the MQQUEUEPROPS structure and call MQGetQueueProperties and examine its returned value.

Equivalent COM Component

When using COM components, the maximum size of the queue can be set and retrieved using the MSMQQueueInfo.Quota property.

Example Code

The following examples show how PROPID_Q_QU0TA is specified in the MQQUEUEPROPS structure for setting and retrieving the maximum size of the queue.

To set the maximum size of the queue

aPropID[i] = PROPID_Q_QUOTA;          // Property identifier
aVariant[i].vt = VT_UI4;              // Type indicator
aVariant[i].bVal = 1000;              // Maximum size of the queue
i++;

To retrieve the maximum size of the queue

aPropID[i] = PROPID_Q_QUOTA;          // Property identifier
aVariant[i].vt = VT_UI4;              // Type indicator
i++;

See Also

MQCreateQueue, MQGetQueueProperties, MQQUEUEPROPS, MQSetQueueProperties


PROPID_Q_TRANSACTION

Optional. The PROPID_Q_TRANSACTION property specifies whether the queue is a transactional queue or a non-transactional queue.

Property ID
PROPID_Q_TRANSACTION
Type Indicator
VT_UI1
MQPROPVARIANT Field
bVal

Property Values

This property can be set to one of the following values:

MQ_TRANSACTIONAL
All messages sent to the queue must come through an Message Queuing transaction.
MQ_TRANSACTIONAL_NONE
The default. No transaction operations can be performed on the queue.

Remarks

If a queue is transactional, it can accept only messages that are sent as part of a transaction (see MQSendMessage). However, messages can be retrieved from a local transactional queue with or without using a transaction (see MQReceiveMessage).

For information on how Message Queuing performs transactions, see Message Queuing Transactions.

To create a transactional queue, specify PROPID_Q_TRANSACTION in the MQQUEUEPROPS structure and call MQCreateQueue.

PROPID_Q_TRANSACTION cannot be changed once the queue is created. If an attempt is made to set it afterward, an MQ_ERROR_PROPERTY error is returned to the call, and the associated aStatus entry of the property will contain MQ_PROPERTY_NOTALLOWED.

To find out if the queue is a transactional queue, specify PROPID_Q_TRANSACTION in the MQQUEUEPROPS structure and call MQGetQueueProperties and examine its returned value.

Equivalent COM Component

When using COM components, the transaction level of the queue can be retrieved using the MSMQQueueInfo.IsTransactional2 property.

Example Code

The following examples show how PROPID_Q_TRANSACTION is specified in the MQQUEUEPROPS structure for setting and retrieving this property.

To set PROPID_Q_TRANSACTION

UCHAR ucTransactionLevel = MQ_TRANSACTIONAL;
aPropID[i] = PROPID_Q_TRANSACTION;        // Property identifier
aVariant[i].vt = VT_UI1;                  // Type indicator
aVariant[i].bVal = ucTransactionLevel;    // Creates transactional queue
i++;

To retrieve PROPID_Q_TRANSACTION

aPropID[i] = PROPID_Q_TRANSACTION;       // Property identifier
aVariant[i].vt = VT_UI1;                 // Type indicator
i++;

See Also

aStatus, MQCreateQueue, MQGetQueueProperties, MQReceiveMessage, MQQUEUEPROPS, MQSendMessage


PROPID_Q_TYPE

Optional. The PROPID_Q_TYPE property specifies the type of service provided by the queue. The type of the queue allows applications to categorize their queues according to how they are used.

Property ID
PROPID_Q_TYPE
Type Indicator
VT_CLSID
MQPROPVARIANT Field
*puuid

Property Values

GUID value. The default is NULL_GUID.

Remarks

The service type of the queue can be used to identify the queue.

It is recommended that the service type of the queue be specified when the queue is created. In most cases, the service type of the queue can be defined by the application. However, some queues used by Message Queuing require a specific Message Queuing–defined service type. For example, input queues used by the Message Queuing mail services have a specific Message Queuing–defined MAPI service type.

Note To generate a GUID, run the Uuidgen.exe program provided by Microsoft Developer Network.

The service type of the queue can also be used to locate public queues registered in the directory service (see MQLocateBegin and MQLocateNext).

To set the initial service type of the queue, specify PROPID_Q_TYPE in the MQQUEUEPROPS structure and call MQCreateQueue.

To change the service type of the queue, specify PROPID_Q_TYPE in the MQQUEUEPROPS structure and call MQSetQueueProperties with a new GUID.

To retrieve the service type of a queue, specify PROPID_Q_TYPE in the MQQUEUEPROPS structure and call MQGetQueueProperties and examine its returned value.

Note The returned queue identifier is a binary GUID. To convert the returned GUID to a string, use UUIDToString. When using this function, include the rpc.h header file in your source code.

Equivalent COM Component

When using COM components, the service type identifierl of the queue can be set and retrieved using the MSMQQueueInfo.ServiceTypeGuid property.

Example Code

The following examples show how PROPID_Q_INSTANCE is specified in the MQQUEUEPROPS structure for setting and retrieving the queue type. Note that when you are retrieving the queue type, a buffer of type CLSID must be declared to receive the returned GUID.

To set the queue type

aPropID[i] = PROPID_Q_TYPE;                 // Property identifier
aVariant[i].vt = VT_CLSID;                  // Type indicator
aVariant[i].puuid = &PRINTER_SERVICE_TYPE;  // Service type of queue

To retrieve the queue type

CLSID TypeBuffer;
aPropID[i] = PROPID_Q_TYPE;        // Property identifier
aVariant[i].vt = VT_CLSID;         // Type indicator
aVariant[i].puuid = &TypeBuffer
i++;

See Also

MQCreateQueue, MQGetQueueProperties, MQLocateBegin, MQLocateNext, MQQUEUEPROPS, MQSetQueueProperties


PROPID_QM_CONNECTION

(Read-only.)The PROPID_QM_CONNECTION property identifies the CN or site list of the computer.

Property ID
PROPID_QM_CONNECTION
Type Indicator
VT_LPWSTR | VT_VECTOR
MQPROPVARIANT Field
calpwstr

Property Values

<TYPE><GUID><Name>

Remarks

The PROPID_QM_CONNECTION property is typically used by connector applications to retrieve the CN or site list of a computer.

For MSMQ 1.0 computers, the returned GUIDs identify the Connected Networks associated with the computer. For MSMQ 2.0 and later computers, the returned GUIDs identify the sites associated with the computer.

To retrieve the CN or site list of a computer, include PROPID_QM_CONNECTION in the MQQMPROPS structure, and then call MQGetMachineProperties and examine the returned property value.

Example Code

The following example code shows how PROPID_QM_CONNECTION is specified in the MQQMPROPS structure.

aQMPropId[i] = PROPID_QM_CONNECTION;         // Property identifier
aQMPropVar[i].vt = VT_LPWSTR|VT_VECTOR;      // Type indicator
aQMPropVar[i].puuid = &Connection;           // Address of connection buffer

Equivalent COM Property

There is no equivalent COM component for retrieving the CN or site list of the computer.

See Also

MQGetMachineProperties, MQQMPROPS


PROPID_QM_ENCRYPTION_PK

(Read-only, superseded by PROPID_QM_ENCRYPTION_PK_BASE.) The PROPID_QM_ENCRYPTION_PK property indicates the 40-bit public encryption key of the computer.

Property ID
PROPID_QM_ENCRYPTION_PK
Type Indicator
VT_VECTOR | VT_UI1
MQPROPVARIANT Field
caub

Property Values

Public encryption key

Remarks

The PROPID_QM_ENCRYPTION_PK property of the computer is set by Message Queuing when Message Queuing is installed.

Retrieving PROPID_QM_ENCRYPTION_PK

To retrieve the public encryption key of the computer, include PROPID_QM_ENCRYPTION_PK in the MQQMPROPS structure, and then call MQGetMachineProperties and examine the returned property value.

Example Code

The following example shows how PROPID_QM_ENCRYPTION_PK is specified in the MQQMPROPS structure.

aQMPropId[i] = PROPID_QM_ENCRYPTION_PK;      // Property identifier
aQMPropVar[i].vt = VT_VECTOR|VT_UI1;         // Type indicator
aQMPropVar[i].puuid = &EncryptionKey;        // Address of encryption key buffer

Equivalent COM Property

There is no equivalent COM component for retrieving the 40-bit public encryption key of the computer.

See Also

MQGetMachineProperties, MQQMPROPS, PROPID_QM_ENCRYPTION_PK_BASE


PROPID_QM_ENCRYPTION_PK_BASE

(Read-only, introduced in MSMQ 2.0.) The PROPID_QM_ENCRYPTION_PK_BASE property indicates the 40-bit public encryption key of the computer.

Property ID
PROPID_QM_ENCRYPTION_PK_BASE
Type Indicator
VT_VECTOR | VT_UI1
MQPROPVARIANT Field
caub

Property Values

40-bit public encryption key

Remarks

The PROPID_QM_ENCRYPTION_PK_BASE property is set by Message Queuing when Message Queuing is installed on the computer. PROPID_QM_ENCRYPTION_PK_BASE supersedes the PROPID_QM_ENCRYPTION_PK property.

To retrieve the 128-bit public encryption key, see PROPID_QM_ENCRYPTION_PK_ENHANCED.

To retrieve the 40-bit public encryption key of the computer, include PROPID_QM_ENCRYPTION_PK_BASE in the MQQMPROPS structure, and then call MQGetMachineProperties and examine the returned property value.

Example Code

The following example shows how PROPID_QM_ENCRYPTION_PK_BASE is specified in the MQQMPROPS structure.

aQMPropId[i] = PROPID_QM_ENCRYPTION_PK_BASE; // Property identifier
aQMPropVar[i].vt = VT_VECTOR|VT_UI1;         // Type indicator
aQMPropVar[i].puuid = &EncryptionKey;        // Address of encryption key buffer

Equivalent COM Property

There is no equivalent COM component for retrieving the 40-bit public encryption key of the computer.

See Also

MQGetMachineProperties, PROPID_QM_ENCRYPTION_PK_ENHANCED


PROPID_QM_ENCRYPTION_PK_ENHANCED

(Read-only, introduced in MSMQ 2.0.) The PROPID_QM_ENCRYPTION_PK_ENHANCED property indicates the 128-bit public encryption key of the computer.

Property ID
PROPID_QM_ENCRYPTION_PK_ENHANCED
Type Indicator
VT_UI1 | VT_VECTOR
MQPROPVARIANT Field
caub

Property Values

128-bit public encryption key.

Remarks

The PROPID_QM_ENCRYPTION_PK_ENHANCED property is set by Message Queuing when Message Queuing is installed.

For the 40-bit public encryption key, see PROPID_QM_ENCRYPTION_PK_BASE.

To retrieve the 128-bit public encryption key of the computer, include PROPID_QM_ENCRYPTION_PK_ENHANCED in the MQQMPROPS structure and then call MQGetMachineProperties and examine the returned property value.

Example Code

The following example shows how PROPID_QM_ENCRYPTION_PK_ENHANCED is specified in the MQQMPROPS structure.

aQMPropId[i] = PROPID_QM_ENCRYPTION_PK_ENHANCED; // Property identifier
aQMPropVar[i].vt = VT_VECTOR|VT_UI1;             // Type indicator
aQMPropVar[i].puuid = &EncryptionKey;            // Address of encryption key buffer

MQGetMachineProperties error codes

When calling the MQGetMachineProperties function to retrieve 128-bit encryption keys, the following two errors may be returned.

MQ_ERROR_PUBLIC_KEY_DOES_NOT_EXIST
This error is returned when the enhanced key is not registered. Message Queuing was able to successfully query the directory service, but the 128-bit public encryption key was not found.
MQ_ERROR_PUBLIC_KEY_NOT_FOUND
This error is returned when Message Queuing failed to query the directory service. For example, this can happen if the computer calling MQGetMachineProperties is operating offline or if you are trying to retrieve the machine properties of a computer running MSMQ 1.0.

Equivalent COM Property

There is no equivalent COM component for retrieving the 128-bit public encryption key of the computer.

See Also

MQGetMachineProperties, MQQMPROPS, PROPID_QM_ENCRYPTION_PK_BASE


PROPID_QM_MACHINE_ID

(Read-only.) The PROPID_QM_MACHINE_ID property identifies the computer.

Property ID
PROPID_QM_MACHINE_ID
Type Indicator
VT_CLSID
MQPROPVARIANT Field
*puuid

Property Values

Machine GUID

Remarks

The PROPID_QM_MACHINE_ID property is set by Message Queuing when the computer is defined (for dependent clients, Message Queuing sets this property to the identifier of the client's server computer).

The PROPID_QM_MACHINE_ID property is used when specifying a private format name for a private queue or a computer format name for a computer journal or dead-letter queue.

To retrieve the identifier of the machine, include PROPID_QM_MACHINE_ID in the MQQMPROPS structure and then call MQGetMachineProperties and examine the returned property value.

Example Code

The following example shows how PROPID_QM_MACHINE_ID is specified in the MQQMPROPS structure.

aQMPropId[i] = PROPID_QM_MACHINE_ID;         // Property identifier
aQMPropVar[i].vt = VT_CLSID;                 // Type indicator
aQMPropVar[i].puuid = &guidMachineId;        // Machine ID buffer

Equivalent COM Property

To retrieve the machine identifier using COM components, call the MSMQApplication.MachineIdofMachineName method.

See Also

MQGetMachineProperties, MSMQApplication.MachineIdofMachineName


PROPID_QM_PATHNAME

(Read-only.) The PROPID_QM_PATHNAME property provides the pathname of the computer.

Property ID
PROPID_QM_PATHNAME
Type Indicator
VT_LPWSTR
MQPROPVARIANT Field
pwszVal

Property Values

UNC pathname of computer.

Remarks

This property returns the UNC name of the computer (for dependent clients, Message Queuing sets this property to the pathname of the client's server computer).

DNS pathname

To retrieve a DNS name of the computer, retrieve the PROPID_QM_PATHNAME_DNS property.

To retrieve the UNC pathname of a computer, include PROPID_QM_PATHNAME in the MQQMPROPS structure and then call MQGetMachineProperties and examine the returned property value. When specifying PROPID_QM_PATHNAME_DNS, set the type identifier field to VT_NULL.

Example Code

The following example shows how PROPID_QM_PATHNAME is specified in the MQQMPROPS structure.

aQMPropId[i] = PROPID_QM_PATHNAME;      // Property identifier
aQMPropVar[i].vt = VT_NULL;             // Type indicator
aQMPropVar[i].puuid = &pathname;        // Pathname buffer

Equivalent COM Property

To retrieve the UNC pathname of the machine using COM components, call the MSMQApplication.MachineNameofMachineId method. Note that the COM component returns the UNC pathname only if it cannot generate the DNS pathname of the computer.

See Also

MQGetMachineProperties, MQQMPROPS, PROPID_QM_PATHNAME_DNS.


PROPID_QM_PATHNAME_DNS

(Read-only, introduced in MSMQ 2.0.) The PROPID_QM_PATHNAME_DNS property provides the DNS pathname of the computer.

Property ID
PROPID_QM_PATHNAME_DNS
Type Indicator
VT_LPWSTR
MQPROPVARIANT Field
pwszVal

Property Values

A string that contains a DNS pathname. A returned value of VT_EMPTY indicates that a DNS name of the computer is not available.

Remarks

This property returns the DNS name for the computer. The DNS pathname is generated on demand, it is not the computer pathname stored in the directory service.

To retrieve the UNC name of the computer, retrieve the PROPID_QM_PATHNAME of the computer.

To retrieve the DNS pathname of a computer, include PROPID_QM_PATHNAME_DNS in the MQQMPROPS structure, and then call MQGetMachineProperties and examine the returned property valu.

Example Code

The following example shows how PROPID_QM_PATHNAME_DNS is specified in the MQQMPROPS structure.

aQMPropId[i] = PROPID_QM_PATHNAME_DNS;  // Property identifier
aQMPropVar[i].vt = VT_LPWSTR;           // Type indicator
aQMPropVar[i].puuid = &pathnameDNS;     // DNS Pathname buffer

Equivalent COM Property

To retrieve the DNS pathname of the machine using COM components, call the MSMQApplication.MachineNameofMachineId method.

See Also

MQGetMachineProperties, PROPID_QM_PATHNAME


PROPID_QM_SITE_ID

(Read-only) The PROPID_QM_SITE_ID property provides the site where the computer is located.

Property ID
PROPID_QM_SITE_ID
Type Indicator
VT_CLSID
MQPROPVARIANT Field
*puuid

Property Values

Site identifier

Remarks

The PROPID_QM_SITE_ID property is set by Message Queuing when the computer is created. It is typically used to determine where the queue manager for a specific machine resides.

The site identifier for a computer indicates where the queue manager for that computer is currently located. When the location of the computer changes, Message Queuing automatically updates PROPID_QM_SITE_ID to indicate the new site.

To retrieve the site identifier for a computer, include PROPID_QM_SITE_IS in the MQQMPROPS structure, and then call MQGetMachineProperties and examine the returned property value.

Example Code

The following example shows how PROPID_QM_SITE_ID is specified in the MQQMPROPS structure.

aQMPropId[i] = PROPID_QM_SITE_ID;                 // Property ID
aQMPropVar[i].vt = VT_CLSID;                      // Type indicator
aQMPropVar[i].puuid = &guidSiteIdBuffer;          // Address of buffer
i++;

Equivalent COM Property

There is no equivalent COM component for retrieving the identifier of the site where the computer is located.

See Also

MQGetMachineProperties, MQQMPROPS


Message Queuing Structures

Message Queuing uses structures for message, queue, queue manager, and personal computer properties, as well as structures for data used to locate queue.

Message Queuing structures include the following.

Structures | Description
aPropID | Specifies the identifiers of the corresponding queue, message, and machine properties.
aPropVar | Specifies the values of the corresponding queue, message and machine properties
aStatus | Optional. Specifies the status of the corresponding queue, message, and machine properties. It contains errors returned by Message Queuing.
MQCOLUMNSET | Specifies the number of queue properties to be retrieved from each queue and their property identifiers.
MQMSGPROPS | Specifies a set of message properties.
MQPRIVATEPROPS | Specifies a set of local computer properties.
MQPROPERTYRESTRICTION | Defines a property restriction for a query.
MQQMPROPS | Specifies a set of queue manager properties.
MQQUEUEPROPS | Specifies a set of queue properties.
MQRESTRICTION | Indicates the properties used to locate queues in a query.
MQSORTKEY | Specifies individual sort keys for a locate queue query.
MQSORTSET | Specifies the sort keys for a locate queue query.
MQPROPVARIANT | Stores property value settings.


aPropID

The aPropID structure is an array used to specify queue, message, and machine property identifiers. It is used to identify which properties are specified for a call.

Message Queuing defines three types of property identifiers: QUEUEPROPID for queue properties, MSGPROPID for message properties, and QMPROPID for machine properties.

typedef PROPID   MSGPROPID
typedef PROPID   QUEUEPROPID
typedef PROPID   QMPROPID

An aPropID array is used in the following property structures: MQQUEUEPROPS, MQMSGPROPS, and MQQMPROPS. Position i in this array contains the identifier for the property whose value and status are in position i in the corresponding aPropVar and aStatus arrays respectively.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mq.h.

See Also

aPropVar, aStatus, MQMSGPROPS, MQQMPROPS, MQQUEUEPROPS


aPropVar

The aPropVar structure is an array of MQPROPVARIANT structures used to specify the value of a queue, message, and machine property.

Position i in this array contains the value for the property whose identifier and status are in position i in the corresponding aPropID and aStatus arrays respectively.

An aPropVar array is used in the following property structures: MQQUEUEPROPS, MQMSGPROPS, and MQQMPROPS.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mq.h.

See Also

aPropID, aStatus, MQMSGPROPS, MQQMPROPS, MQQUEUEPROPS, MQPROPVARIANT


aStatus

The aStatus structure is an optional array that contains error codes returned by Message Queuing. It can be included in MQQUEUEPROPS, MQMSGPROPS, and MQQMPROPS.

Position i in this array is a reported status code of the property whose identifier and value are in position i in the corresponding aPropID and aPropVar arrays.

Message Queuing errors are divided into four categories (by increasing order of severity); the category can be determined by looking at the upper two bits of the error code (success = 00, informational = 01, warning = 10, fatal = 11).

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mq.h.

See Also

aPropID, aPropVar, MQMSGPROPS, MQQMPROPS, MQQUEUEPROPS


MQCOLUMNSET

The MQCOLUMNSET structure specifies the number of queue properties to be retrieved from each queue and their property identifiers. You can specify any number of queue properties, from a single queue property to all the properties provided by Message Queuing. Message Queuing can return any number of queue properties to the single query.

typedef struct  tagMQCOLUMNSET
{
  ULONG              cCol;
  PROPID _RPC_FAR   *aCol;
}   MQCOLUMNSET;

Members

cCol
Number of properties to be retrieved.
aCol
An array of property identifiers (for example, PROPID_Q_PATHNAME, PROPID_Q_INSTANCE, and so on).

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mq.h.

See Also

MQLocateBegin


MQMSGPROPS

The MQMSGPROPS structure describes a set of message properties. It specifies the number of properties (cProp) in the set, the identifier of each property (aPropID), and the values (or placeholder for values) of each property (aPropVar). It also provides an optional status array (aStatus) for errors associated with the property (some properties do not return a status).

typedef struct  tagMQMSGPROPS
{
  DWORD            cProp;
  MSGPROPID       *aPropID;
  MQPROPVARIANT   *aPropVar;
  HRESULT         *aStatus;
} MQMSGPROPS;

Members

cProp
Number of properties in the set.
aPropID
Property identifiers (for example, PROPID_M_LABEL, PROPID_M_MSGID, PROPID_M_BODY, and so on). For information about the structure, see aPropID.
aPropVar
Value of properties in the set. For information about the structure, see aPropVar.
aStatus
Optional. Returns errors that indicate the status of the properties in the set: for example, when a property cannot be set by the call. For information about the structure, see aStatus.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mq.h.

See Also

aPropID, aPropVar, aStatus


MQPRIVATEPROPS

The MQPRIVATEPROPS structure describes a set of properties that describe the local computer. It specifies the number of properties (cProp) in the set, the identifier of each property (aPropID), the values (or placeholder for values) of each property (aPropVar), and an optional status array (aStatus) for errors associated with properties (some properties do not return a status).

typedef struct  tagMQPRIVATEPROPS
{
  DWORD            cProp;
  QMPROPID        *aPropID;
  MQPROPVARIANT   *aPropVar;
  HRESULT         *aStatus;
} MQPRIVATEPROPS;

Members

cProp
Number of properties in the set.
aPropID
Property identifiers (for example, PROPID_PC_VERSION). For information about the structure, see aPropID.
aPropVar
Value of properties in the set. For information about the structure, see aPropVar.
aStatus
Optional. Returns errors that indicate the status of the properties in the set: for example, when a property cannot be set by the call. For information about the structure, see aStatus.

Requirements

Windows NT/2000 or later: Requires Windows 2000 or later.
Windows 95/98/Me: Unsupported.
Header: Declared in Mq.h.

See Also

aPropID, aPropVar, aStatus


MQPROPERTYRESTRICTION

The MQPROPERTYRESTRICTION structure defines a property restriction for a query. The property restriction consists of a comparison operator, a property identifier, and a property value.

typedef struct  tagMQPROPERTYRESTRICTION
{
  ULONG           rel;
  PROPID          prop;
  MQPROPVARIANT   prval;
} MQPROPERTYRESTRICTION;

Members

rel
Comparison operator for this property. Possible values include: less than (PRLT), less than or equal to (PRLE), equal (PREQ), not equal (PRNE), greater than or equal to (PRGE), and greater than (PRGT).
prop
Queue property identifier.
prval
Comparison value (includes variant type and value for the property). For information about the structure used by prval, see MQPROPVARIANT.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mq.h.

See Also

MQLocateBegin, MQRESTRICTION, MQPROPVARIANT


MQQMPROPS

The MQQMPROPS structure describes a set of queue manager properties. It specifies the number of properties (cProp) in the set, the identifier of each property (aPropID), and the values (or placeholder for values) of each property (aPropVar). It also provides an optional status array (aStatus) for errors associated with the property (some properties do not return a status).

typedef struct  tagMQQMPROPS
{
  DWORD            cProp;
  QMPROPID        *aPropID;
  MQPROPVARIANT   *aPropVar;
  HRESULT         *aStatus;
} MQQMPROPS;

Members

cProp
Number of properties in the set.
aPropID
Property identifiers (for example, PROPID_QM_PATHNAME). For information about the structure, see aPropID.
aPropVar
Value of properties in the set. For information about the structure, see aPropVar.
aStatus
Optional. Returns errors that indicate the status of the properties in the set: for example, when a property cannot be set by the call. For information about the structure, see aStatus.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mq.h.

See Also

aPropID, aPropVar, aStatus


MQQUEUEPROPS

The MQQUEUEPROPS structure describes a set of queue properties. It specifies the number of properties (cProp) in the set, the identifier of each property (aPropID), and the values (or placeholder for values) of each property (aPropVar). It also provides an optional status array (aStatus) for errors associated with the property (some properties do not return a status).

typedef struct  tagMQQUEUEPROPS
{
  DWORD             cProp;
  QUEUEPROPID      *aPropID;
  MQPROPVARIANT    *aPropVar;
  HRESULT          *aStatus;
} MQQUEUEPROPS;

Members

cProp
Number of properties in the set.
aPropID
Property identifiers (for example, PROPID_Q_PATHNAME). For information about the structure, see aPropID.
aPropVar
Value of properties in the set. For information about the structure, see aPropVar.
aStatus
Optional. Returns errors that indicate the status of the properties in the set: for example, when a property cannot be set by the call. For information about the structure, see aStatus.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mq.h.

See Also

aPropID, aPropVar, aStatus


MQRESTRICTION

The MQRESTRICTION structure indicates the properties used to locate queues in a query. Only those public queues that match all the restrictions specified here are returned by the query.

For information on starting the query, see MQLocateBegin.

typedef struct  tagMQRESTRICTION
{
  ULONG                            cRes;
  MQPROPERTYRESTRICTION  _RPC_FAR *paPropRes;

} MQRESTRICTION;

Members

cRes
Number of property restrictions to use in the query.
*paPropRes
An array of property restrictions. To specify a property restriction, see MQPROPERTYRESTRICTION.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mq.h.

See Also

MQLocateBegin, MQPROPERTYRESTRICTION


MQSORTKEY

The MQSORTKEY structure specifies a sort key for the query. Each key contains a queue property and a sort order.

typedef struct tagMQSORTKEY
{
  PROPID  propColumn;
  ULONG   dwOrder;
}   MQSORTKEY;

Members

propColumn
Queue property name to sort on (for example, PROPID_Q_QUOTA).
dwOrder
Order of sort. Possible values are QUERY_SORTASCEND and QUERY_SORTDESCEND.

Remarks

An array of MQSORTKEY structures is specified in the aCol member of the MQSORTSET structure. Currently Message Queuing supports only one sort key.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mq.h.

See Also

MQSORTSET


MQSORTSET

The MQSORTSET structure specifies the sort keys for a query.

typedef struct  tagMQSORTSET
{
  ULONG                cCol;
  MQSORTKEY  _RPC_FAR *aCol;
}   MQSORTSET;

Members

cCol
Number of sort keys used to sort the results of the query. This member must be set to 1.
*aCol
An array of MQSORTKEY structures that describe the sort keys. Each sort key specifies a queue property and sort order (ascending or descending) of the sort.

Remarks

The MQSORTSET structure is specified in the pSort parameter of the MQLocateBegin function. Currently Message Queuing supports only one sort key per query.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mq.h.

See Also

MQLocateBegin, MQSORTKEY


MQPROPVARIANT

The MQROPVARIANT structure is a general structure used to store property values and value type. It is used for the elements of the aPropVar array and prval array.

struct    tagMQPROPVARIANT  {
    VARTYPE vt;                    /* value tag  */
    WORD wReserved1;
    WORD wReserved2;
    WORD wReserved3;
    union   {
             UCHAR             bVal;      /* VT_UI1   */
             short             iVal;      /* VT_I2    */
             USHORT            uiVal;     /* VT_UI2   */
             VARIANT_BOOL      bool;      /* VT_BOOL  */
             long              lVal;      /* VT_I4    */
             ULONG             ulVal;     /* VT_UI4   */
             ULARGE_INTEGER    uhVal;     /* VT_UI8   */
             SCODE             scode;     /*          */
             DATE              date;      /* VT_DATE  */
             CLSID  _RPC_FAR  *puuid;     /* VT_CLSID */
             BLOB              blob;      /* VT_BLOB  */
             LPOLESTR          bstrVal;   /*          */
             LPSTR             pszVal;    /* VT_LPSTR */
             LPWSTR            pwszVal;   /* VT_LPWSTR */
             CAUI1             caub;      /* VT_VECTOR | VT_UI1    */
             CAI2              cai;       /* VT_VECTOR | VT_I2     */
             CAUI2             caus;      /* VT_VECTOR | VT_UI2    */
             CABOOL            cabool;    /* VT_VECTOR | VT_BOOL   */
             CAI4              cal;       /* VT_VECTOR | VT_I4     */
             CAUI4             caul;      /* VT_VECTOR | VT_UI4    */
             CACLSID           cauuid;    /* VT_VECTOR | VT_CLSID  */
             CABSTR            cabstr;    /* VT_VECTOR | VT_BSTR   */
             CALPWSTR          calpwstr;  /* VT_VECTOR | VT_LPWSTR */
             CAPROPVARIANT   capropvar;   /*                       */
            };
};

typedef struct MQPROPVARIANT MQPROPVARIANT;

Members

vt
The type indicator of the property. The valid indicators for the VT field are a subset of the Automation VARENUM enumeration type (including VT_NULL, VT_I2, VT_I4, VT_LPWSTR, VT_UI1, VT_UI4, VT_CLSID, VT_VECTOR|VT_UI1, VT_VECTOR|VT_LPWSTR ).
wReserved1, wReserved2, wReserved3
Reserved by Message Queuing.
union
Specifies the value of the property. Depending on the type identifier specified by VT, the corresponding member of the union holds the value of the property.

Remarks

Property values are tagged values, where the tag is the type indicator (an integer value) passed as an instance of VARTYPE.

To specify a property (with the exception of some message properties passed to MQReceiveMessage) and queue properties passed to MQGetQueueProperties, you must know its type indicator and the member of the union associated with the type indicator (both are provided with each property description). For example, to specify the message body in PROPID_M_BODY, the application must set VT to VT_UI1| VT_VECTOR and assign the message body to the caub member of the union.

CA prefixed members of the union (caub through capropvar) are constructs used to pass buffers as counted arrays.

For example, CAUI1 is a counted array of bytes:

typedef struct tagCAUI1 {
    ULONG cElems;               /* Byte Counter                  */
    unsigned char *pElems;      /* Pointer to a buffer of bytes  */
} CAUI1;

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later. Available as a redistributable for Windows 95.
Header: Declared in Mq.h.

See Also

MQLocateNext, MQMSGPROPS, MQPROPERTYRESTRICTION, MQQMPROPS, MQQUEUEPROPS


Message Queuing COM Components

Message Queuing provides COM components that support queue lookup, queue management, message management, queue administration, and transaction support. As a group, these components provide most of the same functionality as the Message Queuing API functions.

The Message Queuing COM objects include the following.

Value | Meaning
MSMQApplication | Provides methods and properties for the application object, including Message Queuing version properties.
MSMQCoordinatedTransactionDispenser | Obtains an MS DTC transaction object.
MSMQEvent | Implements a single event handler that can support multiple queues.
MSMQMessage | Provides the message properties used to specify the behavior of the message and a method for sending the message to the queue.
MSMQQuery | Provides methods for querying the directory service for existing public queues.
MSMQQueue | Represents an open instance of an Message Queuing queue.
MSMQQueueInfo | Represents a Message Queuing queue.
MSMQQueueInfos | Represents a collection of public queues returned in a query.
MSMQTransaction | Represents a transaction object obtained externally or created internally.
MSMQTransactionDispenser | Creates a new Message Queuing internal transaction object.


MSMQApplication

The MSMQApplication object provides methods and properties that can be used to obtain information about the Message Queuing service on the local computer, including the name of the local computer.

Note Creating a new instance of this object does not start a new instance of the Message Queuing service.

Methods

The following table lists the methods of the MSMQApplication object.

Method | Description
MachineIdOfMachineName | Returns the machine identifier for a specified computer.
MachineNameOfMachineId | (Introduced in MSMQ 2.0.) Returns the machine name of a specified computer.
RegisterCertificate | (Introduced in MSMQ 2.0.) Registers an external or internal certificate in the directory service.

Properties

The following table lists the properties of the MSMQApplication object.

Property | Description
IsDSEnabled Access: Read-only Data type: Boolean | (Introduced in MSMQ 2.0.) Indicates whether Message Queuing is using a directory service.
MSMQVersionBuild Access: Read-only Data type: Integer | (Introduced in MSMQ 2.0.) Returns the build number of the version of Message Queuing that is installed.
MSMQVersionMajor Access: Read-only Data type: Integer | (Introduced in MSMQ 2.0.) Returns the major version of Message Queuing that is installed.
MSMQVersionMinor Access: Read-only Data type: Integer | (Introduced in MSMQ 2.0.) Returns the minor version of Message Queuing that is installed.

Remarks

Because MSMQApplication is a COM application object, MSMQApplication does not have to be explicitly referenced when calling the methods provided by the object. For example, the following three calls to MSMQApplication.MachineIdOfMachineName all return the same computer identifier.

Dim strId As String
Dim myapp As New MSMQApplication

strId = MachineIdOfMachineName("machinename")
Debug.Print strId

strId = MSMQApplication.MachineIdOfMachineName("machinename")
Debug.Print strId

strId = myapp.MachineIdOfMachineName("machinename")
Debug.Print strId

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.


MSMQApplication.IsDSEnabled

(Read-only, introduced in MSMQ 2.0.) The IsDSEnabled property indicates whether the local Message Queuing service is using the directory service on the computer.

Type: | Boolean
Run time: | Read-only

applicationObject.IsDSEnabled

Parameters

applicationObject
Optional. The application object (MSMQApplication).

Return Values

For information on return codes, see Message Queuing Error and Information Codes.

Remarks

Message Queuing does not access the directory service to determine if the Message Queuing service is using the directory service. The value returned by MSMQApplication.IsDSEnabled is a calculated value.

COM application objects

When calling MSMQApplication.IsDSEnabled, you do not need to reference the MSMQApplication object explicitly.

Equivalent API function property

When using API functions, the DS enabled indicator can be retrieved using the PROPID_PC_DS_ENABLED property.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQApplication


MSMQApplication.MachineIdOfMachineName

The MachineIdOfMachineName method of the MSMQApplication object returns the machine identifier for a specified computer. The machine identifier can be used to create the format name of a computer journal.

The machine identifier is used when specifying a private format name for a private queue or a computer format name for a computer journal or dead-letter queue.

machineId = applicationObject.MachineIdOfMachineName( _
  "MachineName" _
)

Parameters

machineId
Variable that receives the returned computer identifier.
applicationObject
Optional. The application object (MSMQApplication).
MachineName
String containing the name of the computer.

Return Values

For information on return codes, see Message Queuing Error and Information Codes.

Remarks

The machine identifier is generated by Message Queuing when the computer is defined (for dependent clients, Message Queuing sets this property to the identifier of the dependent client's server computer).

To retrieve the identifier of the local computer, use the Visual Basic constant vbNullString as shown below.

strMachineId = MachineIdOfMachineName(vbNullString)

Applications operating offline cannot call MachineIdOfMachineName while they are offline. Message Queuing must have access to the directory service to retrieve the machine identifier of a computer. For information on offline operations, see Message Queuing Offline Support.

When you call MachineIdOfMachineName, you do not have to reference the MSMQApplication object explicitly. For example, the following lines of code both return the machine identifier of the local computer.

strMachineId = MachineIdOfMachineName(vbNullString)
strMachineId = MSMQApplication.MachineIdOfMachineName(vbNullString)

Equivalent API function property

When using API functions, the machine identifier can be retrieved using the PROPID_QM_MACHINE_ID property.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQApplication, PROPID_QM_MACHINE_ID


MSMQApplication.MachineNameOfMachineId

(Introduced in MSMQ 2.0.) The MachineNameOfMachineId method of the MSMQApplication object returns the machine name for a specified computer.

machineName = applicationObject.MachineNameOfMachineId( _
  "MachineId" _
)

Parameters

machineName
Variable that receives the DNS name (if one is available) or UNC name of the computer.
applicationObject
Optional. The application object (MSMQApplication).
MachineId
String containing the name of the computer.

Return Values

For information on return codes, see Message Queuing Error and Information Codes.

Remarks

The MachineNameOfMachineId property returns the DNS pathname of the computer if possible. If the DNS pathname cannot be generated, the UNC pathname of the computer is returned.

To retrieve the name of the local computer, use the Visual Basic constant vbNullString as shown below.

strMachineName = MachineNameOfMachineId(vbNullString)

Applications operating offline cannot call MSMQApplication.MachineNameOfMachineId while they are offline. Message Queuing must have access to the directory service to retrieve the machine name of a computer. For information on offline operations, see Message Queuing Offline Support.

To retrieve the name of the computer that sent a message, use the MSMQMessage.SourceMachineGuid message property as shown below.

strMachineName = MachineNameOfMachineId(msg.SourceMachineGuid)

COM application objects

When calling MSMQApplication.MachineNameOfMachineId, the MSMQApplication object does not have to be referenced explicitly. For example, the following lines of code both return the machine identifier of the local computer.

strMachineName = MachineNameOfMachineId(vbNullString)
strMachineName = MSMQApplication.MachineNameOfMachineId(vbNullString)

Equivalent API function properties

With API functions, the pathname of a computer retrieved using the PROPID_QM_PATHNAME and PROPID_QM_PATHNAME_DNS properties.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQApplication, SourceMachineGuid


MSMQApplication.MSMQVersionBuild

(Read-only, introduced in MSMQ 2.0.) The MSMQVersionBuild property provides the build version number of Message Queuing running on the computer.

Type: | Integer
Run time: | Read-only

applicationObject.MSMQVersionBuild

Parameters

applicationObject
Optional. The application object (MSMQApplication).

Remarks

The value of MSMQApplication.MSMQVersionBuild is a calculated value set by Message Queuing when the property is referenced. Message Queuing does not access the directory service to get this information.

To retrieve the major and minor version numbers of Message Queue, retrieve the MSMQApplication.MSMQVersionMajor and MSMQApplication.MSMQVersionMinor properties.

When you retrieve MSMQVersionBuild, you do not have to reference the MSMQApplication object explicitly. For example, the following lines of code both retrieve the build version number of Message Queuing.

intBuildVersion = MSMQVersionBuild
intBuildVersion = MSMQApplication.MSMQVersionBuild

Equivalent API function property

When using API functions, the build version number can be retrieved using the PROPID_PC_VERSION property.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQApplication, MSMQApplication.MSMQVersionMajor, MSMQApplication.MSMQVersionMinor, PROPID_PC_VERSION


MSMQApplication.MSMQVersionMajor

(Read-only, introduced in MSMQ 2.0.) The MSMQVersionMajor property provides the major version number of Message Queuing running on the computer.

Type: | Integer
Run time: | Read-only

applicationObject.MSMQVersionMajor

Parameters

applicationObject
Optional. The application object (MSMQApplication).

Remarks

The value of MSMQVersionMajor is a calculated value set by Message Queuing when the property is referenced. Message Queuing does not access the directory service to get this information.

To retrieve the minor and build version numbers of Message Queue, retrieve the MSMQApplication.MSMQVersionMinor and MSMQApplication.MSMQVersionBuild properties.

When you retrieve MSMQApplication.MSMQVersionMajor, you do not have to reference the MSMQApplication object explicitly. For example, the following lines of code both retrieve the major version number of Message Queuing.

intMajorVersion = MSMQVersionMajor
intMajorVersion = MSMQApplication.MSMQVersionMajor

Equivalent API function property

When using API functions, the major version number can be retrieved using the PROPID_PC_VERSION property.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQApplication, MSMQApplication.MSMQVersionBuild, MSMQApplication.MSMQVersionMinor, PROPID_PC_VERSION


MSMQApplication.MSMQVersionMinor

(Introduced in MSMQ 2.0.) The MSMQVersionMinor property provides the minor version number of Message Queuing running on the computer.

Type: | Integer
Run time: | Read-only

applicationObject.MSMQVersionMinor

Parameters

applicationObject
Optional. The application object (MSMQApplication).

Remarks

The value of MSMQVersionMinor is a calculated value set by Message Queuing when the property is referenced. Message Queuing does not access the directory service to get this information.

To retrieve the major and build version numbers of Message Queue, retrieve the MSMQApplication.MSMQVersionMajor and MSMQApplication.MSMQVersionBuild properties.

When you retrieve MSMQApplication.MSMQVersionMinor, you do not have to reference the MSMQApplication object explicitly. For example, the following lines of code both retrieve the minor version number of Message Queuing.

intMinorVersion = MSMQVersionMinor
intMinorVersion = MSMQApplication.MSMQVersionMinor

Equivalent API function property

When using API functions, the minor version number can be retrieved using the PROPID_PC_VERSION property.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQApplication, MSMQApplication.MSMQVersionBuild, MSMQApplication.MSMQVersionMajor, PROPID_PC_VERSION


MSMQApplication.RegisterCertificate

(Introduced in MSMQ 2.0.) The RegisterCertificate method of the MSMQApplication object registers an internal or external certificate in the directory service.

RegisterCertificate eRegisterFlags [,varExternalCertificate]

Parameters

eRegisterFlags
Specifies when the certificate is registered. Select one of the following:
MQCERT_REGISTER_ALWAYS
The default. Registers an internal or external certificate each time RegisterCertificate is called.

For internal certificates, a new certificate is created and registered, deleting any existing certificate.

For external certificates (see varExternalCertificate), this option must be set.

MQCERT_REGISTER_IF_NOT_EXIST
Registers an internal certificate only when none exist. This option cannot be used when registering external certificates.

If an internal certificate is found, the certificate is not registered. In this case, the call succeeds and the MQ_INFORMATION_INTERNAL_USER_CERT_EXITS information code is returned.

Checking for an existing certificate is done locally, without querying the directory service.

varExternalCertificate
Optional. Specifies the external certificate to be registered. This parameter is a byte array that contains a binary representation of an external certificate.

If this parameter is not used, an internal certificate is registered.

Return Values

For information on return codes, see Message Queuing Error and Information Codes.

Remarks

Message Queuing can register only external certificates placed in the Microsoft Internet Explorer personal certificate store. To obtain an external certificate, contact a trusted certification authority. For example, request a class 1 certificate from VeriSign Commercial Software Publishers using Microsoft® Internet Explorer. When you use Microsoft Internet Explorer to obtain the certificate, the certificate is automatically placed in the Microsoft Internet Explorer personal certificate store.

RegisterCertificate cannot be used when operating in a Windows 2000 Workgroup.

When you call MSMQApplication.RegisterCertificate, you do not have to reference the MSMQApplication object explicitly.

Equivalent API function

When using API functions, call MQRegisterCertificate to register the certificate.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MQRegisterCertificate. MSMQApplication


MSMQCoordinatedTransactionDispenser

The MSMQCoordinatedTransactionDispenser object is used to obtain an MS DTC transaction object. When the transaction is obtained, an MSMQTransaction object is returned that can be used to send or retrieve messages.

For information on all MS DTC transactions, see MS DTC External Transactions.

Methods

The following table lists the methods of the MSMQCoordinatedTransactionDispenser object.

Method | Description
BeginTransaction | Creates a new Message Queuing transaction object.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.


MSMQCoordinatedTransactionDispenser.BeginTransaction

The BeginTransaction method of the MSMQCoordinatedTransactionDispenser object creates a new Message Queuing transaction object. It returns an MSMQTransaction object that is used when sending and retrieving messages during the transaction.

Set transactionObject = transactiondispenserObject.BeginTransaction

Parameters

transactionObject
Transaction (MSMQTransaction) object that identifies the transaction.
transactiondispenserObject
Transaction dispenser (MSMQCoordinatedTransactionDispenser) object that creates the transaction.

Return Values

MSMQTransaction object that identifies the transaction.

Remarks

The MSMQTransaction object returned by BeginTransaction must be associated with all transactional messages sent or read within this transaction. For information on MS DTC external transaction, see MS DTC External Transactions.

For information on the transaction model used by Message Queuing and additional transaction types, see Message Queuing Transactions

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQCoordinatedTransactionDispenser, MSMQTransaction


MSMQDestination

(Introduced in MSMQ 3.0.) The MSMQDestination object represents one or more queues. The MSMQDestination object can be used to send messages, specify administration queues, and specify response queues.

Methods

The following table lists the methods of the MSMQDestination object.

Method | Description
Close | Closes the MSMQDestination object after sending messages.
Open | Opens the MSMQDestination for sending messages.

Properties

The following table lists the properties of the MSMQDestination object and gives their access, whether read-only or read/write; their data type; and a description.

Property | Description
ADsPath Access: Read/write Data type: String | Specifies the ADs path to a distribution list, public queue, or queue alias object stored in Active Directory.
FormatName Access: Read/write Data type: String | Specifies a distribution lists format name, multicast address format name, multiple-element format name, or a queue alias for sending messages.
IsOpen Access: Read-only Data type: Boolean | Provides an indication of whether or not the MSMQDestination object is open for sending messages.
PathName Access: Read/write Data type: String | Specifies a pathname for referencing the MSMQDestination object.

Requirements

Windows NT/2000 or later: Requires Whistler.
Windows 95/98/Me: Unsupported.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.


MSMQDestination.Close

(Introduced in MSMQ 3.0.) The Close method of the MSMQDestination object explicitly closes a MSMQDestination object that is open for sending messages.

destObject.Close

Parameters

destObject
Destination (MSMQDestination) object that represents a distribution list or multiple-element format name.

Remarks

MSMQDestination objects can be closed explicitly by calling Close or implicitly by releasing the object or reinitializing it.

Applications can determine if the MSMQDestination object is open for sending messages by inspecting the MSMQDestination.IsOpen property.

Requirements

Windows NT/2000 or later: Requires Whistler.
Windows 95/98/Me: Unsupported.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQDestination, MSMQDestination.IsOpen


MSMQDestination.Open

(Introduced in MSMQ 3.0.) The Open method of the MSMQDestination object explicitly opens an MSMQDestination object for sending messages.

destObject.Open

Parameters

destObject
Destination (MSMQDestination) object that represents a distribution list or multiple-element format name.

Remarks

The MSMQDestination object can be opened explicitly by calling Open or implicitly by referencing the MSMQDestination object when calling the MSMQMessage.Send method. In either case, the MSMQDestination object must be initialized before it can be used.

Before an MSMQDestination object can be opened to send message, the object must be initialized by setting one of the following properties.

  • MSMQDestination.ADsPath: Specifies the ADs path to a distribution lists, public queue, or queue alias object stored in Active Directory.
  • MSMQDestination.FormatName: Specifies a format name for referencing destination queues when using distribution list format names, multicast address format names, or multiple-element format names (note that a multiple-element format name may contain a single public or private format name).
  • MSMQDestination.PathName: Specifies a pathname for referencing the MSMQDestination object.

Applications can determine if the MSMQDestination object is open for sending messages by inspecting the MSMQDestination.IsOpen property.

Requirements

Windows NT/2000 or later: Requires Whistler.
Windows 95/98/Me: Unsupported.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQDestination, MSMQDestination.ADsPath, MSMQDestination.FormatName, MSMQDestination.IsOpen, MSMQDestination.PathName


MSMQDestination.ADsPath

(Introduced in MSMQ 3.0.) The ADsPath property of the MSMQDestination object specifies the ADs path to a distribution lists, public queue, or queue alias object stored in Active Directory.

Setting this property initializes the MSMQDestination object for sending messages.

Type: | String
Run time: | Read/write

destObject.ADsPath

Parameters

destObject
Destination (MSMQDestination) object that represents a distribution list or multiple-element format name.

Return Values

String that contains the ADs path to the distribution lists, public queue, or queue alias object stored in Active Directory.

Remarks

Setting ADsPath initializes the MSMQDestination object so that the object can be opened explicitly by calling MSMQDestination.Open or implicitly by referencing the object in MSMQMessage.Send.

Setting ADsPath also sets the MSMQDestination.FormatName property. Message Queuing generates the appropriate format name for the distribution list, public queue, or queue alias from the ADs path.

However, private queues cannot be explicitly referenced with ADsPath. To reference a private queue create an alias for the private queue and reference the alias, or use the MSMQDestination.FormatName property.

The ADsPath property is a string, and Message Queuing COM components ignore any characters that follow the first Null character in a string without returning an error.

Requirements

Windows NT/2000 or later: Requires Whistler.
Windows 95/98/Me: Unsupported.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQDestination, MSMQDestination.FormatName, MSMQMessage.Send


MSMQDestination.FormatName

(Introduced in MSMQ 3.0.) The FormatName property of the MSMQDestination object specifies a distribution list format name, multicast address format name, multiple-element format, or a queue alias (the queue alias specified by MSMQDestination.ADsPath) for sending messages.

Setting this property initializes the MSMQDestination object for sending messages.

Type: | String
Run time: | Read/write

destObject.FormatName

Parameters

destObject
Destination (MSMQDestination) object that represents a distribution list or multiple-element format name.

Return Values

String that contains a distribution list format name, multicast address format name, multiple-element format name, or the queue alias specified by MSMQDestination.ADsPath.

Remarks

The FormatName can be set by the sending application or by Message Queueing. The sending application must set this property when sending messages using multicast addresses or multiple-element format names. Message Queuing sets this property when the sending application specifies a distribution list, queue alias, or a single public queue using the MSMQDestination.ADsPath or MSMQDestination.PathName properties.

Setting MSMQDestination.FormatName initializes the MSMQDestination object so that the object can be opened explicitly by calling MSMQDestination.Open or implicitly by referencing the object in MSMQMessage.Send.

When you use FormatName to send a message to a multi-element format name, you create the multiple-element format name by concatenating any number of public format names, private format names, direct format names, multicast address format names, or distribution list format names.

The following example shows how to specify a three-element format name and send a message to the three queues. The format name strings in this example could contain any type of format name provided by Message Queuing.

dim dest as new MSMQDestination
dest.FormatName = strFormatName1 & "," & strFormatName2 & "," & strFormatName3
msg.Send dest

When FormatName is set by the sending application, the MSMQDestination.ADsPath and MSMQDestination.PathName properties are ignored.

The FormatName property is a string, and Message Queuing COM components ignore any characters that follow the first Null character in a string without returning an error.

Requirements

Windows NT/2000 or later: Requires Whistler.
Windows 95/98/Me: Unsupported.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQDestination, MSMQDestination.ADsPath, MSMQDestination.FormatName, MSMQDestination.Open, MSMQDestination.PathName, MSMQMessage.Send


MSMQDestination.IsOpen

(Introduced in MSMQ 3.0.)The IsOpen property of the MSMQDestination object provides an indicator of whether the object is or is not open for sending messages.

Type: | Boolean
Run time: | Read-only

destObject.IsOpen

Parameters

destObject
Destination (MSMQDestination) object that represents a distribution list or multiple-element format name.

Return Values

Boolean value that indicates that the MSMQDestination object is open for sending messages (TRUE) or that the object is not open for sending messages.

Remarks

The IsOpen property returns TRUE if the MSMQDestination is open for sending messages, regardless of how the object was opened. MSMQDestination objects can be opened explicitly by calling MSMQDestination.Open, or implicitly by referencing the object in MSMQMessage.Send.

Requirements

Windows NT/2000 or later: Requires Whistler.
Windows 95/98/Me: Unsupported.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQDestination, MSMQDestination.Open, MSMQMessage.Send


MSMQDestination.PathName

(Introduce in MSMQ 3.0.)The PathName property of the MSMQDestination object specifies the path name of a distribution lists, public queue, or queue alias object stored in Active Directory.

Setting this property initializes the MSMQDestination object for sending messages.

Type: | String
Run time: | Read/write

destObject.PathName

Parameters

destObject
Destination (MSMQDestination) object that represents a distribution list or multiple-element format name.

Return Values

String that contains the path name of the distribution lists, public queue, or queue alias object stored in Active Directory.

Remarks

Setting PathName initializes the MSMQDestination object so that the object can be opened explicitly by calling MSMQDestination.Open or implicitly by referencing the object in MSMQMessage.Send.

Setting PathName also sets the MSMQDestination.FormatName property. Message Queuing generates the appropriate format name from the queue path name.

Private queues cannot be explicitly referenced with PathName. To reference a private queue, create an alias for the private queue and reference the alias, or use MSMQDestination.FormatName.

The PathName property is a string, and Message Queuing COM components ignore any characters that follow the first Null character in a string without returning an error.

Requirements

Windows NT/2000 or later: Requires Whistler.
Windows 95/98/Me: Unsupported.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQDestination, MSMQDestination.FormatName, MSMQDestination.Open, MSMQMessage.Send


MSMQEvent

The MSMQEvent object can be used to implement a single event handler that can support multiple queues. The MSMQEvent object provides an arrived event that is fired when a message arrives at the queue and an arrived error event that is fired when an error occurs while the message is being delivered or, when asynchronously reading messages, when the message is not retrieved before a time-out timer expires.

Events

The following table lists the events of the MSMQEvent object.

Event | Description
Arrived | Fired when a message is found in the queue.
ArrivedError | Fired when an error is generated by Message Queuing.

Each instance of the MSMQEvent object can be associated with any number of queues. This allows receiving applications to have one generic event handler that can treat all common tasks identically, using the different queue handles passed to the event handler for special-case situations.

The formal parameter passed to the MSMQEvent_Arrived event is of type Object (this is required because event firing is implemented in terms of IDispatch), which means that the event handler uses COM late-binding by default instead of early-binding. However, early-binding is more efficient, and the applications may choose to assign the formal parameter to a local variable of type MSMQQueue to regain the benefits of early-binding.

The MSMQEvent object is implemented in terms of callbacks, and is limited to 64 callbacks per process. Internally, Message Queuing uses the WaitForMultipleObjects function which is limited to 64 objects per process.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQQueue


MSMQEvent.Arrived

The Arrived event of the MSMQEvent object is fired when MSMQQueue.EnableNotification has been called and a message is found at the appropriate location in the queue.

eventObject_Arrived( _
  byval Queue as Object, _
  byval Cursor as Long _
)

Parameters

eventObject
Instance of event (MSMQEvent) object used for the event handler.
Queue
Queue (MSMQQueue) object that represents an open instance of the queue where the message arrived.
Cursor
Indicates the value of the Cursor argument in the call to MSMQQueue.EnableNotification that triggered the event. Its values may be MQMSG_FIRST (default value of EnableNotification), MQMSG_CURRENT, or MQMSG_NEXT. Refer to this value when re-enabling notification within your event handler

Remarks

The Arrived event is fired by an instance of the MSMQEvent object. Every queue that has called MSMQQueue.EnableNotification triggers an instance of the MSMQEvent object when a message arrives at the specific cursor location in the queue (this includes existing messages in the queue when EnableNotification is first called).

MSMQQueue.EnableNotification can be called with its Cursor parameter set to MQMSG_FIRST (the default value) to signal a notification whenever there is a message in the queue, or it can be called with the Cursor parameter set to a combination of MQMSG_CURRENT and MQMSG_NEXT values to traverse the queue. Regardless of the Cursor parameter setting, MSMQQueue.EnableNotification must be called to start notification and explicitly reset notification after each Arrived event is fired.

There is no association between an Arrived event and a specific message. The arrived event only means that some message arrived at a specific location in the queue.

Although an Arrived event is fired for a message, there is no guarantee that the message that triggered the event will still be there when the event handler tries to read the message. Queues are dynamic, and another application may have already removed the message that triggered the Arrived event.

For information on | See
How cursors behave | Navigating with Cursors

For an example of | See
Writing an arrived event handler that navigates a queue | Reading Messages Synchronously

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQQueue.EnableNotification, MSMQEvent, MSMQQueue


MSMQEvent.ArrivedError

The ArrivedError event of the MSMQEvent object is fired when MSMQQueue.EnableNotification has been called and an error is generated.

eventObject ArrivedError( _
  byval Queue as Object, _
  byval ErrorCode as Long, _
  byval Cursor as Long _
)

Parameters

eventObject
Instance of event (MSMQEvent) object used for the event handler.
Queue
Queue (MSMQQueue) object that represents an open instance of the queue where the message arrived.
ErrorCode
Error code returned by MQReceiveMessage.
Cursor
Indicates the value of the Cursor argument in the call to MSMQQueue.EnableNotification that triggered the event. Its values may be MQMSG_FIRST (default value of EnableNotification), MQMSG_CURRENT, or MQMSG_NEXT.

Remarks

An ArrivedError event can be triggered by the message's time-out timer expiring or by an error occurring while the queue is receiving the message. The message's time-out timer can be used when the application will wait a specific amount of time to receive its messages.

This event applies only to messages failing to arrive at the queue; it is not associated with any errors generated while the application is trying to read messages in the queue.

For an example of | See
Writing an arrived error event handler | Reading Messages Synchronously

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.


MSMQMessage

The MSMQMessage object provides access to the properties needed to define a messages, plus the methods needed to send the message to its destination queue.

Note The Send method listed below is used for both transactional and non-transactional messages (for information on its use in transactions, see Message Queuing Transactions).

The body of a message can be a string, an array of bytes, any numeric date or currency type that a Variant can contain, or any persistent COM object that supports IDispatch and IPersist (IPersistStream, IPersistStreamInit, or IPersistStorage).

Methods

The following table lists the methods of the MSMQMessage object.

Method | Description
AttachCurrentSecurityContext | Used when sending authenticated messages. This method retrieves security context information from a specific certificate.
Send | Sends the message to the specified queue.

Properties

The following table lists the properties of the MSMQMessage object and gives their access, whether read-only or read/write; their data type; and a description.

Property | Description
Ack Access: Read/write Data type: Long | Specifies the type of acknowledgment messages that Message Queuing returns to the administration queue.
AdminQueueInfo Access: Read/write Data type: MSMQQueueInfo | Specifies the queue used for acknowledgment messages.
AppSpecific Access: Read/write Data type: Long | Specifies application-generated information for filtering messages.
ArrivedTime Access: Read-only Data type: Date Variant | Provides the time when the message arrived at the queue.
AuthenticationProviderName Access: Read/write Data type: String | (Introduced in MSMQ 2.0.) Specifies the name of the provider used to authenticate the message.
AuthenticationProviderType Access: Read/write Data type: Long | (Introduced in MSMQ 2.0.) Specifies the type of provider used to authenticate the message.
AuthLevel Access: Read/write Data type: Long | Specifies whether the message should be authenticated when received by the queue.
Body Access: Read/write Data type: Variant | Specifies the body of the message.
BodyLength Access: Read-only Data type: Long | Provides the size of the message body.
Class Access: Read-only Data type: Long | (Superseded by MsgClass.) Provides the type of message.
CompoundMessage Access: Read-only Data type: Variant (array of bytes) | (Introduced in MSMQ 3.0) Provides the SOAP attaments associated with the message.
ConnectorTypeGuid Access: Read/write Data type: String (GUID format) | (Introduced in MSMQ 2.0.) Indicates the some properties typically set by Message Queuing were set by the sending application.
CorrelationId Access: Read/write Data type: Variant (array of bytes) | Specifies the correlation identifier of the message.
Delivery Access: Read/write Data type: Long | Specifies how the message is delivered (optimize throughput or recoverability).
DestinationQueueInfo Access: Read-only Data type: MSMQQueueInfo | Provides the queue where the message resides (the queue to which the message is sent).
DestinationSymmetricKey Access: Read/write Data type: Variant (array of bytes) | (Introduced in MSMQ 2.0.) Specifies the symmetric key used to encrypt the message.
EncryptAlgorithm Access: Read/write Data type: Long | Specifies the algorithm used to encrypt the message body.
Extension Access: Read/write Data type: Variant (array of bytes) | (Introduced in MSMQ 2.0.)Specifies additional application-defined information.
HashAlgorithm Access: Read/write Data type: Long | Specifies the hash algorithm used when authenticating messages.
Id Access: Read-only Data type: Variant (array of bytes) | Provides the MSMQ-generated identifier for the message.
IsAuthenticated Access: Read-only Data type: Short | Indicates whether the message was authenticated by MSMQ.
IsFirstInTransaction Access: Read-only Data type: Short | (Introduced in MSMQ 2.0.) Indicates whether the message was the first message in a transaction.
IsLastInTransaction Access: Read-only Data type: Short | (Introduced in MSMQ 2.0.) Indicates whether the message was the last message in a transaction.
Journal Access: Read/write Data type: Long | Specifies whether a copy of the message is stored in the computer journal.
Label Access: Read/write Data type: String | Specifies an application-defined label for the message.
LookupId Access: Read-only Data type: String | (Introduced in MSMQ 3.0) Provides the lookup identifier of the message.
MaxTimeToReachQueue Access: Read/write Data type: Long | Specifies how long the message has to reach the queue.
MaxTimeToReceive Access: Read/write Data type: Long | Specifies how long the receiving application has to remove the message from the queue.
MsgClass Access: Read/write Data type: Long | (Introduced in MSMQ 2.0.) Specifies the type of message.
Priority Access: Read/write Data type: Long | Specifies the priority of the message (where it is placed in the queue).
PrivLevel Access: Read/write Data type: Long | Specifies whether the message is private (encrypted).
ReceivedAuthenticationLevel Access: Read only Data type: Short | (Introduced in MSMQ 2.0.) Provides the authentication level specified by the sending application.
ResponseQueueInfo Access: Read/write Data type: MSMQQueueInfo | Specifies the queue for sending responses to the message.
SenderCertificate Access: Read/write Data type: Variant (array of bytes) | Specifies the sender certificate.
SenderId Access: Read/write Data type: Variant (array of bytes) | Identifies the user who sent the message.
SenderIdType Access: Read/write Data type: Long | Specifies the type of sender identifier found in SenderId.
SenderVersion | Reserved for future use.
SentTime Access: Read-only Data type: Date Variant | provides the date and time that the message was sent.
Signature Access: Read/write Data type: Variant (array of bytes) | (Introduced in MSMQ 2.0.) Specifies the digital signature used to sign the message.
SOAPEnvelope Access: Read-only Data type: Variant (array of bytes) | (Introduced in MSMQ 3.0) Provides the SOAP envelope (not including binary attachments) attached to the message.
SourceMachineGuid Access: Read-only Data type: String (GUID format) | Provides the identifier of the computer where the message originated.
Trace Access: Read/write Data type: Long | Specifies whether the route of the message is traced.
TransactionId Access: Read-only Data type: Variant (array of bytes) | (Introduced in MSMQ 2.0.) Provides the transaction identifier for the message.
TransactionStatusQueueInfo Access: Read-only Data type: MSMQQueueInfo | (Introduced in MSMQ 2.0.) Provides the transaction status queue.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.


MSMQMessage.Send

The Send method of the MSMQMessage object sends a message to one or more destination queues.

messageObject.Send( _
  DestinationQueue _
  [, Transaction] _
)

Parameters

messageObject
Message (MSMQMessage) object to be sent.
DestinationQueue
Reference to an MSMQDestination or MSMQQueueInfo object.
Transaction
Optional. An MSMQTransaction object or one of the following constants:
MQ_NO_TRANSACTION
Specifies that the call is not part of a transaction.
MQ_MTS_TRANSACTION
Default. Specifies that the call is part of the current MTS (Microsoft Transaction Server) transaction.
MQ_SINGLE_MESSAGE
Sends a single message as a transaction.
MQ_XA_TRANSACTION
Specifies that the call is part of an externally coordinated, XA-compliant transaction.

Remarks

Each Message Queuing message can have no more than 4 MB of data.

To get the handle of a queue, use the MSMQQueue.Handle property of the queue.

To save a copy of the message in a computer journal, set MSMQMessage.Journal to MQMSG_JOURNAL.

Messages that do not reach their destination can be sent to a dead-letter queue by setting the message's MSMQMessage.Journal property to MQMSG_DEADLETTER.

When sending messages using Send, you cannot specify the type of message body included in the message. Message Queuing will determine the body type and set the message body type property for you (the body type property of the message can be accessed only with Message Queuing functions).

Sending Message to Multiple Destinations

To send message to multiple destinations (introduced in MSMQ 3.0), the DestinationQueue parameter must reference an MSMQDestination object. For information on the different ways messages can be sent to multiple destination, see Multiple-Destination Messaging.

Sending Messages Within a Transaction

The Transaction parameter can be set to an MSMQTransaction object or one of the constants described above. Transaction objects cannot be reused after you commit to or abort the transaction. In addition, if you release the transaction object without calling Commit or Abort, the transaction is automatically aborted.

Responding to Messages

The sending application can request a response by providing the format name of a response queue when it sends the message. The format name is specified in the MSMQMessage.ResponseQueueInfo property when the message is sent. For information on how to respond, see Response Messages.

For information on | See
Dead-letter queues | Dead-letter queues
Message Queuing transaction support, including types of transactions | Message Queuing Transactions.
How Message Queuing sets the body type of a message | Message Body Types
Sending messages using Message Queuing functions | MQSendMessage

For an example of | See
Sending a message that request a response from the receiving application | Requesting Response Messages

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQMessage.Body, MSMQMessage.Journal, MSMQMessage.Label, MSMQMessage, MSMQQueue.Close, MSMQQueue.Handle, MSMQQueue, MSMQQueueInfo.Create, MSMQQueueInfo.Open, MSMQQueueInfo.PathName, MSMQQueueInfo, MSMQTransaction


MSMQMessage.Ack

The Ack property specifies the type of acknowledgment messages that Message Queuing posts (in the administration queue) and when acknowledgments are returned to the sending application.

Type: | Long
Run time: | Read/write

messageObject.Ack

Parameters

messageObject
Message (MSMQMessage) object that defines the message.

Property Values

The Ack property can have any one of the following values:

MQMSG_ACKNOWLEDGMENT_FULL_REACH_QUEUE
Posts positive and negative acknowledgments depending on whether the message reaches the queue. This can happen when the time-to-reach-queue timer expires, or when a message cannot be authenticated.
MQMSG_ACKNOWLEDGMENT_FULL_RECEIVE
Posts a positive or negative acknowledgment depending on whether the message is retrieved from the queue before its time-to-be-received timer expires.
MQMSG_ACKNOWLEDGMENT_NACK_REACH_QUEUE
Posts a negative acknowledgment when the message cannot reach the queue. This can happen when the time-to-reach-queue timer expires or when a message cannot be authenticated
MQMSG_ACKNOWLEDGMENT_NACK_RECEIVE
Posts a negative acknowledgment when an error occurs and the message cannot be retrieved from the queue before its time-to-be-received timer expires.
MQMSG_ACKNOWLEDGMENT_NONE
The default. No acknowledgment messages (positive or negative) are posted.

Remarks

To receive a positive acknowledgment message when a message reaches its destination and when the message is retrieved, the following two full-acknowledgment settings must be combined using the OR operator: MQMSG_FULL_REACH_QUEUE and MQMSG_FULL_RECEIVE.

Positive and negative acknowledgments are MSMQ-generated messages that are sent to an administration queue specified by the message. For an explanation of administration queues, see Administration Queues.

Acknowledgment messages contain some of the information found in the original message; however, each acknowledgment message has its own message identifier and class. The message identifier, MSMQMessage.Id, identifies the acknowledgment in the same way it identifies each message sent by an Message Queuing application. The message class, MSMQMessage.MsgClass, identifies the type of acknowledgment posted. Both these properties are set by Message Queuing when it creates the acknowledgment message. For information on acknowledgment messages, see Acknowledgment Messages.

To request acknowledgment messages, the sending application must set Ack and MSMQMessage.AdminQueueInfo when sending messages.

To find out if acknowledgment messages were requested, the receiving application can examine Ack and MSMQMessage.AdminQueueInfo when it reads the messages in the queue.

Equivalent API Function Property

When using API function calls, the acknowledgment level of the message can be set and retrieved using the PROPID_M_ACKNOWLEDGE message property.

Example Code

The following example code is included in the Platform SDK.

For an example of | See
Sending messages that request acknowledgment messages | Requesting Acknowledgment Messages

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQMessage.AdminQueueInfo, MSMQMessage.MsgClass, MSMQMessage.Id, MSMQMessage.MaxTimeToReachQueue, MSMQMessage.MaxTimeToReceive, PROPID_M_ACKNOWLEDGE


MSMQMessage.AdminDestination

The AdminDestination property of the MSMQMessage object specifies a set of queues used for returned acknowledgment messages.

Type: | MSMQDestination
Run time: | Read/write

set messageObject.AdminDestination = destinationObject

Parameters

messageObject
Message (MSMQMessage) object that represents the message.
destinationObject
Destination (MSMQDestination) object that represents a distribution list or multiple-element format name.

Property Values

MSMQDestination object.

Remarks

The AdminDestination property can be set by the sending application when requesting acknowledgment messages from Message Queuing or a connector application (connector applications return acknowledgment messages for messages sent to foreign queues). Acknowledgment messages can indicate whether the original messages reached their destinations, whether the messages were retrieved from their destinations, or a combination of both.

Administration queues can be any non-transactional queue.

Sets of administration queues can be specified using the following format names.

  • Distribution list format names are used to reference administration queues based on a public distribution list that is published in Active Directory. For information the syntax of distribution list format names, see Distribution List Format Names.
  • Multicast address format names are used to reference administration queues that are associated with a specific multicast address. For information the syntax of multicast address format names, see Multicast Address Format Names.
  • Multiple-element format names are used to reference administration queues based on a private list of destination queues. For information the syntax of multiple element format names, see Multiple-Element Format Names.

Equivalent API function property

When using API functions, the administration queue set can be set and retrieved using the PROPID_M_ADMIN_FORMAT_NAME property.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQDestination, MSMQMessage, PROPID_M_ADMIN_FORMAT_NAME


MSMQMessage.AdminQueueInfo

The AdminQueueInfo property of the MSMQMessage object specifies the queue used for MSMQ-generated acknowledgment messages. This object is passed to the queue manager on the target machine.

Type: | MSMQQueueInfo
Run time: | Read/write

set messageObject.AdminQueueInfo = queueinfoObject

Parameters

messageObject
Message (MSMQMessage) object that represents the message.
queueinfoObject
Queue information (MSMQQueueInfo) object that represents the administration queue.

Property Values

MSMQQueueInfo object.

Remarks

The administration queue can be any non-transactional queue. The acknowledgment messages sent to the queue can indicate whether or not the original message reached its destination queue or whether or not it was removed from the queue. Acknowledgment messages are generated and sent by MSMQ. For information on acknowledgment messages and administration queues, see Acknowledgment Messages and Administration Queues.

To obtain an MSMQQueueInfo object for the administration queue, the sending application must do one of the following:

  • Create a new queue.
  • Call MSMQQuery.LookupQueue to locate an existing queue.
  • Specify the pathname of a known queue and call MSMQQueueInfo.Refresh.

To request acknowledgment messages, the sending application must set MSMQMessage.Ack and AdminQueueInfo when sending messages.

To find out if acknowledgment messages were requested, the receiving application can examine MSMQMessage.Ack and AdminQueueInfo when it reads the messages in the queue.

You can also set and retrieve the administration queue when using Message Queuing function calls.

For information on | See
How administration queues are used | Administration Queues
What is in an acknowledgment message | Acknowledgment Messages
Setting and retrieving the administration queue using Message Queuing function calls | PROPID_M_ADMIN_QUEUE

For an example of | See
Specifying the administration queue when requesting acknowledgment messages | Requesting Acknowledgment Messages

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQMessage, MSMQMessage.Ack, MSMQQuery.LookupQueue, MSMQQueueInfo, MSMQQueueInfo.Refresh, PROPID_M_ADMIN_QUEUE


MSMQMessage.AppSpecific

The AppSpecific property of the MSMQMessage object specifies application-generated information such as single integer values or application defined message classes.

Type: | Long
Run time: | Read/write

messageObject.AppSpecific

Parameters

messageObject
Message (MSMQMessage) object that defines the message.

Remarks

The AppSpecific property can be used to identify a single message or set of messages. For example, the receiving application can search a queue for all messages that have the same application specific information.

If the sending application sets AppSpecific to a negative value, receiving applications that are using the API calls to read messages will read these values as Unsigned Long values.

Another message property that can be used to pass application-defined information is MSMQMessage.CorrelationId.

Equivalent API Function Property

When using API function calls, the application specific information of the message can be set and retieved using the PROPID_M_APPSPECIFIC message property.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQMessage, MSMQMessage.CorrelationId, PROPID_M_APPSPECIFIC


MSMQMessage.ArrivedTime

Read-only. The ArrivedTime property of the MSMQMessage object indicates when the message arrived at the queue.

Type: | Date Variant
Run time: | Read-only

messageObject.ArrivedTime

Parameters

messageObject
Message (MSMQMessage) object that defines the message.

Return Values

Date and time when message arrived.

Remarks

The returned value for this property can be manipulated using standard Microsoft® Visual Basic® date and time functions such as Date$ and Time$. For descriptions of Visual Basic functions, see the Visual Basic documentation.

When you read messages from a queue journal, the ArrivedTime value indicates when the original message reached its destination queue, not when the original message was removed from that queue and a copy placed in the queue journal.

When reading messages from a computer journal, dead-letter queue, or transactional dead-letter queue, ArrivedTime indicates when the message reached the system queue where the application is reading the message. In these cases, the original message never reached its destination.

When ArrivedTime is displayed, Visual Basic automatically converts the parameter value to the local system time and system date.

You can also retrieve the arrival time of a message when using Message Queuing function calls.

For information on | See
Retrieving the arrived time using Message Queuing function calls | PROPID_M_ARRIVEDTIME

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQMessage, PROPID_M_ARRIVEDTIME


MSMQMessage.AuthLevel

The AuthLevel property of the MSMQMessage object specifies if the message needs to be authenticated.

Type: | Long
Run time: | Read/write

messageObject.AuthLevel

Parameters

messageObject
Message (MSMQMessage) object that defines the queue.

Property Values

Set AuthLevel to one of the following values:

MQMSG_AUTH_LEVEL_NONE
The default. The message is not signed. Message Queuing does not need to authenticate the message when it reaches the queue.
MQMSG_AUTH_LEVEL_ALWAYS
Message Queuing run time signs the message using a one or more types of digital signatures.

Non-HTTP messages are signed based on the value of the sending authentication registry key. If the registry key is not set, an MQMSG_AUTH_LEVEL_SIG10 signature is used. (For information on the sending authentication registry key, see Digital Signature Registry Keys.

HTTP messages are signed with an XML digital signature.

MQMSG_AUTH_LEVEL_MSMQ10
Obsolete. This value is superseded by MQMSG_AUTH_LEVEL_SIG10.
MQMSG_AUTH_LEVEL_MSMQ20
Obsolete. This value is superseded by MQMSG_AUTH_LEVEL_SIG20.
MQMSG_AUTH_LEVEL_SIG10
Introduced in MSMQ 3.0. For non-HTTP messages, the Message Queuing run time ignores the sending authentication registry key and signs the message using only an MQMSG_AUTH_LEVEL_SIG10 signature.

For HTTP messages, the message is signed using an XML digital signature.

MQMSG_AUTH_LEVEL_SIG20
Introduced in MSMQ 3.0. For non-HTTP messages, the Message Queuing run time ignores the sending authentication registry key and signs the message using an MQMSG_AUTH_LEVEL_SIG20 signature. (This setting cannot be used when sending messages to multiple destinations using distribution lists, multicast addresses, or multiple-element format names.)

For HTTP messages, the message is signed using an XML digital signature.

MQMSG_AUTH_LEVEL_SIG30
Introduced in MSMQ 3.0. For non-HTTP messages, the Message Queuing run time ignores the sending authentication registry key and signs the message using an MQMSG_AUTH_LEVEL_SIG30 or MQMSG_AUTH_LEVEL_SIG20 signature.

MQMSG_AUTH_LEVEL_SIG30 signatures are used if the message is sent to using distribution lists, multicast addresses, or multiple-element format names.

MQMSG_AUTH_LEVEL_SIG20 signatures are used if the message is sent without using distribution lists, multicast addresses or multiple-element format names.

For HTTP messages, the message is signed using an XML digital signature.

Remarks

The AuthLevel property is only used by the sending application to request authentication. When authentication is requested, Message Queuing creates an XML signature for HTTP message and one or more of three non-XML signatures for non-HTTP messages. The created digital signature is used to digitally sign the message when it is sent and authenticate the message when it reaches the target computer where the destination queue resides.

For information on how Message Queuing authenticates messages, see Message Authentication.

Authentication can be enforced at the queue level by setting the MSMQQueueInfo.Authenticate property of the queue. When sending messages to queues that only accept authenticated messages, the message will be rejected when it reaches the queue if the authentication level of a message is set to MQMSG_AUTH_LEVEL_NONE.

Message Queuing provides different signatures for HTTP and non-HTTP messages. Non-HTTP signatures include the following (for a complete description, including the message properties used to create these signatures, see Digital Signatures):

  • MQMSG_AUTH_LEVEL_SIG10
  • MQMSG_AUTH_LEVEL_SIG20 (introduced in MSMQ 2.0)
  • MQMSG_AUTH_LEVEL_SIG30 (introduced in MSMQ 3.0)

XML signatures (introduced in MSMQ 3.0) are used whenever an HTTP message requests authentication.

The following authentication registry keys can be used to specify what type of signature is used for non-HTTP messages. When MQMSG_AUTH_LEVEL_ALWAYS is specified, the Message Queuing run-time creates digital signatures based on the value of the sending authentication registry key.

hklm\software\microsoft\msmq\parameters\security\SendMsgAuthn
hklm\software\microsoft\msmq\parameters\security\RcvOnlyEnhMsgAuthn

For details on setting these registry key, see Digital Signature Registry Keys.

The receiving application can check to see if authentication was requested by retrieving one of the following read-only message properties: MSMQMessage.IsAuthenticated and MSMQMessage.ReceivedAuthenticationLevel (introduced in MSMQ 2.0).

Equivalent API function property

When using API functions, authentication can requested using the PROPID_M_AUTH_LEVEL property.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQMessage, MSMQMessage.IsAuthenticated, MSMQMessage.ReceivedAuthenticationLevel, MSMQQueueInfo.Authenticate, PROPID_M_AUTH_LEVEL


MSMQMessage.AttachCurrentSecurityContext

The AttachCurrentSecurityContext method of the MSMQMessage object retrieves the security information needed to attach a certificate to a message when requesting authentication.

This method is superseded by MSMQMessage.AttachCurrentSecurityContext2.

messageObject.AttachCurrentSecurityContext

Parameters

messageObject
Message (MSMQMessage) object that defines the message.

Remarks

Use this method when you are sending a large number of messages using the same certificate or when you are impersonating a user. AttachCurrentSecurityContext creates a security context based on the data that is in MSMQMessage.SenderCertificate. If SenderCertificate is not set before calling AttachCurrentSecurityContext, then the Message Queuing internal certificate for the user is used as the security context.

When you are sending authenticated messages, this method retrieves the information Message Queuing run-time needs to attach a certificate to the messages. This provides an easier, more efficient way to send a large number of messages that require authentication using the same certificate.

When using more than one certificate, the sending application must call AttachSecurityContext for each certificate it will use.

For information on | See
What it means to authenticate a message: message integrity an sender authentication | Message Authentication
The process used to authenticate a messages | How Message Queuing Authenticates Messages

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQMessage, MSMQMessage.SenderCertificate


MSMQMessage.AttachCurrentSecurityContext2

(Introduced in Windows 2000 Service Pack 2) The AttachCurrentSecurityContext2 method of the MSMQMessage object retrieves the security information needed to attach a certificate to a message when requesting authentication.

MSMQMessage.AttachCurrentSecurityContext2 supersedes MSMQMessage.AttachCurrentSecurityContext.

messageObject.AttachCurrentSecurityContext2

Parameters

messageObject
Message (MSMQMessage) object that defines the message.

Remarks

The AttachCurrentSecurityContext2 method is used whenever possible to send large numbers of messages using the same certificate or when impersonating another user.

AttachCurrentSecurityContext2 creates a security context based on the data that is in MSMQMessage.SenderCertificate property. If MSMQMessage.SenderCertificate is not set before calling AttachCurrentSecurityContext2, then the Message Queuing internal certificate for the user is used as the security context.

When you are sending authenticated messages, this method retrieves the information Message Queuing run-time needs to attach a certificate to the messages. This provides an easier, more efficient way to send a large number of messages that require authentication using the same certificate.

If, however, the sending application is using more than one certificate, it must call MSMQMessage.AttachCurrentSecurityContext2 for each certificate it will use.

When impersonating another user, the sending application must load the hive of the impersonated user and call MSMQMessage.AttachCurrentSecurityContext2 before it sends the messages of the impersonated user. Internally, MSMQMessage.AttachCurrentSecurityContext2 uses the MQGetSecurityContextEx function to access the certificate of the impersonated user. Once the security information for the impersonated user is retrieved, the sending application can revert to the original user and later use the impersonated security context information to send another message without needing to impersonate the user again.

The hive of the impersonated user can be loaded programmatically (for code example see Microsoft Knowledge Base Article Q168877) or manually using a tool such as RegEdit32.

MSMQMessage.AttachCurrentSecurityContext2 and MSMQMessage.AttachCurrentSecurityContext

The MSMQMessage.AttachCurrentSecurityContext2 method supersedes MSMQMessage.AttachCurrentSecurityContext method. Both functions provide the same functionality, however MSMQMessage.AttachCurrentSecurityContext2 provides improved security.

Equivalent API Function

When using API Functions, you can retrieve security context information by calling MQGetSecurityContextEx.

For information on | See
What it means to authenticate a message: message integrity an sender authentication | Message Authentication
The process used to authenticate a messages | How Message Queuing Authenticates Messages

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQMessage, MSMQMessage.SenderCertificate, MQGetSecurityContextEx


MSMQMessage.AuthenticationProviderName

(Introduced in MSMQ 2.0.) The AuthenticationProviderName property of the MSMQMessage object specifies the name of the cryptographic provider used to generate the digital signature of the message.

Type: | String
Run time: | Read/write

messageObject.AuthenticationProviderName

Parameters

messageObject
Message (MSMQMessage) object that represents the message.

Property Values

String of the provider name (the default is "Microsoft Base Cryptographic Provider, Ver. 1.0").

Remarks

The AuthenticationProviderName property is typically used when working with foreign queues. In these cases, the name and type (MSMQMessage.AuthenticationProviderType) of the cryptographic provider are required to validate the digital signature of messages sent to or received from a foreign queue.

When sending messages, always set AuthenticationProviderName and MSMQMessage.ConnectorTypeGuid together. AuthenticationProviderName is ignored if MSMQMessage.ConnectorTypeGuid is not also set when the message is sent.

The AuthenticationProviderName property is a string, and Message Queuing COM components ignore any characters that follow the first null character in a string without returning an error.

For information on | See
Setting and retrieving the provider name using Message Queuing function calls | PROPID_M_PROV_NAME

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQMessage, PROPID_M_PROV_NAME, MSMQMessage.AuthenticationProviderType


MSMQMessage.AuthenticationProviderType

(Introduce in MSMQ 2.0)) The AuthenticationProviderType property of the MSMQMessage object specifies the type of cryptographic provider used to generate the digital signature of the message.

Type: | Long
Run time: | Read/write

messageObject.AuthenticationProviderName

Parameters

messageObject
Message (MSMQMessage) object that represents the message.

Property Values

Possible values provided in wincrypt.h. (The default is PROV_RSA_FULL.)

Remarks

The AuthenticationProviderType property is typically used when you are working with foreign queues. The name (MSMQMessage.AuthenticationProviderName) and type of the cryptographic provider are required to validate the digital signature of messages sent to a foreign queue or messages passed to Message Queuing from a foreign queue.

When sending messages, always set AutheticationProviderType and MSMQMessage.ConnectorTypeGuid together. AuthenticationProviderType is ignored if MSMQMessage.ConnectorTypeGuid is not also set when the message is sent.

Equivalent API function property

When using API functions, the authentication provider type of the message can be set and retrieved using the PROPID_M_PROV_TYPE property.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQMessage, PROPID_M_PROV_TYPE, MSMQMessage.AuthenticationProviderName


MSMQMessage.Body

The Body property of the MSMQMessage object specifies the contents of the message.

Type: | Variant
Run time: | Read/write

messageObject.Body

Parameters

messageObject
Message (MSMQMessage) object that defines message.

Property Values

Any intrinsic Variant, including string, date, currency, number, as well as an array of bytes or any persistent COM object that supports IDispatch and IPersist (IPersistStream/IPersistStorage or IPersistStorage).

Remarks

Each Message Queuing message can have no more than 4 MB of data.

When sending messages using COM components, the sending application does not indicate the type of information (string, array of bytes, numeric types, currency, date, or COM object) that is stored in the message body. Message Queuing determines the body type from the true type of the Variant assigned to the MSMQMessage.Body property.

When assigning an object to the Body property, the Visual Basic Set operator should not be used. The correct syntax to use is msg.Body = <object reference>. This syntax should be used because the actual object contents are copied into the message buffer, rather than just a reference to the object.

When peeking at or retrieving messages, the receiving application should determine what type of information is in the message body before processing the message body. This can be done using the standard Visual Basic If..Then..Else function with the following conditional functions: TypeOf and TypeName. The TypeName function can be used to find out if the message in the queue is a string, array of bytes, numeric type, currency, or date. If it is not one of these, TypeOf can be used to see which OLE interface the object supports.

Message Queuing COM components ignore any characters that follow the first null character in a string (including in the body of a message) without returning an error.

Equivalent API function property

When using API functions, the body of the message can be set and retrieved using the PROPID_M_BODY property.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQMessage, PROPID_M_BODY


MSMQMessage.BodyLength

(Read-only.) The BodyLength property of the MSMQMessage object provides the length of the message body in bytes.

Type: | Long
Run time: | Read-only

messageObject.BodyLength

Parameters

messageObject
Message (MSMQMessage) object that represents the message.

Return Values

Length (in bytes) of the message.

Remarks

Each Message Queuing message can have no more than 4 MB of data.

MSMQMessage.BodyLength can be used by the sending application or receiving application.

Sending applications can use MSMQMessage.BodyLength to find the size of the message body as soon as MSMQMessage.Body is set, including before and after the message is sent.

Receiving applications can use BodyLength to find the size of a message before or after retrieving the message body.

Equivalent API function property

When using API functions, the size of body of the message can be retrieved using the PROPID_M_BODY_SIZE property.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQMessage, MSMQMessage.Body, PROPID_M_BODY_SIZE


MSMQMessage.Class

This property is being superceded by MSMQMessage.MsgClass (introduced in MSMQ 2.0).

The Class property of the MSMQMessage object provides the message type set by Message Queuing. A message can be a normal Message Queuing message, a positive or negative (arrival and read) acknowledgment message, or a report message.

Type: | Long
Run time: | Read-only

messageObject.Class

Parameters

messageObject
Message (MSMQMessage) object that represents the message.

Return Values

Message Queuing sets the Class property to one of the following values:

Normal messages (all messages created by your application):

MQMSG_CLASS_NORMAL
A normal Message Queuing message.

Positive acknowledgment messages (generated by MSMQ):

MQMSG_CLASS_ACK_REACH_QUEUE
The original message reached its destination queue.
MQMSG_CLASS_ACK_RECEIVE
The original message was retrieved by the receiving application.

Negative arrival acknowledgment messages (generated by MSMQ):

MQMSG_CLASS_NACK_ACCESS_DENIED
The sending application does not have access rights to the destination queue.
MQMSG_CLASS_NACK_BAD_DST_Q
The destination queue is not available to the sending application.
MQMSG_CLASS_NACK_BAD_ENCRYPTION
The destination queue manager could not decrypt a private (encrypted) message (see MSMQMessage.PrivLevel).
MQMSG_CLASS_NACK_BAD_SIGNATURE
Message Queuing could not authenticate the original message. The original message's digital signature is not valid.
MQMSG_CLASS_NACK_COULD_NOT_ENCRYPT
The source queue manager could not encrypt a private message (see MSMQMessage.PrivLevel).
MQMSG_CLASS_NACK_HOP_COUNT_EXCEEDED
The original message's hop count is exceeded.
MQMSG_CLASS_NACK_Q_EXCEED_QUOTA
The original message's destination queue is full.
MQMSG_CLASS_NACK_REACH_QUEUE_TIMEOUT
Either the time-to-reach-queue or time-to-be-received timer expired before the original message reached the destination queue.

For transactional messages, this is an in-doubt negative acknowledgment. For example, the local queue manager sets this class when the message timer expires, even though a positive confirmation may be in route from the remote queue manager.

MQMSG_CLASS_NACK_PURGED
The message was purged before reaching the destination queue.
MQMSG_CLASS_NACK_NOT_TRANSACTIONAL_Q
A transactional message was sent to a non-transactional queue.
MQMSG_CLASS_NACK_NOT_TRANSACTIONAL_MSG
A non-transactional message was sent to a transactional queue.
MQMSG_CLASS_NACK_UNSUPPORTED_CRYPTO_PROVIDER
The target queue manager does not have the enhanced (128-bit) cryptographic provider installed.

Negative read acknowledgment messages (generated by MSMQ):

MQMSG_CLASS_NACK_Q_DELETED
The queue was deleted before the message could be read from the queue.
MQMSG_CLASS_NACK_Q_PURGED
The queue was purged and the message no longer exists.
MQMSG_CLASS_NACK_RECEIVE_TIMEOUT
The original message was not removed from the queue before its time-to-be-received timer expired.

For transactional messages, this means that the remote queue manager has indicated that the message was not retrieved. This is the only negative acknowledgment that can be trusted to indicate the message was not retrieved.

MQMSG_CLASS_NACK_RECEIVE_TIMEOUT_AT_SENDER
For transactional messages only. The local queue manager has indicated that the original message was not removed from the queue before its time-to-be-received timer expired.

This class is an in-doubt negative acknowledgment. For example, the local queue manager sets this class when the time-to-be-received timer expires, even though a positive confirmation may be in route from the remote queue manager.

Report messages (generated by MSMQ):

MQMSG_CLASS_REPORT
Sent each time the message enters or leaves an Message Queuing server.

Remarks

Acknowledgment messages are generated by Message Queuing whenever the sending application requests them. Message Queuing returns the appropriate acknowledgment message to the administration queue specified by the sending application. For information on acknowledgment messages, see Acknowledgment Messages.

Transactional messages can have two in-doubt negative acknowledgments: MQMSG_CLASS_NACK_REACH_QUEUE_TIMEOUT and MQMSG_CLASS_NACK_RECEIVE_TIMEOUT_AT_SENDER. These two classes are considered in doubt because they can be set by the local queue manager even though a confirmation notification may be in route from the remote queue manager. The only trusted negative acknowledgment is MQMSG_CLASS_NACK_RECEIVE_TIMEOUT, because this class is set by the remote queue manager.

Report messages are generated by Message Queuing whenever a report queue is defined at the source queue manager.

When reading messages in an administration queue or dead-letter queue, retrieve Class to find out why the message was sent to the queue.

You can also retrieve the class of a message when using Message Queuing function calls.

Equivalent API Function Property

When using API function calls, the class of the message can be set and retrieved using the PROPID_M_CLASS message property.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQMessage, MSMQMessage.MsgClass, MSMQMessage.PrivLevel, PROPID_M_CLASS


MSMQMessage.CompoundMessage

(Introduced in MSMQ 3.0.)The CompoundMessage property of the MSMQMessage object provides the SOAP attachments associated with the message.

Type: | Variant
Run time: | Read-only

messageObject.CompoundMessage

Parameters

messageObject
Message (MSMQMessage) object that defines the message.

Return Values

An array of bytes that represent the SOAP attachments (MIME binary attachments) attached to the message.

Remarks

CompoundMessage is used only when an application retrieves HTTP messages. When an HTTP message is sent, the sending queue manager attaches the SOAP attachments, along with the SOAP envelope, to the message.

This property can contain any number of SOAP attachments, it is the responsibility of the receiving application to parse the returned array of bytes and process the individual attachments.

To retrieve the SOAP envelope, see MSMQMessage.SOAPEnvelope.

Equivalent API function property

When using API functions, you can retrieve the SOAP attachments by using the PROPID_M_COMPOUND_MESSAGE property.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQMessage, MSMQMessage.SOAPEnvelope, PROPID_M_COMPOUND_MESSAGE


MSMQMessage.ConnectorTypeGuid

(Introduced in MSMQ 2.0.) The ConnectorTypeGuid property of the MSMQMessage object indicates that some message properties that are typically set by Message Queuing were set by the sending application.

Typically, this property is set by connector application and applications sending application-encrypted messages.

Type: | String (GUID format)
Run time: | Read/write

messageObject.ConnectorTypeGuid

Parameters

messageObject
Message (MSMQMessage) object that defines the message.

Setting

A string representation of an application-defined GUID. For example, of the following strings, the first indicates a valid setting, and the second indicates the default GUID_NULL.

{12345678-1234-1234-1234-123456789012}
{00000000-0000-0000-0000-000000000000}

Remarks

ConnectorTypeGuid is required whenever an application sets a message property that is typically set by MSMQ. It is typically used in the following two cases.

Whenever a connector application sends a message to a Message Queuing queue, the connector type property is required so that the receiving applications know how to interpret the security and acknowledgment properties of the messages.

Whenever an application sends an application-encrypted message, the connector type property is requires so that the Message Queuing run time knows to use the symmetric key provided in MSMQMessage.DestinationSymmetricKey to decrypt the message.

The sending application must set ConnectorTypeGuid when it sets any of the following properties. If ConnectorTypeGuid is not set, these properties will be ignored:

MSMQMessage.AuthenticationProviderName
MSMQMessage.AuthenticationProviderType
MSMQMessage.DestinationSymmetricKey
MSMQMessage.MsgClass
MSMQMessage.Signature
MSMQMessage.SenderId

The receiving application must explicitly specify that it wants this property when peeking at or retrieving messages. Each peek and receive method has a WantConnectorType parameter that controls whether this property is retrieved with the message. By default, ConnectorTypeGuid is not retrieved with the message.

The ConnectorTypeGuid property is a string, and Message Queuing COM components ignore any characters that follow the first null character in a string without returning an error.

Equivalent API function property

When using API functions, the connector type property of the message can be set and retrieved using the PROPID_M_CONNECTOR_TYPE property.

For information on | See
Connector applications | MSMQ Connector Servers
Sending a symmetric key when encrypting messages | Application-Encrypted Messages

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQMessage, MSMQMessage.AuthenticationProviderName, MSMQMessage.AuthenticationProviderType, MSMQMessage.DestinationSymmetricKey, MSMQMessage.MsgClass, MSMQMessage.Signature, MSMQMessage.SenderId, PROPID_M_CONNECTOR_TYPE


MSMQMessage.CorrelationId

The CorrelationId property of the MSMQMessage object identifies the message using a 20-byte, correlation identifier.

Type: | Variant (array of bytes)
Run time: | Read/write

messageObject.CorrelationId

Parameters

messageObject
Message (MSMQMessage) object that defines the message.

Property Values

A 20-byte application-defined correlation identifier.

Remarks

CorrelationId provides an application-defined identifier that the receiving application can use to sort messages. The correlation identifier must be a 20-byte identifier. If the correlation identifier is not 20-bytes, an MQ_ERROR_ILLEGAL_PROPERTY_SIZE error will be returned when the message is sent.

When sending response messages back to the sending application, the CorrelationId property of the response message can be set to the message identifier (MSMQMessage.Id) of the original message that is in the queue. This provides an easy mechanism that the sending application can use to match the response message with the original message that was sent.

When Message Queuing generates an acknowledgment message or report message, it uses the CorrelationId property to return the message identifier of the original message. The application reading the acknowledgment or report message can then look at the CorrelationId property to find the message identifier of the original message that was sent.

When generating acknowledgment and report messages, connector applications must set the correlation identifier of the acknowledgment and report messages to the message identifier of the original message.

When dimensioning Visual Basic arrays for the correlation identifier, always set the lower boundary of the array to 0. When filling in the correlation identifier, Message Queuing sets the lower boundary of the returned byte-array to 0 regardless of what boundary was set by the application.

The following Visual Basic call will always return 0.

LBound(msg.CorrelationId)

Equivalent API function property

When using API functions, the correlation identifier of the message can be set and retrieved using the PROPID_M_CORRELATIONID property.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQMessage, MSMQMessage.Id, PROPID_M_CORRELATIONID


MSMQMessage.Delivery

The Delivery property of the MSMQMessage object specifies how Message Queuing delivers the message.

Type: | Long
Run time: | Read/write

messageObject.Delivery

Parameters

messageObject
Message (MSMQMessage) object that represents the message.

Property Values

The Delivery property can have one of the following values:

MQMSG_DELIVERY_RECOVERABLE
In every hop along its route, the message is forwarded to the next hop or stored locally in a backup file until delivered. This guarantees delivery even in the case of a computer crash.
MQMSG_DELIVERY_EXPRESS
The default. The message stays in memory until it can be delivered. (In-memory message store and forward.)

Remarks

The Delivery property is used to specify express or recoverable messaging. Express messaging provides faster throughput. Recoverable messaging guarantees that the message will be delivered, even if a computer crashes while the message is en route to the queue. For a comparison of express and recoverable messaging, see Express and Recoverable Messaging.

Message Queuing always sets the delivery mechanism of transactional messages to MQMSG_DELIVERY_RECOVERABLE. For information on transactions, see Message Queuing Transactions.

Equivalent API Function Property

When using API function calls, the delivery type can be set and retrieved using the PROPID_M_DELIVERY message property.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQMessage, PROPID_M_DELIVERY


MSMQMessage.Destination

(Read-only, introduced in MSMQ 3.0) The Destination property of the MSMQMessage object provides the set of destination queues where the message was sent.

Type: | MSMQDestination
Run time: | Read-only

set messageObject.Destination = destinationObject

Parameters

messageObject
Message (MSMQMessage) object that represents the message.
destinationObject
Destination (MSMQDestination) object that represents a distribution list or multiple-element format name.

Property Values

MSMQDestination object.

Remarks

The Destination property is set by Message Queuing when the sending application sends the message using distribution lists or multiple-element format name.

Multiple destinations can be specified using distribution list or a multiple-element format names. Distribution lists are public lists that are published in Active Directory and multiple element format names are private lists that are created and maintained at the application level. For information on distribution lists and multiple-element format names, see Sending Messages to Multiple Destinations.

When multiple destinations are specified by the sending application, the receiving application can retrieve MSMQMessage.Destination to get the complete set of destinations, or retrieve MSMQMessage.DestinationQueueInfo to get the specific destination of the message. Message Queuing sets both properties when it sends messages to multiple destiinations.

Equivalent API function property

When using API functions, the destination queue set can be set and retrieved using the PROPID_M_DEST_FORMAT_NAME property.

Requirements

Windows NT/2000 or later: Requires Whistler.
Windows 95/98/Me: Unsupported.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQMessage, MSMQMessage.DestinationQueueInfo, PROPID_M_DEST_FORMAT_NAME


MSMQMessage.DestinationQueueInfo

Read-only. The DestinationQueueInfo property of the MSMQMessage object is set by Message Queuing when a message is sent. It specifies the destination queue of the message.

Type: | MSMQQueueInfo
Run time: | Read-only

set messageObject = queueinfoObject.DestinationQueueInfo

Parameters

messageObject
Message (MSMQMessage) object that represents the message.
queueinfoObject
Queue information (MSMQQueueInfo) object that represents the destination queue.

Property Values

MSMQQueueInfo object.

Remarks

To retrieve the DestinationQueueInfo property of the message, set the WantDestinationQueue parameter of receive or peek methods to TRUE. These methods include MSMQQueue.Peek, MSMQQueue.PeekCurrent, and MSMQQueue.PeekNext, MSMQQueue.Receive, MSMQQueue.ReceiveCurrent. For reasons of performance, the default setting of WantDestinationQueue is FALSE.

DestinationQueueInfo is typically used when reading messages that have been sent to a queue other than its original destination queue. For example, you may want to know the original destination queue of the messages that Message Queuing has sent to a computer journal or dead-letter queue. In normal circumstances, you do not need this property because you typically read the message from its destination queue.

This property can also be used when sending response messages to a response queue. To provide the destination queue of a message in a response message, set the MSMQMessage.ResponseQueueInfo property of the response message to the DestinationQueueInfo property of the original message. The application reading the response message can then look at the response queue information property to determine the origin of the response message.

You can also retrieve the destination queue when using Message Queuing function calls.

For information on | See
Retrieving the destination queue using Message Queuing function calls | PROPID_M_DEST_QUEUE

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQMessage, MSMQMessage.ResponseQueueInfo, MSMQQueue.Peek, MSMQQueue.PeekCurrent, MSMQQueue.PeekNext, MSMQQueue.Receive, MSMQQueue.ReceiveCurrent, MSMQQueueInfo, PROPID_M_DEST_QUEUE


MSMQMessage.DestinationSymmetricKey

(Introduced in MSMQ 2.0.) The DestinationSymmetricKey property of the MSMQMessage object specifies the symmetric key used to encrypt the message.

This property is used by connector applications and when sending application-encrypted messages.

Type: | Variant (array of bytes)
Run time: | Read/write

messageObject.DestinationSymmetricKey

Parameters

messageObject
Message (MSMQMessage) object that represents the message.

Property Values

The destination symmetric key used to encrypt the message.

Remarks

DestinationSymmetricKey contains an encrypted version of the symmetric key that the sending application used to encrypt the body of the message. Typically this property is used by connector applications to process encrypted message sent to foreign queues. However, it is also needed by any receiving application that must decrypt an application-encrypted message.

When sending an application-encrypted message, the sending application must encrypt the symmetric key that it used to encrypt the message using the public key of the receiving queue manager.

When this property is set, the sending application must also set MSMQMessage.ConnectorTypeGuid so that Message Queuing knows that the property was set by the sending application. MSMQMessage.DestinationSymmetricKey is ignored if both properties are not set when the message is sent.

Connector applications

Messages sent to a foreign queues are processed by the appropriate connector application and then passed on to the foreign queue. When the connector application receives an application-encrypted message, it can decrypt the message body itself or send the encrypted message body and the symmetric key on to the foreign queue. If the connector application does not decrypt the message, it is the responsibility of the receiving application to decrypt the symmetric key and the body of the message.

Retrieving application-encrypted messages

When you send application-encrypted messages, the receiving application must decrypt the symmetric key using the private key of the receiving queue manager and then use the symmetric key to decrypt the message body.

Visual Basic arrays

When dimensioning arrays for the symmetric key, always set the lower boundary of the array to 0. When filling in the correlation identifier, Message Queuing sets the lower boundary of the returned byte-array to 0 regardless of what boundary was set by the application.

The following Visual Basic call will always return 0.

LBound(msg.DestinationSymmetricKey)

Equivalent API function property

When using API functions, the symmetric key of the message can be set and retrieved using the PROPID_M_DEST_SYMM_KEYproperty.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQMessage, PROPID_M_DEST_SYMM_KEY


MSMQMessage.EncryptAlgorithm

The EncryptAlgorithm property of the MSMQMessage object specifies the encryption algorithm used to encrypt the message body of a private message.

Type: | Long
Run time: | Read/write

messageObject.EncrypAlgorithm

Parameters

messageObject
Message (MSMQMessage) object that represents the message.

Property Values

The EncryptAlgorithm property can have any one of the following values:

MQMSG_CALG_RC2
Default.
MQMSG_CALG_RC4

Message encryption is based on public-key encryption using the Microsoft® Cryptographic API with an underlying RSA provider.

Remarks

When sending private messages, Message Queuing uses the algorithm specified by MSMQMessage.EncryptAlgorithm to encrypt the body of the message and to decrypt the message body when it is received by the receiving queue manager.

Message can be encrypted by Message Queuing and by applications. For information on Message Queuing and application encryption, see Message Encryption.

Equivalent API Function Property

When using API function calls, the encryption algorithm can be set and retrieved using the PROPID_M_ENCRYPTION_ALG message property.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQMessage, MSMQMessage.PrivLevel, PROPID_M_ENCRYPTION_ALG


MSMQMessage.Extension

(Introduced in MSMQ 2.0.) The Extension property of the MSMQMessage object specifies additional application-defined information that is associated with the message.

This property is used by connector applications.

Type: | Variant (array of bytes)
Run time: | Read/write

messageObject.Extension

Parameters

messageObject
Message (MSMQMessage) object that represents the message.

Property Values

Application-defined information.

Remarks

The MSMQMessage.Extension property is used by connector applications to process non-Message Queuing message properties when translating between Message Queuing messages and foreign messages. It is the responsibility of the sending application, connector application, and the receiving application to understand the content of this property.

Visual Basic arrays

When dimensioning arrays for extension data, always set the lower boundary of the array to 0. When filling in the extension data, Message Queuing sets the lower boundary of the returned byte-array to 0 regardless of what boundary was set by the application.

The following Visual Basic call will always return 0.

LBound(msg.Extenstion)

Equivalent API function property

When using API functions, the extension property of the message can be set and retrieved using the PROPID_M_EXTENSION property.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQMessage, PROPID_M_EXTENSION


MSMQMessage.HashAlgorithm

The HashAlgorithm property of the MSMQMessage object specifies the hash algorithm used by Message Queuing when authenticating messages.

Type: | Long
Run time: | Read/write

messageObject.HashAlgorithm

Parameters

messageObject
Message (MSMQMessage) object that represents the message.

Property Values

This property can be set to any of the values defined by the ALG_ID data type in wincrypt.h (the default is CALG_MD5) or in the MSMQ_CALG enumeration.

Remarks

The Message Queuing run-time code uses the hashing algorithm when creating a digital signature and when authenticating the message. For information on how Message Queuing authenticates messages, see Message Authentication

Equivalent API Function Property

When using API function calls, the hash algorithm for the digital signature can be set and retrieved using the PROPID_M_HASH_ALG message property.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQMessage, PROPID_M_HASH_ALG


MSMQMessage.Id

Read-only. The Id property of the MSMQMessage object identifies the message using an MSMQ-generated message identifier.

Type: | Variant (array of bytes)
Run time: | Read-only

messageObject.Id

Parameters

messageObject
Message (MSMQMessage) object from queue.

Return Values

20-byte message identifier (array of bytes).

Remarks

Message Queuing generates a 20-byte message identifier when the message is sent. This includes application-generated messages sent by applications and system-generated messages sent by Message Queuing. The message identifier is composed of the machine GUID of the sending computer plus an additional identifier that is unique to the computer. By combining these two components, the message identifier is unique for each message.

Sending messages to multiple destinations

When messages are sent to multiple destinations by means of distribution lists, multicast addresses, and multiple-element format names, only one identifier is generated for all the messages sent. For example, if a distribution list is used to send a message to three destinations all three messages will have the same message identifier. To distinguish between messages with the same identifier, the application looking at the messages must also check the unique destination of each message.

Message identifiers in acknowledgment messages

When an acknowledgment message is created, the message identifier of the original message can be found in the MSMQMessage.CorrelationId property of the acknowledgment message.

Message identifiers in response messages

When sending response messages, MSMQMessage.CorrelationId can be set to the message identifier of the message that is in the queue. This provides an easy mechanism that the sending application can use to match the response message with the message that was sent.

Visual Basic arrays

When dimensioning arrays for the message identifier, always set the lower boundary of the array to 0. When filling in the identifier, Message Queuing sets the lower boundary of the returned byte-array to 0 regardless of what boundary was set by the application.

The following Visual Basic call will always return 0.

LBound(msg.Id)

Equivalent API function property

When using API functions, the identifier of the message can be set and retrieved using the PROPID_M_MSGID property.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQMessage, MSMQMessage.CorrelationId, PROPID_M_MSGID


MSMQMessage.IsAuthenticated

Read-only. The IsAuthenticated property of the MSMQMessage object indicates whether the sending application requested authentication.

This property is superseded by MSMQMessage.IsAuthenticated2.

Type: | Short
Run time: | Read-only

messageObject.IsAuthenticated

Parameters

messageObject
Message (MSMQMessage) object that defines the message.

Returned Value

1
The sending application requested authentication. The receiving queue manager authenticated the message when it received the message.
0
The sending application did not request authentication. The receiving queue manager did not attempt to authenticate the message when it received the message.

Remarks

This message property is used by the receiving application only when trying to determine if authentication was requested. If authentication was requested and the message is in the queue, then the message was authenticated.

Note It is not possible to look at the properties of a message and determine if a message failed authentication. Messages that fail authentication are discarded and are not delivered to the queue.

Authentication requests can also be retrieved using Message Queuing function calls.

MSMQ 1.0 and 2.0 Differences

Message Queuing can use two different signatures to authenticate messages: MSMQ 1.0 signatures and MSMQ 2.0 signatures. By default, a receiving computer running MSMQ 2.0 will accept either type of signature. The following registry key specifies what type of signature is used by the receiving computer:

hklm\software\microsoft\msmq\parameters\security\RcvOnlyEnhMsgAuthn
To | Set registry key to
Accept either MSMQ 1.0 or MSMQ 2.0 signatures. | 0
Accept only MSMQ 2.0 signatures | 1

For compatibility, a source computer running MSMQ 2.0 sends, by default, only the MSMQ 1.0 signature. Therefore, when you set this receiving registry key to accept only MSMQ 2.0 signatures, make sure you reset the sending registry key on the source computer as well. For more information, see MSMQMessage.AuthLevel.

If the receiving application needs only to check whether authentication was requested, it should use IsAuthenticated. However, if the receiving application also needs to check what type of signature was used during authentication, it must use MSMQMessage.ReceivedAuthenticationLevel.

You cannot specify both message properties when reading the messages in the queue.

For information on | See
Retrieving authentication requests using Message Queuing function calls | PROPID_M_AUTHENTICATED

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQMessage, MSMQMessage.ReceivedAuthenticationLevel, PROPID_M_AUTHENTICATED


MSMQMessage.IsAuthenticated2

(Read-only, introduced in MSMQ 3.0.) The IsAuthenticated2 property of the MSMQMessage object indicates whether the sending application requested message authentication.

MSMQMessage.IsAuthenticated2 is a Boolean property that supercedes the non-Boolean MSMQMessage.IsAuthenticated

Type: | Boolean
Run time: | Read-only

messageObject.IsAuthenticated2

Parameters

messageObject
Message (MSMQMessage) object that defines the message.

Returned Value

VARIANT_TRUE (-1)
The sending application requested authentication. The receiving queue manager authenticated the message when it received the message.
VARIANT_FALSE (0)
The sending application did not request authentication. The receiving queue manager did not attempt to authenticate the message when it received the message.

Remarks

MSMQMessage.IsAuthenticated2 is used by the receiving application to determine if the sending application requested authentication (see also, MSMQMessage.ReceivedAuthenticationLevel). If authentication was requested and the message is in the queue, then the receiving application can assume that the message was authenticated.

Note It is not possible to look at the properties of a message and determine if a message failed authentication. Messages that fail authentication are discarded and are not delivered to the queue.

MSMQMessage.IsAuthenticated2 and MSMQMessage.IsAuthenticated

MSMQMessage.IsAuthenticated2 supercedes MSMQMessage.IsAuthenticated and should be used whenever possible. MSMQMessage.IsAuthenticated2 returns Boolean values that are consistent with Microsoft Visual Basic Boolean data types. Otherwise, both properties are functionally equivalent.

Checking Digital Signature Type

To check what type of signature was used to sign the message, the receiving application must look at the MSMQMessage.ReceivedAuthenticationLevel property of the message.

Equivalent API Function Property

When using API function calls, you can check whether message authentication was requested by retrieving the PROPID_M_AUTHENTICATED.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQMessage, MSMQMessage.ReceivedAuthenticationLevel, PROPID_M_AUTHENTICATED


MSMQMessage.IsFirstInTransaction

(Introduced in MSMQ 2.0.) Read-only. The IsFirstInTransaction property of the MSMQMessage object indicates whether the message was the first message sent in its transaction.

This property is superseded by MSMQMessage.IsFirstInTransaction2.

Type: | Short
Run time: | Read-only

messageObject.IsFirstInTransaction

Parameters

messageObject
Message (MSMQMessage) object that defines the message.

Returned Value

1
The message was the first message sent in the transaction.
0
The message was not the first message sent in the transaction.

Remarks

This property is available for MSMQ 2.0 and later. It is used by receiving applications to verify that a message was the first message sent in a single transaction to a single queue.

You can use IsFirstInTransaction along with two other properties to verify transaction boundaries. These two properties are a property for checking whether a message was the last message sent in a transaction and a property for retrieving the identifier of the transaction: MSMQMessage.IsLastInTransaction and MSMQMessage.TransactionId.

If only one message is sent in a transaction, both IsFirstInTransaction and IsLastInTransaction are set.

You can also check whether a message was first in the transaction using Message Queuing function calls.

For information on | See
How transaction boundaries can be used | Checking for Transaction Boundaries when Receiving Messages
Checking the last message in the transaction | MSMQMessage.IsLastInTransaction
Retrieving the identifier of the transaction | MSMQMessage.TransactionId
Checking the first message using Message Queuing function calls | PROPID_M_FIRST_IN_XACT

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQMessage, MSMQMessage.IsLastInTransaction, MSMQMessage.TransactionId, PROPID_M_FIRST_IN_XACT


MSMQMessage.IsFirstInTransaction2

(Read-only, introduced in MSMQ 3.0.) The IsFirstInTransaction2 property of the MSMQMessage object indicates whether the message was the first message sent to the queue within a specific transaction.

MSMQMessage.IsFirstInTransaction2 is a Boolean property that supercedes the non-Boolean MSMQMessage.IsFirstInTransaction.

Type: | Boolean
Run time: | Read-only

messageObject.IsFirstInTransaction2

Parameters

messageObject
Message (MSMQMessage) object that defines the message.

Returned Value

VARIANT_TRUE (-1)
The message was the first message sent in the transaction.
VARIANT_FALSE (0)
The message was not the first message sent in the transaction.

Remarks

MSMQMessage.IsFirstInTransaction2 is used by receiving applications to verify that a message was the first message sent in a single transaction to a single queue.

Message Properties used to Check Transaction Boundaries

Message Queuing provides the following properties for verifying the boundaries (the first and last message sent to a specific queue) of a transaction.

  • MSMQMessage.IsFirstInTransaction2

    Indicates whether the message was the first message sent to the queue within a specific transaction.

  • MSMQMessage.TransactionId

    Indicates whether the message is part of a specific transaction.

  • MSMQMessage.IsLastInTransaction2

    Indicates whether the message was the last message sent to the queue within a specific transaction.

If only one message is sent in a transaction, both IsFirstInTransaction2 and IsLastInTransaction2 are set.

MSMQMessage.IsFirstInTransaction2 and MSMQMessage.IsFirstInTransaction

MSMQMessage.IsFirstInTransaction2 supercedes MSMQMessage.IsFirstInTransaction and should be used whenever possible. MSMQMessage.IsFirstInTransaction2 returns Boolean values that are consistent with Microsoft Visual Basic Boolean data types. Otherwise, both properties are functionally equivalent.

Equivalent API Function Property

When using API function calls, you can check whether a message is the first message in the transaction by retrieving the PROPID_M_FIRST_IN_XACT property.

For information on | See
How transaction boundaries can be used | Checking for Transaction Boundaries when Receiving Messages

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQMessage, MSMQMessage.IsLastInTransaction2, MSMQMessage.TransactionId, PROPID_M_FIRST_IN_XACT


MSMQMessage.IsLastInTransaction

(Introduced in MSMQ 2.0.) Read-only. The IsLastInTransaction property of the MSMQMessage object indicates whether the message was the last message sent in its transaction.

This property is superseded by MSMQMessage.IsLastInTransaction2.

Type: | Short
Run time: | Read-only

messageObject.IsLastInTransaction

Parameters

messageObject
Message (MSMQMessage) object that defines the message.

Returned Value

1
The message was the last message sent in the transaction.
0
The message was not the last message sent in the transaction.

Remarks

This property is available for MSMQ 2.0 and later. It is used by receiving applications to verify that a message was the last message sent in a single transaction to a single queue.

You can use IsLastInTransaction along with two other properties to verify transaction boundaries. These two properties are a property for checking the first message sent in a transaction and a property for retrieving the identifier of the transaction: MSMQMessage.IsFirstInTransaction and MSMQMessage.TransactionId.

If only one message is sent in a transaction, both IsFirstInTransaction and IsLastInTransaction are set.

You can also check whether a message was last in the transaction using Message Queuing function calls.

For information on | See
How transaction boundaries can be used | Checking for Transaction Boundaries when Receiving Messages
Checking the first message in the transaction | MSMQMessage.IsFirstInTransaction
Retrieving the identifier of the transaction | MSMQMessage.TransactionId
Checking the last message using Message Queuing function calls | PROPID_M_LAST_IN_XACT

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQMessage, MSMQMessage.IsFirstInTransaction, MSMQMessage.TransactionId, PROPID_M_LAST_IN_XACT


MSMQMessage.IsLastInTransaction2

(Read-only, introduced in MSMQ 3.0.) The IsLastInTransaction2 property of the MSMQMessage object indicates whether the message was the last message sent to the queue within a specific transaction.

MSMQMessage.IsLastInTransaction2 is a Boolean property that supersedes the non-Boolean MSMQMessage.IsLastInTransaction.

Type: | Boolean
Run time: | Read-only

messageObject.IsLastInTransaction2

Parameters

messageObject
Message (MSMQMessage) object that defines the message.

Returned Value

VARIANT_TRUE (-1)
The message was the last message sent in the transaction.
VARIANT_FALSE (0)
The message was not the last message sent in the transaction.

Remarks

MSMQMessage.IsLastInTransaction2 is used by receiving applications to verify that a message was the last message sent to the queue within a specific transaction.

Message Properties used to Check Transaction Boundaries

Message Queuing provides the following properties for verifying the boundaries (the first and last message sent to a specific queue) of a transaction.

  • MSMQMessage.IsFirstInTransaction2

    Indicates whether the message was the first message sent to the queue within a specific transaction.

  • MSMQMessage.TransactionId

    Indicates whether the message is part of a specific transaction.

  • MSMQMessage.IsLastInTransaction2

    Indicates whether the message was the last message sent to the queue within a specific transaction.

If only one message is sent in a transaction, both IsFirstInTransaction2 and IsLastInTransaction2 are set.

MSMQMessage.IsLastInTransaction2 and MSMQMessage.IsLastInTransaction

MSMQMessage.IsLastInTransaction2 supersedes MSMQMessage.IsLastInTransaction and should be used whenever possible. MSMQMessage.IsLastInTransaction2 returns Boolean values that are consistent with Microsoft Visual Basic Boolean data types. Otherwise, both properties are functionally equivalent.

Equivalent API Function Property

When using API function calls, you can verify whether a message is the last message in the transaction by retrieving the PROPID_M_LAST_IN_XACT property.

For information on | See
How transaction boundaries can be used | Checking for Transaction Boundaries when Receiving Messages

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQMessage, MSMQMessage.IsFirstInTransaction2, MSMQMessage.TransactionId, PROPID_M_LAST_IN_XACT


MSMQMessage.Journal

The Journal property of the MSMQMessage object specifies how Message Queuing tracks messages as they are routed to the destination queue.

Type: | Long
Run time: | Read/write

messageObject.Journal

Parameters

messageObject
Message (MSMQMessage) object used to define a message.

Property Values

Set Journal to one or more of the following values:

MQMSG_DEADLETTER
Negative source journaling is requested. Messages are stored in dead-letter queues on failure.

For non-transactional messages, failure means that the computer was not able to deliver the message to the next computer (for example, if a message timer expires).

For transactional messages, failure means that the source queue manager did not receive a confirmation that the message was removed from its destination queue.

MQMSG_JOURNAL
Positive source journaling is requested. A copy of the message is stored in computer journal on the computer if the message was successfully delivered to the next computer.
MQMSG_JOURNAL_NONE
The default. The message is not kept in the originating computer's computer journal.

Remarks

MSMQMessage.Journal can specify positive source journaling, negative source journaling, or both. For information on positive and negative source journaling, see Source Journaling.

MSMQMessage.Journal can be set to the following combinations.

  • MQMSG_JOURNAL: Positive source journaling is requested. Messages are stored in computer journals on success but not in dead-letter queues on failure.
  • MQMSG_DEADLETTER: Negative source journaling is requested. Messages are stored in dead-letter queues on failure, but not in computer journals on success.
  • MQMSG_JOURNAL | MQMSG_DEADLETTER: Positive and negative source journaling is requested. Messages are stored in computer journals on success and stored in dead-letter queues on failure.
  • MQMSG_JOURNAL_NONE: Source journaling is disabled (default). Copies of messages are not stored in computer journals on success nor in dead-letter queues on failure.

Negative source journaling

Negative source journaling uses a transactional and non-transaction dead-letter queues to store message that fail. For non-transactional messages, failure means that a computer could not deliver the message. For transactional messages, failure means that the source queue manager did not receive a confirmation that the transactional message was removed from the destination queue. Copies of failed transactional messages are placed only in the transactional dead-letter queue of the source computer.

For transactional messages, the default semantics for the source computer can be changed by setting the following registry to one of two setting.

XactDeadLetterAlways

The default negative source journaling semantics for transactional messages are:

  • Negative source journaling always: The XactDeadLetterAlways registry key is set to 1.

    When this default is used, Message Queuing puts a copy of every unconfirmed message in the transactional dead-letter queue of the source computer regardless of what the journaling property of the transactional messages are set to. These are the default semantics for MSMQ 1.0 and MSMQ 3.0.

  • Negative source journaling optional: The XactDeadLetterAlways registry key is set to 0.

    When this default is used, Message Queueing places a copy of unconfirmed transactional messages in the transactional dead-letter queue of the source computer only when the journaling property of the message specifies MQMSG_DEADLETTER. This is the default semantics for MSMQ 2.0.

Processing messages in computer journal and dead-letter queues

Processing messages in computer journals and dead-letter queues is the responsibility of the application or the Message Queuing administrator. Messages should be removed from these queues on a regular basis so that they do not consume the resources of the computer. Messages stored in dead-letter queues count against the quota of the computer (the computer quota is set by Message Queuing administrator).

Creating computer journal and dead-letter queues

Setting MSMQMessage.Journal do positive or negative journaling does not create a computer journal or dead-letter queue. Computer journal and dead-letter queues are system queues generated by Message Queuing. For information on journal and dead-letter queues, see System Generated Queues.

Equivalent API function property

When using API functions, the journaling level of the message can be set and retrieved using the PROPID_M_JOURNAL property.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQMessage, MSMQMessage.Send, PROPID_M_JOURNAL


MSMQMessage.Label

The Label property of the MSMQMessage object specifies a description of the message.

Type: | String
Run time: | Read/write

messageObject.Label

Parameters

messageObject
The message (MSMQMessage) object that defines the message.

Property Values

Message label
Application-defined string describing the message. The maximum length of a message label is 250 Unicode characters (including end-of-line character).

Remarks

Message labels can be used by administration tools for display purposes. For example, a printing application could put the source application and document name in the label of each message it sends to the printer queue.

You can also set and retrieve the label of a message when using Message Queuing function calls.

Null characters in strings

Message Queuing COM components ignore any characters that follow the first Null character in a string without returning an error.

Equivalent API function property

When using API functions, the label of the message can be set and retrieved using the PROPID_M_LABEL property.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQMessage, PROPID_M_LABEL


MSMQMessage.LookupId

(Read-only, introduced in MSMQ 3.0) The LookupId property of the MSMQMessage object provides the lookup identifier of the message.

Type: | Variant
Run time: | Read only

messageObject.LookupId

Parameters

messageObject
Message (MSMQMessage) object that represents the message.

Property Values

String representation of 64-bit lookup identifier of message.

Remarks

The lookup identifier of a message is a 64-bit, local number that is set by the target queue manager when the queue manager places the message in the queue. The lookup identifier of a message is unique with respect to the queue, and is always greater than the lookup identifier of the preceding message and less then the lookup identifier of the following message.

All messages placed in a queue have a lookup identifier. This includes messages sent by applications and messages sent by Message Queuing.

The receiving application can use the lookup identifier when calling one of the following methods.

  • MSMQQueue.PeekPreviousByLookupId
  • MSMQQueue.PeekByLookupId
  • MSMQQueue.PeekNextByLookupId
  • MSMQQueue.ReceivePreviousByLookupId
  • MSMQQueue.ReceiveByLookupId
  • MSMQQueue.ReceiveNextByLookupId

For information on navigating queues using lookup identifiers, see Message Lookup Identifier.

Null characters in strings

Message Queuing COM components ignore any characters that follow the first Null character in a string without returning an error.

Equivalent API Property

When using API functions, you can look at the lookup identifier of a message using the PROPID_M_LOOKUPID property.

Requirements

Windows NT/2000 or later: Requires Whistler.
Windows 95/98/Me: Unsupported.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQQueue.PeekByLookupId, MSMQQueue.PeekNextByLookupId, MSMQQueue.PeekPreviousByLookupId, MSMQQueue.ReceiveByLookupId, MSMQQueue.ReceiveNextByLookupId, MSMQQueue.ReceivePreviousByLookupId, PROPID_M_LOOKUPID


MSMQMessage.MaxTimeToReachQueue

The MaxTimeToReachQueue property of the MSMQMessage object specifies a time limit (in seconds) for the message to reach the queue.

Type: | Long
Run time: | Read/write

messageObject.MaxTimeToReachQueue

Parameters

messageObject
Message (MSMQMessage) object that represents the message.

Property Values

Integer value (the default is LONG_LIVED).

Remarks

MaxTimeToReachQueue sets the message's time-to-reach-queue timer. For a discussion of message timers, see Message Timers. If the time-to-reach-queue timer expires before the message reaches its destination, Message Queuing discards the message, sending it to the dead-letter queue if the message's MSMQMessage.Journal property is set to MQMSG_DEADLETTER.

Message Queuing can also send a return negative acknowledgment message back to the sending application if the message does not arrive and the message's MSMQMessage.Ack property is set accordingly.

The default value LONG_LIVED is an enterprise-wide setting that can be adjusted by the MSMQ Administrator. Typically, LONG_LIVED is set to 90 days. Although this timer can be set to INFINITE, Message Queuing automatically uses the LONG_LIVED value in its place.

Once a message arrives at the queue, MaxTimeToReachQueue can be used to find out how much time remains in the time-to-reach-queue timer. A value of 0 indicates the timer has expired.

Message Queuing uses two message timers: time-to-reach-queue and time-to-be-received. If the time-to-be-received timer is set to a value less than the time-to-reach-queue timer, the time-to-be-received timer takes precedence over the time-to-reach-queue timer.

No matter what value MaxTimeToReachQueue is set to (even if set to 0), Message Queuing always gives each message one chance to reach its destination if the queue is waiting for the message. If the queue is local, the message always reaches the queue.

Message Queuing automatically uses the time-to-reach-queue timer of the first message when several messages are sent in a transaction. For more information, see Message Queuing Transactions.

When Message Queuing creates an acknowledgment message, it always sets the message's time-to-reach-queue timer to LONG_LIVED.

When a message is sent from an independent client computer, the time-to-reach-queue timer starts ticking as soon as the send operation succeeds, even if the client computer is offline.

Equivalent API Function Property

When using API function calls, the time-to-reach-queue timer of the message can be set and retrieved using the PROPID_M_TIME_TO_REACH_QUEUE message property.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQMessage, MSMQMessage.Ack, MSMQMessage.Journal, PROPID_M_TIME_TO_REACH_QUEUE


MSMQMessage.MaxTimeToReceive

The MaxTimeToReceive property of the MSMQMessage object specifies a time limit (in seconds) for the message to be retrieved from the target queue. This includes the time spent getting to the destination queue plus the time spent waiting in the queue before it is retrieved by an application.

Type: | Long
Run time: | Read/write

messageObject.MaxTimeToReceive

Parameters

messageObject
Message (MSMQMessage) object that defines the message.

Property Values

Integer value (the default is INFINITE).

Remarks

MaxTimeToReceive sets the message's time-to-be-received timer. For a discussion of message timers, see Message Timers. If the time-to-be-received timer expires before the message is removed from the queue, Message Queuing discards the message, sending it to the dead-letter queue if the message's MSMQMessage.Journal property is set to MQMSG_DEADLETTER.

Message Queuing can also send a negative acknowledgment message back to the sending application if the message's MSMQMessage.Ack property is set accordingly and the message is not retrieved before the timer expires.

Once a message arrives at the queue, MaxTimeToReceive can be used to find out how much time remains in the time-to-be-received timer.

Message Queuing uses two message timers: time-to-reach-queue and time-to-be-received. If the time-to-be-received timer is set to a value less than the time-to-reach-queue timer, the time-to-be-received timer takes precedence over the time-to-reach-queue timer.

Message Queuing automatically uses the time-to-be-received timer of the first message when several messages are sent in a transaction. For more information, see Message Queuing Transactions.

When Message Queuing creates an acknowledgment message, it always sets the message's time-to-be-received timer to INFINITE.

When a message is sent from an independent client computer, the time-to-be-received timer starts ticking as soon as the send operation succeeds, even if the client computer is offline.

When using dependent client computers, make sure the clock on the client computer is in sync with the clock on the server running MSMQ. If these two clocks are not synchronized, you may see unpredictable behavior when sending messages with the time-to-be-received timer set.

Equivalent API Function Property

When using API function calls, the time-to-be-received timer of the message can be set and retrieved using the PROPID_M_TIME_TO_BE_RECEIVED message property.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQMessage, MSMQMessage.Ack, MSMQMessage.Journal, PROPID_M_TIME_TO_BE_RECEIVED


MSMQMessage.MsgClass

(Introduced in MSMQ 2.0.) The MsgClass property of the MSMQMessage object indicates the message type. A message can be a normal Message Queuing message, a positive or negative (arrival and read) acknowledgment message, or a report message. Typically this property is set by Message Queuing when it sends the message, however it can also be set by a connector application when the connector application sends a message.

Type: | Long
Run time: | Read/write

messageObject.MsgClass

Parameters

messageObject
Message (MSMQMessage) object that represents the message.

Return Values

MsgClass can be set to one of the following values:

Normal messages (all messages created by your application):

MQMSG_CLASS_NORMAL
A normal Message Queuing message.

Positive acknowledgment messages:

MQMSG_CLASS_ACK_REACH_QUEUE
The original message reached its destination queue.
MQMSG_CLASS_ACK_RECEIVE
The original message was retrieved by the receiving application.

Negative arrival acknowledgment messages:

MQMSG_CLASS_NACK_ACCESS_DENIED
The sending application does not have access rights to the destination queue.
MQMSG_CLASS_NACK_BAD_DST_Q
The destination queue is not available to the sending application.
MQMSG_CLASS_NACK_BAD_ENCRYPTION
The destination queue manager could not decrypt a private (encrypted) message (see MSMQMessage.PrivLevel).
MQMSG_CLASS_NACK_BAD_SIGNATURE
Message Queuing could not authenticate the original message. The original message's digital signature is not valid.
MQMSG_CLASS_NACK_COULD_NOT_ENCRYPT
The source queue manager could not encrypt a private message (see MSMQMessage.PrivLevel).
MQMSG_CLASS_NACK_HOP_COUNT_EXCEEDED
The original message's hop count is exceeded.
MQMSG_CLASS_NACK_Q_EXCEED_QUOTA
The original message's destination queue is full.
MQMSG_CLASS_NACK_REACH_QUEUE_TIMEOUT
Either the time-to-reach-queue or time-to-be-received timer expired before the original message could reach the destination queue.

For transactional messages, this is an in-doubt negative acknowledgment. For example, the local queue manager sets this class when the message timer expires, even though a positive confirmation may be in route from the remote queue manager.

MQMSG_CLASS_NACK_PURGED
The message was purged before reaching the destination queue.
MQMSG_CLASS_NACK_NOT_TRANSACTIONAL_Q
A transactional message was sent to a non-transactional queue.
MQMSG_CLASS_NACK_NOT_TRANSACTIONAL_MSG
A non-transactional message was sent to a transactional queue.
MQMSG_CLASS_NACK_UNSUPPORTED_CRYPTO_PROVIDER
The target queue manager does not have the enhanced (128-bit) cryptographic provider installed.

Negative read acknowledgment messages:

MQMSG_CLASS_NACK_Q_DELETED
The queue was deleted before the message could be read from the queue.
MQMSG_CLASS_NACK_Q_PURGED
The queue was purged and the message no longer exists.
MQMSG_CLASS_NACK_RECEIVE_TIMEOUT
The original message was not removed from the queue before its time-to-be-received timer expired.

For transactional messages, this means that the remote queue manager has indicated that the message was not retrieved. This is the only negative acknowledgment that can be trusted to indicate the message was not retrieved.

MQMSG_CLASS_NACK_RECEIVE_TIMEOUT_AT_SENDER
For transactional messages only. The local queue manager has indicated that the original message was not removed from the queue before its time-to-be-received timer expired.

This class is an in-doubt negative acknowledgment. For example, the local queue manager will set this class when the time-to-be-received timer expires, even though a positive confirmation may be in route from the remote queue manager.

Report messages:

MQMSG_CLASS_REPORT
Sent each time the message enters or leaves an Message Queuing server.

Remarks

Acknowledgment messages are generated by Message Queuing whenever the sending application requests them. Message Queuing returns the appropriate acknowledgment message to the administration queue that is specified by the sending application. For information on acknowledgment messages, see Acknowledgment Messages.

Transactional messages can have two in-doubt negative acknowledgments: MQMSG_CLASS_NACK_REACH_QUEUE_TIMEOUT and MQMSG_CLASS_NACK_RECEIVE_TIMEOUT_AT_SENDER. These two classes are considered in doubt because they can be set by the local queue manager even though a confirmation notification may be in route from the remote queue manager. The only trusted negative acknowledgment is MQMSG_CLASS_NACK_RECEIVE_TIMEOUT, because this class is set by the remote queue manager.

Report messages are generated by Message Queuing whenever a report queue is defined at the source queue manager.

Reading Messages in Administration and Dead-Letter Queues

When reading messages in an administration queue or dead-letter queue, retrieve MSMQMessage.MsgClass to find out why the message was sent to the queue.

Connector Applications Creating Acknowledgment Messages

When a connector application creates an acknowledgment message, it must set the class of the acknowledgment message the correct type. To do this the connector application must set MSMQMessage.MgClass and MSMQMessage.ConnectorTypeGuid. The MSMQMessage.MsgClass property is ignored if the MSMQMessage.ConnectorTypeGuid property is not also set when the message is sent.

Equivalent API Function Property

When using API function calls, the class of the message can be set and retrieved using the PROPID_M_CLASS message property.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQMessage, MSMQMessage.PrivLevel, PROPID_M_CLASS


MSMQMessage.Priority

The Priority property of the MSMQMessage object specifies the message's priority. A low number indicates a low priority message.

Type: | Long
Run time: | Read/write

messageObject.Priority

Parameters

messageObject
Message (MSMQMessage) object that represents the message.

Property Values

Set Priority to an integer value between 7 and 0 (the default is 3).

Remarks

Message priority effects how Message Queuing handles the message while it is in route, as well as where the message is placed in the queue. Higher priority messages are given preference during routing, and inserted toward the front of the queue. For example, when routing messages Message Queuing handles messages with a priority of 7 before it handles messages with a priority of 0 and, when the message is delivered to the destination queue, places the priority 7 messages closer to the front of the queue.

Messages with the same priority are placed in the queue according to their arrival time.

Messages sent to public queues

When Message Queuing routes a message to a public queue, the priority level of the message is added to the priority level of the public queue (the priority level of the queue is specified by the MSMQQueueInfo.BasePriority property of the queue). However, the priority level of the queue has no effect on how messages are placed in the queue.

Message priority within transactions

Message Queuing automatically sets the priority level of transactional messages to 0: MSMQMessage.Priority is ignored by the transaction. For information about transactions, see Message Queuing Transactions.

Equivalent Function Property

When using MSMQ functions, the priority level of a message can be set using PROPID_M_PRIORITY.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQMessage, MSMQQueueInfo.BasePriority, PROPID_M_PRIORITY


MSMQMessage.PrivLevel

The PrivLevel property of the MSMQMessage object specifies privacy level of the message.

Type: | Long
Run time: | Read/write

messageObject.PrivLevel

Parameters

messageObject
The message (MSMQMessage) object that defines the message.

Property Values

Set PrivLevel to one of the following values:

MQMSG_PRIV_LEVEL_BODY
Privacy is enforced. 40-bit end-to-end encryption of the message body is used.
MQMSG_PRIV_LEVEL_BODY_BASE
(Introduced in MSMQ 2.0.) Privacy is enforced. 40-bit end-to-end encryption of the message body is used.
MQMSG_PRIV_LEVEL_BODY_ENHANCED
(Introduced in MSMQ 2.0.) Privacy is enforced. 128-bit end-to-end encryption of the message body is used.
MQMSG_PRIV_LEVEL_NONE
The default. The message is a non-private (clear) message.

Remarks

The MSMQMessage.PrivLevel is used to request encryption by Message Queueing. For information on how Message Queueing encrypts messages, see Message Encryption.

The sending application can request encryption by setting the MSMQMessage.PrivLevel property to to MQMSG_PRIV_LEVEL_BODY, MQMSG_PRIV_LEVEL_BODY_BASE, or MQMSG_PRIV_LEVEL_BODY_ENHANCED. When one of these settings is used, the body of the message is encrypted with the algorithm specified by MSMQMessage.EncryptAlgorithm.

Note MSMQ 2.0 and MSMQ 3.0 applications can use MQMSG_PRIV_LEVEL_BODY or MQMSG_PRIV_LEVEL_BODY_BASE to request 40-bit encryption.

Application Encrypted Messages

Messages can also be encrypted by applications. In this case the MSMQMessage.PrivLevel property must be set as follows.

  • If your application is encrypting the message body with a 40-bit key, ignore the MSMQMessage.PrivLevel property when sending messages.
  • If your application is encrypting the message body with a 128-bit key, set MSMQMessage.PrivLevel to MQMSG_PRIV_LEVEL_BODY_ENHANCED and include it with the message.

For information on application encryption, see Application-Encrypted Messages

Equivalent API Function Property

When using API function calls, the privacy level of the message can be set and retieved using the PROPID_M_PRIV_LEVEL message property.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQMessage, MSMQMessage.EncryptAlgorithm, PROPID_M_PRIV_LEVEL


MSMQMessage.ReceivedAuthenticationLevel

Read-only. The ReceivedAuthenticationLevel property of the MSMQMessage object indicates whether the sending application requested authentication and indicates what type of signature was used.

Type: | Short
Run time: | Read-only

messageObject.ReceivedAuthenticationLevel

Parameters

messageObject
Message (MSMQMessage) object that defines the message.

Return Values

MQMSG_AUTHENTICATION_NOT_REQUESTED
The sending application did not request authentication. The receiving queue manager did not attempt to authenticate the message when it received the message.
MQMSG_AUTHENTICATED_SIG10
Introduced in MSMQ 3.0. For non-HTTP messages, the sending application requested authentication using an MSMQ 1.0 signature.

For HTTP messages, the sending application requested authentication using an XML digital signature.

MQMSG_AUTHENTICATED_SIG20
Introduced in MSMQ 3.0. For non-HTTP messages, the sending application requested authentication using an MSMQ 2.0 signature.

For HTTP messages, the sending application requested authentication using an XML digital signature.

MQMSG_AUTHENTICATED_SIG30
Introduced in MSMQ 3.0. For non-HTTP messages, the sending application requested authentication using an MSMQ 2.0 or MSMQ 3.0 signature. MSMQ 3.0 signatures are used when sending messages using distribution lists, multicast addresses, or multiple-element format names.

For HTTP messages, the message is signed using an XML digital signature.

MQMSG_AUTHENTICATED_SIGXML
Introduced in MSMQ 3.0. The sending application requested authentication using a digital signature.
MQMSG_AUTHENTICATION_REQUESTED
Obsolete. The sending application requested authentication using an MSMQ 1.0 signature. This value is superseded by MQMSG_AUTH_LEVEL_SIG10.
MQMSG_AUTHENTICATION_REQUESTED_EX
Obsolete. The sending application requested authentication using an MSMQ 2.0 signature. This value is superseded by MQMSG_AUTH_LEVEL_SIG20.

Remarks

This message property is only used by the receiving application when trying to determine if authentication was requested and what type of signature was used. If authentication was requested and the message is in the queue, then the message was authenticated.

Note It is not possible to look at the properties of a message and determine if a message failed authentication. Messages that fail authentication are discarded and are not delivered to the queue.

MSMQ 1.0 and 2.0 Differences

Message Queuing can use two different signatures to authenticate messages: MSMQ 1.0 signatures and MSMQ 2.0 signatures (by default, the receiving computer will accept either type of signature.) The following registry key specifies what type of signature is used by the receiving computer.

hklm\software\microsoft\msmq\parameters\security\RcvOnlyEnhMsgAuthn

To change the default behavior, set this key to one of the following values.

To | Set registry key to
Use MSMQ 1.0 and MSMQ 2.0 signatures. | 0
Use only MSMQ 2.0 signatures | 1

For compatibility, a source computer running MSMQ 2.0 sends, by default, only the MSMQ 1.0 signature. Therefore, when you set this receiving registry key to accept only MSMQ 2.0 signatures, make sure you reset the sending registry key on the source computer as well. For more information, see MSMQMessage.AuthLevel.

If the receiving application needs to check only whether authentication was requested, it should use MSMQMessage.IsAuthenticated. However, if the receiving application also needs to check what type of signature was used during authentication, it should use MSMQMessage.ReceivedAuthenticationLevel.

You cannot specify both message properties when reading the messages in the queue.

For information on | See
Retrieving authentication requests using Message Queuing function calls | PROPID_M_AUTHENTICATED_EX

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQMessage, MSMQMessage.IsAuthenticated, PROPID_M_AUTHENTICATED_EX


MSMQMessage.ResponseDestination

The ResponseDestination property of the MSMQMessage object specifies a set of queues used for returned response messages.

Type: | MSMQDestination
Run time: | Read/write

set messageObject.ResponseDestination = destinationObject

Parameters

messageObject
Message (MSMQMessage) object that represents the message.
destinationObject
Destination (MSMQDestination) object that represents a distribution list or multiple-element format name.

Property Values

MSMQDestination object.

Remarks

The MSMQMessage.ResponseDestination property can be set by the sending application when requesting response messages from a receiving application. Response messages are application-defined, and it is the sending and receiving applications responsibility to understand what is in the message.

Response queues can be any transactional or non-transactional queue.

Specifying multiple response queues

Sets of response queues can be specified using the following format names.

  • Distribution list format names are used to reference response queues based on a public distribution list that is published in Active Directory. For information on the syntax of distribution list format names, see Distribution List Format Names.
  • Multicast address format names are used to reference response queues that are associated with a specific multicast address. For information on the syntax of multicast address format names, see Multicast Address Format Names.
  • Multiple-element format names are used to reference response queues based on a private list of destination queues. For information on the syntax of multiple element format names, see Multiple-Element Format Names.

Equivalent API function property

When using API functions, the response queue set can be set and retrieved using the PROPID_M_RESP_FORMAT_NAME property.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQDestination, MSMQMessage, PROPID_M_RESP_FORMAT_NAME


MSMQMessage.ResponseQueueInfo

The ResponseQueueInfo property of the MSMQMessage object specifies a queue for receiving response messages returned from the receiving application.

Type: | MSMQQueueInfo
Run time: | Read/write

set messageObject.ResponseQueueInfo = queueinfoObject

Parameters

messageObject
Message (MSMQMessage) object that represents the message.
queueinfoObject
Queue information (MSMQQueueInfo) object that represents the response queue.

Property Values

MSMQQueueInfo object of response queue.

Remarks

ResponseQueueInfo is used to send the format name of another queue to the receiving application. Typically, this is done so that the receiving application can send response messages back to the sending application. For information on response queues, see Response Queues.

Note The MSMQQueueInfo object of a private queue (which would be inaccessible otherwise) can also be sent using ResponseQueueInfo.

Messages returned to the response queue are application defined. The application must define what is in the messages as well as what is to be done when a message is received.

You can also set and retrieve the response queue when using Message Queuing function calls.

For information on | See
Setting and retrieving the response queue using Message Queuing function calls | PROPID_M_RESP_QUEUE

For an example of | See
Sending a message that provides the format name of a response queue | Requesting Response Messages

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQMessage, MSMQQueueInfo, PROPID_M_RESP_QUEUE_LEVEL


MSMQMessage.SenderCertificate

The SenderCertificate property of the MSMQMessage object provides an array of bytes that represents the security certificate. The security certificate is used to authenticate messages.

Type: | Variant
Run time: | Read/write

messageObject.SenderCertificate

Parameters

messageObject
Message (MSMQMessage) object that defines the message.

Property Values

Security certificate (internal or external).

Remarks

Use SenderCertificate when you want to authenticate a small number of messages with the same certificate.

Note When sending a large number of messages using the same certificate, use security context information to attach the certificate. Security context information is obtained by calling MSMQMessage.AttachCurrentSecurityContext. This security context method creates a security context based on the data that is in MSMQMessage.SenderCertificate. If MSMQMessage.SenderCertificate is not set before calling AttachCurrentSecurityContext, then the Message Queuing internal certificate for the user is used for the security context.

Message Queuing uses the certificate to authenticate the message. However, the receiving application can use the information in an external certificate to further verify who sent the message. (When an internal certificate is used, the information in the certificate is not useful to the receiving application.)

The receiving application should use only SenderCertificate when an external certificate is sent with the message. After retrieving the certificate, use the CryptoAPI to validate the information in the certificate. (If you don't know if an external or internal certificate was sent, retrieve the certificate and look at its locality attribute. If the locality attribute was set by MSMQ, then the certificate is an Message Queuing internal certificate.)

You can also set and retrieve the security certificate when using Message Queuing function calls.

For information on | See
What it means to authenticate a message | Message Authentication
Registering internal and external certificates | Registering a Certificate
How messages are authenticated | Message Authentication
Setting and retrieving the security certificate using Message Queuing function calls | PROPID_M_SENDER_CERT

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQMessage, MSMQMessage.AttachCurrentSecurityContext, PROPID_M_SENDER_CERT


MSMQMessage.SenderId

The SenderId property of the MSMQMessage object is an array of bytes that represents the identifier of the sending user. Typically, Message Queuing sets this property when the message is sent.

Type: | Variant
Run time: | Read/write

messageObject.SenderId

Parameters

messageObject
Message (MSMQMessage) object that defines the message.

Return Values

An array of bytes generated by MSMQ.

Remarks

SenderId is set by MSMQ, and is used primarily by the receiving queue manager when authenticating a message. The receiving queue manager uses the sender identifier in this property to verify who sent the message and to verify that the sender has access rights to a queue.

By default, Message Queuing sets this property when a message is sent. However, Message Queuing will not attach the sender identifier to the message if the sending application has set MSMQMessage.SenderIdType to MQMSG_SENDERID_TYPE_NONE, indicating that the sending application does not want Message Queuing to validate who sent the message.

The receiving application can use SenderId to retrieve information about who sent the message. However, the information in SenderId is only trustworthy if the message was authenticated.

Connector applications must provide the sender identification when sending message. In this case, SenderId and MSMQMessage.ConnectorTypeGuid must be set. SenderId is ignored if MSMQMessage.ConnectorTypeGuid is not also set when the message is sent.

You can also retrieve the sender identifier when using Message Queuing function calls.

For information on | See
Retrieving the sender identifier using Message Queuing function calls | PROPID_M_SENDERID

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQMessage, MSMQMessage.SenderIdType, PROPID_M_SENDERID


MSMQMessage.SenderIdType

The SenderIdType property of the MSMQMessage object specifies the type of sender identifier found by MSMQ. Currently, the only type of sender identifier available to Message Queuing is a security identifier (SID).

Type: | Long
Run time: | Read/write

messageObject.SenderIdType

Parameters

messageObject
Message (MSMQMessage) object that defines the message.

Property Values

Message Queuing sets SenderIdType to one of the following:

MQMSG_SENDERID_TYPE_NONE
MSMQMessage.SenderId is not attached to the message.
MQMSG_SENDERID_TYPE_SID
The default. The SenderId property contains an SID for the user sending the message.

Remarks

If the sending application does not want Message Queuing to authenticate who sent the message, it can specify MQMSG_SENDERID_TYPE_NONE when sending a message. This tells Message Queuing not to attach the SID to MSMQMessage.SenderId. However, if the sender identifier is not sent with the message, the access rights of the queue must be set to accept messages from everyone.

The receiving application can use SenderIdType to determine what type of sender identifier was attached to the message.

An SIDr of a local user (a user not logged in to a Microsoft® Windows® 2000 domain) is only valid locally. Even if a local user specifies an SID, it is not sent with the message.

Equivalent API Function Property

When using API function calls, the sender identifier type can be set and retrieved using the PROPID_M_SENDERID_TYPE message property.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQMessage, MSMQMessage.SenderId, PROPID_M_SENDERID_TYPE


MSMQMessage.SenderVersion

This property is reserved for future use.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.


MSMQMessage.SentTime

The SentTime property of the MSMQMessage object indicates when a message is sent.

Type: | Date Variant
Run time: | Read-only

messageObject.SentTime

Parameters

messageObject
Message (MSMQMessage) object that defines the message.

Return Values

Date when message was sent.

Remarks

The returned value for this property can be manipulated using standard Microsoft® Visual Basic® date and time functions such as Date$ and Time$. For descriptions of Visual Basic functions, see the Visual Basic documentation.

When SentTime is displayed, Visual Basic automatically converts the parameter's value to the local system time and system date.

You can also retrieve the sent time of a message using Message Queuing function calls.

For information on | See
Retrieving the sent time using Message Queuing function calls | PROPID_M_SENTTIME

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQMessage, PROPID_M_SENTTIME


MSMQMessage.Signature

(Introduced in MSMQ 2.0.) The Signature property of the MSMQMessage object specifies the MSMQ 1.0 signature used to authenticate the message.

Type: | Variant (array of bytes)
Run time: | Read/write

messageObject.Signature

Parameters

messageObject
Message (MSMQMessage) object that defines the message.

Setting

Digital Signature.

Remarks

In most cases, MSMQMessage.Signature is set by the Message Queuing run time when the sending application requests authentication (this property can also be set by connector applications sending messages to MSMQ). In these cases, only the receiving application will use this property to retrieve the MSMQ 1.0 signature attached to the message.

Using MSMQ 1.0 signatures

Note that the sending application must specify MSMQ 1.0 signatures when requesting authentication.

Using MSMQ 2.0 signatures

If the sending application sent an MSMQ 2.0 signature, this property will contain a buffer of 4 zeroed bytes.

Connector Applications

Connector applications may also set this property when they call MSMQMessage.Send. However, when a connector application sets this property, Message Queuing does not generate the digital signature. The connector application must generate the digital signature itself based on the certificate of the user sending the message.

When connector applications set MSMQMessage.Signature, the MSMQMessage.ConnectorTypeGuid property must also be set so that Message Queuing does not generate a signature. MSMQMessage.Signature is ignored if MSMQMessage.ConnectorTypeGuid is not also set when the message is sent.

Visual Basic arrays

When dimensioning arrays for the signature, always set the lower boundary of the array to 0. When filling in the signature, Message Queuing sets the lower boundary of the returned byte-array to 0 regardless of what boundary was set by the application.

The following Visual Basic call will always return 0.

LBound(msg.Signature)

Equivalent API function property

When using API functions, the signature of the message can be set and retrieved using the PROPID_M_SIGNATURE property.

For information on | See
How Message Queuing creates digital signatures | How Message Queuing Authenticates Messages
MSMQ 1.0 signatures | Digital Signatures

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQMessage, PROPID_M_SIGNATURE


MSMQMessage.SourceMachineGuid

(Read-only.)The SourceMachineGuid property of the MSMQMessage object provides the identifier of the source computer that sent the message.

Type: | String (GUID format)
Run time: | Read-only

messageObject.SourceMachineGuid

Parameters

messageObject
Message (MSMQMessage) object that defines the message.

Return Values

String that includes the GUID of the source computer.

Remarks

MSMQMessage.SourceMachineGuid can be used by the receiving application when it needs to know the identifier of the computer that sent the message. For example, the receiving application can use the returned identifier to generate the name of the source computer using the MSMQApplication.MachineNameOfMachineId method.

Format of returned identifier

The string returned by this property does not include the braces normally used with GUIDs. The format of the source machine GUID string is shown below

12345678-1234-1234-1234-123456789012

Null characters in strings

Message Queuing COM components ignore any characters that follow the first Null character in a string without returning an error.

Equivalent API function property

When using API functions, the identifier of the source computer can be set and retrieved using the PROPID_M_SRC_MACHINE_ID property.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQApplication.MachineNameOfMachineId, MSMQMessage, PROPID_M_SRC_MACHINE_ID


MSMQMessage.SOAPEnvelope

(Introduced in MSMQ 3.0.)The SOAPEnvelope property of the MSMQMessage object provides the SOAP envelope (not including binary attachments) attached to the message.

Type: | Variant
Run time: | Read-only

messageObject.SOAPEnvelope

Parameters

messageObject
Message (MSMQMessage) object that defines the message.

Return Values

An array of bytes that represent the SOAP envelope.

Remarks

MSMQMessage.SOAPEnvelope is used only when retrieving HTTP messages. When an HTTP message is sent, the sending queue manager attaches the SOAP envelope and, when applicable, the SOAP attachments to the message.

SOAP Attachments

To retrieve SOAP attachments, see MSMQMessage.CompoundMessage.

Equivalent API function property

When using API functions, you can retrieve the SOAP envelope by using the PROPID_M_SOAP_ENVELOPE property.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQMessage, MSMQMessage.CompoundMessage, PROPID_M_SOAP_ENVELOPE


MSMQMessage.Trace

The Trace property of the MSMQMessage object specifies how Message Queuing traces the route of the message.

Type: | Long
Run time: | Read/write

messageObject.Trace

Parameters

messageObject
Message (MSMQMessage) object that defines the message.

Property Values

The Trace property can be set to one of the following values:

MQMSG_SEND_ROUTE_TO_REPORT_QUEUE
Tracing is requested. Each hop made by the original message generates a report message that is sent to a report queue.
MQMSG_TRACE_NONE
The default. Tracing is not requested.

Remarks

When tracing is enabled and a report queue is specified, report messages are created and sent to the report queue each time the message leaves or arrives at a Message Queuing computer. For example, report messages are generated at the following time.

  • When the message leaves the source computer one report message is generated.
  • When the message arrives at and leaves a routing server two report messages are generated.
  • When the message arrives the target computer where the destination queue resides one report message is generated.

Report queues are specified by the computer. If MQMSG_SEND_ROUTE_TO_REPORT_QUEUE is specified but the report queue is not specified, this property is ignored.

Note Message Queuing does not support tracing under the following conditions.

  • When you send messages to multiple destinations using distribution lists, multicast addresses, and multiple-element format names.
  • When you send HTTP messages.

Equivalent API function property

When using API functions, you can set the tracing level of the message using the PROPID_M_TRACE property.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQMessage, PROPID_M_TRACE


MSMQMessage.TransactionId

(Introduced in MSMQ 2.0.) Read-only. The TransactionId property provides the identifier of the transaction that sent the message.

Type: | Variant (array of bytes)
Run time: | Read-only

messageObject.TransactionId

Parameters

messageObject
Message (MSMQMessage) object from queue.

Return Values

20-byte transaction identifier (array of bytes).

Remarks

The MSMQMessage.TransactionId property is used by receiving applications to verify that a message was sent as part of a specific transaction. The transaction identifier is a 20-byte identifier that includes the computer identifier of the sending machine (first 16 bits) followed by a 4-byte transaction sequence number.

Transaction identifiers are not guaranteed to be unique because the transaction sequence numbers are not persistent, and they start over again at 2^20. Message Queuing guarantees only that subsequent transactions will have different transaction sequence numbers.

Transaction boundaries

You can use TransactionId along with two transaction boundary properties to verify transaction boundaries. These two properties (MSMQMessage.IsFirstInTransaction and MSMQMessage.IsLastInTransaction) are properties for checking the first and last message sent in a transaction.

Visual Basic arrays

When dimensioning arrays for the transaction identifier, always set the lower boundary of the array to 0. When filling in the identifier, Message Queuing sets the lower boundary of the returned byte-array to 0 regardless of what boundary was set by the application.

The following Visual Basic call will always return 0.

LBound(msg.TransactionId)

Equivalent API function property

When using API functions, the symmetric key of the message can be set and retrieved using the PROPID_M_XACTIDproperty.

For information on | See
How transaction boundaries can be used | Checking for Transaction Boundaries when Receiving Messages

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQMessage


MSMQMessage.TransactionStatusQueueInfo

(Introduced in MSMQ 2.0.) The TransactionStatusQueueInfo property of the MSMQMessage object specifies the transaction status queue on the source computer. It is used only by connector applications when retrieving transactional messages sent to a foreign queue.

Type: | MSMQQueueInfo
Run time: | read

messageObject.TransactionStatusQueueInfo

Parameters

messageObject
Message (MSMQMessage) object that defines the message.

Property Values

MSMQQueueInfo object of transaction status queue.

Remarks

TransactionStatusQueueInfo is set by MSMQ. Connector applications can then use this object to send positive (read receipt) or negative acknowledgment messages back to the sending application. The transaction status queue should receive these acknowledgments even if the sending application does not request other acknowledgments.

For information on | See
Retrieving the transaction status queue when using Message Queuing function calls | PROPID_M_XACT_STATUS_QUEUE

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQMessage, PROPID_M_XACT_STATUS_QUEUE


MSMQQuery

The MSMQQuery object provides a method for querying the directory service for existing public queues.

Queries can be based on one or more of the following queue properties.

  • Queue identifier
  • Service type
  • Queue label
  • Create time
  • Modify time
  • Multicast address

Query results

The results of the query, referred to as a collection of queues, is returned as an MSMQQueueInfos object.

Methods

The following table lists the methods of the MSMQQuery object.

Method | Description
LookupQueue | Returns a collection of public queues.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQQueueInfos


MSMQQuery.LookupQueue

The LookupQueue method of the MSMQQuery object returns a collection of public queues based on the following queue properties: queue identifier, service type, label, create time, and modify time.

queryObject.LookupQueue( _
  [QueueGuid] _
  [, ServiceTypeGuid] _
  [, Label] _
  [, CreateTime] _
  [, ModifyTime] _
  [, RelServiceType] _
  [, RelLabel] _
  [, RelCreateTime] _
  [, RelModifyTime] _
  [, MulticastAddress] _
  [, RelMulticastAddress] _
)

Parameters

queryObject
MSMQQuery.
QueueGuid
Optional. Identifier of the queue.
ServiceTypeGuid
Optional. Type of service provided by the queue. See also RelServiceType.
Label
Optional. Label of queue. See also RelLabel.
CreateTime
Optional. Time when queue was created. See also RelCreateTime.
ModifyTime
Optional. Time when queue properties were last set (both when the queue was created and the last time MSMQQueueInfo.Update was called). See also RelModifyTime.
RelServiceType
Optional (default is REL_EQ). Relationship parameter for ServiceTypeGuid.
RelLabel
Optional (default is REL_EQ). Relationship parameter for Label.
RelCreateTime
Optional (default is REL_EQ). Relationship parameter for CreateTime.
RelModifyTime
Optional (default is REL_EQ). Relationship parameter for ModifyTime.
MulticastAddress
Optional. Multicast address associated with the queue. If this parameter is specified with an empty string, Message Queuing returns all queues that are not associated with any multicast address. See also RelMulticastAddress.
RelMulticastAddress
Optional (default is REL_EQ). Relationship parameter for MulticastAddress.

Return Values

MSMQQueueInfos object.

For information on return codes, see Message Queuing Error and Information Codes.

Remarks

LookupQueue returns a single MSMQQueueInfos object that represents a set of MSMQQueueInfo objects that each contain information describing a single public queue.

The relationship parameters RelServiceType, RelLabel, RelCreateTime, RelModifyTime provide simple Boolean comparison operators that can be used in conjunction with their respective lookup parameter. These comparison operators include: REL_EQ, REL_NEQ, REL_LT, REL_GT, REL_LE, REL_GE, and REL_NOP (REL_NOP indicates that the associated lookup parameter should be ignored). These operators give you greater control over which queues are returned from to the query.

The CreateTime and ModifyTime parameters return both the date and time. Consequently, using the REL_EQ value for RelCreateTime or RelModifyTime may not prove very useful.

When running a query, Message Queuing can locate queues faster when the query is based on MSMQQueueInfo.QueueGuid, MSMQQueueInfo.ServiceTypeGuid, or MSMQQueueInfo.Label (RelLabel = REL_EQ). The query runs faster because these properties are indexed in the directory service, providing a faster way for Message Queuing to locate the property specified in the call.

MSMQQuery.LookupQueue can return only those queues that are listed in the directory service when LookupQueue is called. Queues created after LookupQueue is called are not included.

To reference a specific queue in the collection, the application must call the MSMQQueueInfos.Reset and MSMQQueueInfos.Next methods. MSMQQueueInfos.Reset points the cursor to the front of the collections (not the first queue in the query) and MSMQQueueInfos.Next points to the next queue. Once the queue is located, the application can call the MSMQQueueInfo.Open method to open the queue.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQQueueInfo.Open, MSMQQueueInfos.Next MSMQQueueInfos.Reset, MSMQQuery


MSMQQueue

The MSMQQueue object represents an open instance of the queue. The MSMQQueue object provides the methods needed to read the messages in the queue and the properties needed to manage the open queue.

For information on opening the queue, see the MSMQQueueInfo.Open method.

Methods

The following table lists the methods of the MSMQQueue object.

Method | Description
Close | Closes this instance of the queue.
EnableNotification | Starts event notification for asynchronously reading messages in the queue.
Peek | Returns the first message in the queue, or waits for a message to arrive if the queue is empty.
PeekByLookupId | (Introduced in MSMQ 3.0.) Returns the message referenced by the supplied lookup identifier.
PeekCurrent | Returns the current message, depending on the position of the cursor.
PeekFirstByLookupId | (Introduced in MSMQ 3.0.) Returns the first message in the queue. Used when navigating the queue using lookup identifiers.
PeekLastByLookupId | (Introduced in MSMQ 3.0.) Returns the last message in the queue. Used when navigating the queue using lookup identifiers.
PeekNext | Returns the next message in the queue but does not remove it from the queue.
PeekNextByLookupId | (Introduced in MSMQ 3.0.) Returns the message that follows the message referenced by the supplied message lookup identifier.
PeekPreviousByLookupId | (Introduced in MSMQ 3.0.) Returns the message that precedes the message referenced by the supplied message lookup identifier.
Receive | Retrieves the first message in the queue, removing the message from the queue.
ReceiveByLookupId | (Introduced in MSMQ 3.0.) Retrieves the message referenced by the supplied lookup identifier and removes the message from the queue. Used when navigating the queue using lookup identifiers.
ReceiveCurrent | Reads the message at the current cursor location.
ReceiveFirstByLookupId | (Introduced in MSMQ 3.0.) Returns the first message in the queue and removes the message from the queue. Used when navigating the queue using lookup identifiers.
ReceiveLastByLookupId | (Introduced in MSMQ 3.0.) Returns the last message in the queue. Used when navigating the queue using lookup identifiers and removes the message from the queue. Used when navigating the queue using lookup identifiers.
ReceiveNextByLookupId | (Introduced in MSMQ 3.0.) Returns the message that follows the message referenced by the supplied message lookup identifier and removes the message from the queue. Used when navigating the queue using lookup identifiers.
ReceivePreviousByLookupId | (Introduced in MSMQ 3.0.) Returns the message that precedes the message referenced by the supplied message lookup identifier and removes the message from the queue. Used when navigating the queue using lookup identifiers.
Reset | Returns the cursor to the start of the of a queue.

Properties

The following table lists the properties of the MSMQQueue object and gives their access, whether read-only or read/write; their data type; and a description.

Property | Description
Access Access: Read only Data type: Long | Provides the access rights of the open queue.
Handle Access: Read-only Data type: Long | Provides the handle of the opened queue.
IsOpen Access: Read-only Data type: Short | Provides an indication of whether or not the queue is open.
QueueInfo Access: Read-only Data type: MSMQQueueInfo | Provides an MSMQQueueInfo object that contains the initial settings used to open the queue.
ShareMode Access: Read-only Data type: Long | Provides the share mode of the open queue.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQQueueInfo, MSMQQueueInfo.Create, MSMQQueueInfo.Open


MSMQQueue.Close

The Close method of the MSMQQueue object closes this instance of the queue.

queueObject.Close

Parameters

queueObject
Queue (MSMQQueue) object that represents the open instance of the queue.

Remarks

When Message Queuing successfully closes the queue, it sets the MSMQQueue.Handle property to INVALID_HANDLE_VALUE but does not delete the MSMQQueue object.

Determining if the queue is open

Applications can determine if the queue is open by testing the MSMQMessage.IsOpen property.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQMessage.IsOpen, MSMQQueue, MSMQQueue.Handle, MSMQQueueInfo.Open


MSMQQueue.EnableNotification

The EnableNotification method of the MSMQQueue object starts event notification for asynchronously reading messages in the queue. Once this method is called, applications can asynchronously peek at messages or retrieve them from the queue in a user-defined event handler.

queueObject.EnableNotification ( _
  Event _
  [, Cursor] _
  [, ReceiveTimeout] _
)

Parameters

queueObject
Queue (MSMQQueue) object that represents the open instance of the queue.
Event
References an MSMQEvent object.
Cursor
Optional. Specifies the action of the cursor.
MQMSG_FIRST
Default. Notification starts when a message is in the queue.
MQMSG_CURRENT
Notification starts when a message is at the current location of the cursor.
MQMSG_NEXT
The cursor is moved, then notification starts when a message is at the new cursor location.
ReceiveTimeout
Optional. Specifies how long (in milliseconds) Message Queuing waits for a message to arrive. This parameter can be set to infinite (-1), 0, or a specific amount of time. The default setting is infinite.

Return Values

For information on return codes, see Message Queuing Error and Information Codes.

Remarks

When MSMQQueue.EnableNotification is called, events are triggered when a message is found at the position specified by Cursor. When the default setting is used, events are triggered when a message is in the queue.

For information on navigating queues with cursors, see Navigating with Cursors.

MSMQQueue.EnableNotification fires a single MSMQEvent.Arrived event when it finds a message. To read more messages, MSMQQueue.EnableNotification must be explicitly called again from within the event handler.

The Arrived event

The Arrived event is triggered on the MSMQEvent object passed in Event. The MSMQEvent_Arrived event handler (typically implemented by the user) is passed a reference to the queue where the message arrived.

Note In Microsoft® Visual Basic®, the application's event handler can still be invoked even if the form it is on has been unloaded by the application. When the event handler is fired, Visual Basic reloads the form automatically if any of its members (for example, a message box on the form) are referred to.

When an Arrived event is triggered, there is no guarantee that the message that triggered the event will still be available when the application tries to use the message. All queues are dynamic, and other clients may remove the arrived message before it can be used. It is up to the application to determine if the message is there before attempting to peek at the message or retrieve it. (If the queue is not being shared, it is safe to assume that the message is still there.)

Setting the ReceiveTimeout parameter to zero

Invoking EnableNotification with ReceiveTimeout set to infinite (-1) blocks processing until a message is in the queue (this is the default setting). If ReceiveTimeout is set to "0", an Arrived event is fired if a message is in the queue, or an ArrivedError event is fired immediately returning an MQ_ERROR_IO_TIMEOUT error.

Receive errors

Receive errors (such as time-out errors) trigger an MSMQEvent.ArrivedError event on the associated MSMQEvent object.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQEvent, MSMQEvent.Arrived, MSMQEvent.ArrivedError, MSMQQueue, MSMQQueue.Peek


MSMQQueue.Peek

The Peek method of the MSMQQueue object returns the first message in the queue, or waits for a message to arrive if the queue is empty. It does not remove the message from the queue.

set messageObject = queueObject.Peek( _
  [WantDestinationQueue] _
  [, WantBody] _
  [, ReceiveTimeout] _
  [, WantConnectorType] _
)

Parameters

messageObject
Message (MSMQMessage) object that represents the message read from the queue.
queueObject
Queue (MSMQQueue) object that represents the queue where the message resides.
WantDestinationQueue
Optional (default is FALSE). If TRUE, MSMQMessage.DestinationQueueInfo is updated when the message is read from the queue. Setting this property to TRUE may slow down the operation of the application.
WantBody
Optional (default is TRUE). If the Body of the message is not needed, set this property to FALSE to optimize the speed of the application.
ReceiveTimeout
Optional. Specifies how long (in milliseconds) Message Queuing waits for a message to arrive.
WantConnectorType
Optional (default is FALSE). Set to TRUE if the receiving application wants to retrieve the MSMQMessage.ConnectorTypeGuid property. By default, Message Queuing does not retrieve the MSMQMessage.ConnectorTypeGuid property when it retrieves a message from the queue.

Return Values

MSMQMessage object (or Null message object if no message is available).

Remarks

MSMQQueue.Peek looks at the first message in the queue. It does not use the cursor created when the queue is opened and should not be called when you are using MSMQQueue.PeekCurrent, MSMQQueue.PeekNext, or MSMQQueue.ReceiveCurrent to navigate through the queue.

ReceiveTimeout parameter

The ReceiveTimeout parameter is optional. If a timeout period is specified and a timeout occurs, a Null message object is returned to the application. However, if a timeout period is not specified the default value of ReceiveTimeout (INFINITE) forces the MSMQQueue.Peek call to block execution until a message arrives.

WantDestinationQueue and WantBody parameters

The WantDestinationQueue and WantBody parameters can be used to optimize the speed of the application.

Message body type

When peeking at message, you cannot look at the type of message body included in the message. Message Queuing will determine the body type based on the message's body type property (the body type property of the messages can be accessed only with Message Queuing functions). However, if the message was sent using MQSendMessage, the following situations can occur.

  • If the body type property was not set before MQSendMessage was called, the message body is treated as an array of bytes.
  • If the body type was set to an invalid body type (for valid types, see Message Body Types) before MQSendMessage was called, the message can be retrieved, but an error will occur when you try to read the message body.

Peeking at Messages Asynchronously

The MSMQEvent object, used to read messages asynchronously, is implemented in terms of callbacks, and is limited to 64 callbacks per process. Internally, Message Queuing uses the WaitForMultipleObjects function which is limited to 64 objects per process.

Responding to Messages

The receiving application can determine if the sending application expects a response messages by retrieving the MSMQMessage.ResponseDestination (introduced in MSMQ 3.0) or MSMQMessage.ResponseQueueInfo property when reading the message. If the property is set to Null, the sending application is not expecting a response message. For information on requesting and returning response messages, see Response Messages.

Opening queues

Applications can peek at messages in queues opened with peek or receive access (see MSMQQueueInfo.Open).

Opening a queue with peek access requires a direct connection to the computer where the queue resides. You cannot peek at the messages in a queue that resides on a computer that has no direct connection to the computer where your application is running.

Equivalent API Function

When using API function calls, use MQReceiveMessage to peek at messages in the queue. To peek at messages using this function, set the dwAction parameter to the appropriate value.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQMessage, MSMQMessage.DestinationQueueInfo, MSMQMessage.ResponseQueueInfo, MSMQMessage.ResponseQueueInfo, MSMQMessage.Send, MSMQQueue, MSMQQueueInfo, MSMQQueue.PeekCurrent, MSMQQueue.PeekNext, MSMQQueue.ReceiveCurrent


MSMQQueue.PeekByLookupId

(Introduced in MSMQ 3.0.) The PeekByLookupId method of the MSMQQueue object returns the message referenced by the supplied lookup identifier.

set messageObject = queueObject.PeekByLookupId( _
  LookupId
  [, WantDestinationQueue] _
  [, WantBody]_
  [, WantConnectorType]_
)

Parameters

messageObject
Message (MSMQMessage) object that represents the message read from the queue.
queueObject
Queue (MSMQQueue) object that represents the queue where the message resides.
LookupId
Lookup identifier of the message.
WantDestinationQueue
Optional (default is FALSE). If TRUE, MSMQMessage.DestinationQueueInfo is updated when the message is read from the queue. Setting this property to TRUE may slow down the operation of the application.
WantBody
Optional (default is TRUE). If the Body of the message is not needed, set this property to FALSE to optimize the speed of the application.
WantConnectorType
Optional (default is FALSE). Set to TRUE if the receiving application wants to retrieve the MSMQMessage.ConnectorTypeGuid property. By default, Message Queuing does not retrieve the MSMQMessage.ConnectorTypeGuid property when it retrieves a message from the queue.

Return Values

MSMQMessage object (or Null message object if no message is available).

Remarks

MSMQQueue.PeekByLookupId is part of a set of methods that can be used to locate messages and navigate the queue without using cursors. For information on all the methods included in this set, see Message Lookup Identifier.

WantDestinationQueue and WantBody parameters

The WantDestinationQueue and WantBody parameters can be used to optimize the speed of the application.

Message body type

When peeking at message, you cannot look at the type of message body included in the message. Message Queuing will determine the body type based on the message's body type property (the body type property of the messages can be accessed only with Message Queuing functions). However, if the message was sent using MQSendMessage, the following situations can occur.

  • If the body type property was not set before MQSendMessage was called, the message body is treated as an array of bytes.
  • If the body type was set to an invalid body type (for valid types, see Message Body Types) before MQSendMessage was called, the message can be retrieved, but an error will occur when you try to read the message body.

Responding to Messages

The receiving application can determine if the sending application expects a response messages by retrieving the MSMQMessage.ResponseDestination (introduced in MSMQ 3.0) or MSMQMessage.ResponseQueueInfo property when reading the message. If the property is set to Null, the sending application is not expecting a response message. For information on requesting and returning response messages, see Response Messages.

Opening queues

Applications can peek at messages in queues opened with peek or receive access (see MSMQQueueInfo.Open).

Opening a queue with peek access requires a direct connection to the computer where the queue resides. You cannot peek at the messages in a queue that resides on a computer that has no direct connection to the computer where your application is running.

Equivalent API Function

When using API function calls, use MQReceiveMessageByLookupId to peek at messages based on their lookup identifier. To peek at messages using this function, set the dwLookupAction parameter to the appropriate value.

Requirements

Windows NT/2000 or later: Requires Whistler.
Windows 95/98/Me: Unsupported.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MQSendMessage, MSMQMessage, MSMQMessage.DestinationQueueInfo, MSMQMessage.LookupId, MSMQMessage.ResponseDestination, MSMQMessage.ResponseQueueInfo, MSMQQueue, MSMQQueueInfo.Open


MSMQQueue.PeekCurrent

The PeekCurrent method of the MSMQQueue object returns the message at the current cursor position, but does not remove the message from the queue.

When PeekCurrent is called, execution is stopped until the message is read from the queue or the receive time-out timer (ReceiveTimeout) expires.

set messageObject = queueObject.PeekCurrent( _
  [WantDestinationQueue] _
  [, WantBody] _
  [, ReceiveTimeout] _
  [, WantConnectorType] _
)

Parameters

messageObject
Message (MSMQMessage) object that represents the message read from the queue.
queueObject
Queue (MSMQQueue) object that represents the queue where the message resides.
WantDestinationQueue
Optional (default is FALSE). If TRUE, MSMQMessage.DestinationQueueInfo is updated when the message is read from the queue. Setting this property to TRUE may slow down the operation of the application.
WantBody
Optional (default is TRUE). If the body of the message is not needed, set this property to FALSE to optimize the speed of the application.
ReceiveTimeout
Optional. Specifies how long (in milliseconds) Message Queuing waits for a message to arrive when the queue is empty or the cursor is pointing at the end of the queue.
WantConnectorType
Optional (default is FALSE). Set to TRUE if the receiving application wants to retrieve the MSMQMessage.ConnectorTypeGuid property. By default, Message Queuing does not retrieve the MSMQMessage.ConnectorTypeGuid property when it retrieves a message from the queue.

Return Values

MSMQMessage object (or Null message object if no message is available).

Remarks

MSMQQueue.PeekCurrent uses the cursor created when the queue is opened to locate the message (this method should not be used when navigating the queue using lookup identifiers). It is typically used with MSMQQueue.PeekNext and MSMQQueue.ReceiveCurrent when navigating through the queue using the cursor.

ReceiveTimeout parameter

The ReceiveTimeout parameter is optional. If a timeout period is specified and a timeout occurs, a Null message object is returned to the application. However, if a timeout period is not specified the default value of ReceiveTimeout (INFINITE) forces the MSMQQueue.PeekCurrent call to block execution until a message arrives.

WantDestinationQueue and WantBody parameters

The WantDestinationQueue and WantBody parameters can be used to optimize the speed of the application.

Message body type

When peeking at message, you cannot look at the type of message body included in the message. Message Queuing will determine the body type based on the message's body type property (the body type property of the messages can be accessed only with Message Queuing functions). However, if the message was sent using MQSendMessage, the following situations can occur.

  • If the body type property was not set before MQSendMessage was called, the message body is treated as an array of bytes.
  • If the body type was set to an invalid body type (for valid types, see Message Body Types) before MQSendMessage was called, the message can be retrieved, but an error will occur when you try to read the message body.

Peeking at Messages Asynchronously

The MSMQEvent object, used to read messages asynchronously, is implemented in terms of callbacks, and is limited to 64 callbacks per process. Internally, Message Queuing uses the WaitForMultipleObjects function which is limited to 64 objects per process.

Responding to Messages

The receiving application can determine if the sending application expects a response messages by retrieving the MSMQMessage.ResponseDestination (introduced in MSMQ 3.0) or MSMQMessage.ResponseQueueInfo property when reading the message. If the property is set to Null, the sending application is not expecting a response message. For information on requesting and returning response messages, see Response Messages.

Opening queues

Applications can peek at messages in queues opened with peek or receive access (see MSMQQueueInfo.Open).

Opening a queue with peek access requires a direct connection to the computer where the queue resides. You cannot peek at the messages in a queue that resides on a computer that has no direct connection to the computer where your application is running.

Equivalent API Function

When using API function calls, use MQReceiveMessage to peek at messages in the queue. To peek at messages using this function, set the dwAction parameter to the appropriate value.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQMessage, MSMQMessage.DestinationQueueInfo, MSMQMessage.ResponseQueueInfo, MSMQQueue, MSMQQueue.PeekNext, MSMQQueue.ReceiveCurrent, MSMQQueueInfo, MSMQQueueInfo.Open


MSMQQueue.PeekFirstByLookupId

(Introduced in MSMQ 3.0.) The PeekFirstByLookupId method of the MSMQQueue object returns the first message in the queue without removing the message.

set messageObject = queueObject.PeekFirstByLookupId( _
  [, WantDestinationQueue] _
  [, WantBody]_
  [, WantConnectorType]_
)

Parameters

messageObject
Message (MSMQMessage) object that represents the message read from the queue.
queueObject
Queue (MSMQQueue) object that represents the queue where the message resides.
WantDestinationQueue
Optional (default is FALSE). If TRUE, MSMQMessage.DestinationQueueInfo is updated when the message is read from the queue. Setting this property to TRUE may slow down the operation of the application.
WantBody
Optional (default is TRUE). If the Body of the message is not needed, set this property to FALSE to optimize the speed of the application.
WantConnectorType
Optional (default is FALSE). Set to TRUE if the receiving application wants to retrieve the MSMQMessage.ConnectorTypeGuid property. By default, Message Queuing does not retrieve the MSMQMessage.ConnectorTypeGuid property when it retrieves a message from the queue.

Return Values

MSMQMessage object (or Null message object if no message is available).

Remarks

MSMQQueue.PeekFirstByLookupId is part of a set of methods that can be used to locate messages and navigate the queue without using cursors. For information on all the methods included in this set, see Message Lookup Identifier.

WantDestinationQueue and WantBody parameters

The WantDestinationQueue and WantBody parameters can be used to optimize the speed of the application.

Message body type

When peeking at message, you cannot look at the type of message body included in the message. Message Queuing will determine the body type based on the message's body type property (the body type property of the messages can be accessed only with Message Queuing functions). However, if the message was sent using MQSendMessage, the following situations can occur.

  • If the body type property was not set before MQSendMessage was called, the message body is treated as an array of bytes.
  • If the body type was set to an invalid body type (for valid types, see Message Body Types) before MQSendMessage was called, the message can be retrieved, but an error will occur when you try to read the message body.

Responding to Messages

The receiving application can determine if the sending application expects a response messages by retrieving the MSMQMessage.ResponseDestination (introduced in MSMQ 3.0) or MSMQMessage.ResponseQueueInfo property when reading the message. If the property is set to Null, the sending application is not expecting a response message. For information on requesting and returning response messages, see Response Messages.

Opening queues

Applications can peek at messages in queues opened with peek or receive access (see MSMQQueueInfo.Open).

Opening a queue with peek access requires a direct connection to the computer where the queue resides. You cannot peek at the messages in a queue that resides on a computer that has no direct connection to the computer where your application is running.

Equivalent API Function

When using API function calls, use MQReceiveMessageByLookupId to peek at messages based on their lookup identifier. To peek at messages using this function, set the dwLookupAction parameter to the appropriate value.

Requirements

Windows NT/2000 or later: Requires Whistler.
Windows 95/98/Me: Unsupported.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MQSendMessage, MSMQMessage, MSMQMessage.DestinationQueueInfo, MSMQMessage.LookupId, MSMQMessage.ResponseDestination, MSMQMessage.ResponseQueueInfo, MSMQQueue, MSMQQueueInfo.Open


MSMQQueue.PeekLastByLookupId

(Introduced in MSMQ 3.0.) The PeekLastByLookupId method of the MSMQQueue object returns the first message in the queue without removing the message.

set messageObject = queueObject.PeekLastByLookupId( _
  [, WantDestinationQueue] _
  [, WantBody]_
  [, WantConnectorType]_
)

Parameters

messageObject
Message (MSMQMessage) object that represents the message read from the queue.
queueObject
Queue (MSMQQueue) object that represents the queue where the message resides.
WantDestinationQueue
Optional (default is FALSE). If TRUE, MSMQMessage.DestinationQueueInfo is updated when the message is read from the queue. Setting this property to TRUE may slow down the operation of the application.
WantBody
Optional (default is TRUE). If the Body of the message is not needed, set this property to FALSE to optimize the speed of the application.
WantConnectorType
Optional (default is FALSE). Set to TRUE if the receiving application wants to retrieve the MSMQMessage.ConnectorTypeGuid property. By default, Message Queuing does not retrieve the MSMQMessage.ConnectorTypeGuid property when it retrieves a message from the queue.

Return Values

MSMQMessage object (or Null message object if no message is available).

Remarks

MSMQQueue.PeekLastByLookupId is part of a set of methods that can be used to locate messages and navigate the queue without using cursors. For information on all the methods included in this set, see Message Lookup Identifier.

WantDestinationQueue and WantBody parameters

The WantDestinationQueue and WantBody parameters can be used to optimize the speed of the application.

Message body type

When peeking at message, you cannot look at the type of message body included in the message. Message Queuing will determine the body type based on the message's body type property (the body type property of the messages can be accessed only with Message Queuing functions). However, if the message was sent using MQSendMessage, the following situations can occur.

  • If the body type property was not set before MQSendMessage was called, the message body is treated as an array of bytes.
  • If the body type was set to an invalid body type (for valid types, see Message Body Types) before MQSendMessage was called, the message can be retrieved, but an error will occur when you try to read the message body.

Responding to Messages

The receiving application can determine if the sending application expects a response messages by retrieving the MSMQMessage.ResponseDestination (introduced in MSMQ 3.0) or MSMQMessage.ResponseQueueInfo property when reading the message. If the property is set to Null, the sending application is not expecting a response message. For information on requesting and returning response messages, see Response Messages.

Opening queues

Applications can peek at messages in queues opened with peek or receive access (see MSMQQueueInfo.Open).

Opening a queue with peek access requires a direct connection to the computer where the queue resides. You cannot peek at the messages in a queue that resides on a computer that has no direct connection to the computer where your application is running.

Equivalent API Function

When using API function calls, use MQReceiveMessageByLookupId to peek at messages based on their lookup identifier. To peek at messages using this function, set the dwLookupAction parameter to the appropriate value.

Requirements

Windows NT/2000 or later: Requires Whistler.
Windows 95/98/Me: Unsupported.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MQSendMessage, MSMQMessage, MSMQMessage.DestinationQueueInfo, MSMQMessage.LookupId, MSMQMessage.ResponseDestination, MSMQMessage.ResponseQueueInfo, MSMQQueue, MSMQQueueInfo.Open


MSMQQueue.PeekNext

The PeekNext method of the MSMQQueue object returns the next message after the current cursor position, but does not remove the message from the queue.

When PeekNext is called, execution is stopped until the message is read from the queue or the receive time-out timer (ReceiveTimeout) expires.

set messageObject = queueObject.PeekNext( _
  [WantDestinationQueue] _
  [, WantBody] _
  [, ReceiveTimeout] _
  [, WantConnectorType] _
)

Parameters

messageObject
Message (MSMQMessage) object that represents the message read from the queue.
queueObject
Queue (MSMQQueue) object that represents the queue where the message resides.
WantDestinationQueue
Optional (default is FALSE). If TRUE, MSMQMessage.DestinationQueueInfo is updated when the message is read from the queue. Setting this property to TRUE may slow down the operation of the application.
WantBody
Optional (default is TRUE). If the Body of the message is not needed, set this property to FALSE to optimize the speed of the application.
ReceiveTimeout
Optional. Specifies how long (in milliseconds) Message Queuing waits for a message to arrive when the cursor is pointing at the end of the queue.
WantConnectorType
Optional (default is FALSE). Set to TRUE if the receiving application wants to retrieve the MSMQMessage.ConnectorTypeGuid property. By default, Message Queuing does not retrieve the MSMQMessage.ConnectorTypeGuid property when it retrieves a message from the queue.

Return Values

MSMQMessage object (or Null message object if no message is available).

Remarks

MSMQQueue.PeekNext uses the cursor created when the queue is opened to locate the message (this method should not be used when navigating the queue using lookup identifiers). It is typically used with MSMQQueue.PeekCurrent and MSMQQueue.ReceiveCurrent when navigating through the queue.

MSMQQueue.PeekNext moves the cursor first and then looks at the message at the new location.

Before calling MSMQQueue.PeekNext

The MSMQQueue.PeekCurrent method must be called to point the cursor to the first message in the queue. If MSMQQueue.PeekNext is called before MSMQQueue.PeekCurrent is not called, MQ_ERROR_ILLEGAL CURSOR_ACTION is returned.

ReceiveTimeout parameter

The ReceiveTimeout parameter is optional. If a timeout period is specified and a timeout occurs, a Null message object is returned to the application. However, if a timeout period is not specified the default value of ReceiveTimeout (INFINITE) forces the MSMQQueue.PeekCurrent call to block execution until a message arrives.

WantDestinationQueue and WantBody parameters

The WantDestinationQueue and WantBody parameters can be used to optimize the speed of the application.

Message body type

When peeking at message, you cannot look at the type of message body included in the message. Message Queuing will determine the body type based on the message's body type property (the body type property of the messages can be accessed only with Message Queuing functions). However, if the message was sent using MQSendMessage, the following situations can occur.

  • If the body type property was not set before MQSendMessage was called, the message body is treated as an array of bytes.
  • If the body type was set to an invalid body type (for valid types, see Message Body Types) before MQSendMessage was called, the message can be retrieved, but an error will occur when you try to read the message body.

Peeking at Messages Asynchronously

The MSMQEvent object, used to read messages asynchronously, is implemented in terms of callbacks, and is limited to 64 callbacks per process. Internally, Message Queuing uses the WaitForMultipleObjects function which is limited to 64 objects per process.

Responding to Messages

The receiving application can determine if the sending application expects a response messages by retrieving the MSMQMessage.ResponseDestination (introduced in MSMQ 3.0) or MSMQMessage.ResponseQueueInfo property when reading the message. If the property is set to Null, the sending application is not expecting a response message. For information on requesting and returning response messages, see Response Messages.

Opening queues

Applications can peek at messages in queues opened with peek or receive access (see MSMQQueueInfo.Open).

Opening a queue with peek access requires a direct connection to the computer where the queue resides. You cannot peek at the messages in a queue that resides on a computer that has no direct connection to the computer where your application is running.

Equivalent API Function

When using API function calls, use MQReceiveMessage to peek at messages in the queue. To peek at messages using this function, set the dwAction parameter to the appropriate value.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQMessage, MSMQMessage.DestinationQueueInfo, MSMQMessage.ResponseQueueInfo, MSMQQueue, MSMQQueue.PeekCurrent, MSMQQueue.ReceiveCurrent, MSMQQueueInfo, MSMQQueueInfo.Open


MSMQQueue.PeekNextByLookupId

(Introduced in MSMQ 3.0.) The PeekNextByLookupId method of the MSMQQueue object returns the message that follows the message referenced by the supplied message lookup identifier.

set messageObject = queueObject.PeekNextByLookupId( _
  LookupId
  [, WantDestinationQueue] _
  [, WantBody]_
  [, WantConnectorType]_
)

Parameters

messageObject
Message (MSMQMessage) object that represents the message read from the queue.
queueObject
Queue (MSMQQueue) object that represents the queue where the message resides.
LookupId
Lookup identifier of the message.
WantDestinationQueue
Optional (default is FALSE). If TRUE, MSMQMessage.DestinationQueueInfo is updated when the message is read from the queue. Setting this property to TRUE may slow down the operation of the application.
WantBody
Optional (default is TRUE). If the Body of the message is not needed, set this property to FALSE to optimize the speed of the application.
WantConnectorType
Optional (default is FALSE). Set to TRUE if the receiving application wants to retrieve the MSMQMessage.ConnectorTypeGuid property. By default, Message Queuing does not retrieve the MSMQMessage.ConnectorTypeGuid property when it retrieves a message from the queue.

Return Values

MSMQMessage object (or Null message object if no message is available).

Remarks

MSMQQueue.PeekNextByLookupId is part of a set of methods that can be used to locate messages and navigate the queue without using cursors. For information on all the methods included in this set, see Message Lookup Identifier.

WantDestinationQueue and WantBody parameters

The WantDestinationQueue and WantBody parameters can be used to optimize the speed of the application.

Message body type

When peeking at message, you cannot look at the type of message body included in the message. Message Queuing will determine the body type based on the message's body type property (the body type property of the messages can be accessed only with Message Queuing functions). However, if the message was sent using MQSendMessage, the following situations can occur.

  • If the body type property was not set before MQSendMessage was called, the message body is treated as an array of bytes.
  • If the body type was set to an invalid body type (for valid types, see Message Body Types) before MQSendMessage was called, the message can be retrieved, but an error will occur when you try to read the message body.

Responding to Messages

The receiving application can determine if the sending application expects a response messages by retrieving the MSMQMessage.ResponseDestination (introduced in MSMQ 3.0) or MSMQMessage.ResponseQueueInfo property when reading the message. If the property is set to Null, the sending application is not expecting a response message. For information on requesting and returning response messages, see Response Messages.

Opening queues

Applications can peek at messages in queues opened with peek or receive access (see MSMQQueueInfo.Open).

Opening a queue with peek access requires a direct connection to the computer where the queue resides. You cannot peek at the messages in a queue that resides on a computer that has no direct connection to the computer where your application is running.

Equivalent API Function

When using API function calls, use MQReceiveMessageByLookupId to peek at messages based on their lookup identifier. To peek at messages using this function, set the dwLookupAction parameter to the appropriate value.

Requirements

Windows NT/2000 or later: Requires Whistler.
Windows 95/98/Me: Unsupported.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MQSendMessage, MSMQMessage, MSMQMessage.DestinationQueueInfo, MSMQMessage.LookupId, MSMQMessage.ResponseDestination, MSMQMessage.ResponseQueueInfo, MSMQQueue, MSMQQueueInfo.Open


MSMQQueue.PeekPreviousByLookupId

(Introduced in MSMQ 3.0.) The PeekPreviousByLookupId method of the MSMQQueue object returns the message that precedes the message referenced by the supplied message lookup identifier.

set messageObject = queueObject.PeekPreviousByLookupId( _
  LookupId
  [, WantDestinationQueue] _
  [, WantBody] _
  [, WantConnectorType]_
)

Parameters

messageObject
Message (MSMQMessage) object that represents the message read from the queue.
queueObject
Queue (MSMQQueue) object that represents the queue where the message resides.
LookupId
Lookup identifier of the message. Note that this identifier does not reference the message that is returned.
WantDestinationQueue
Optional (default is FALSE). If TRUE, MSMQMessage.DestinationQueueInfo is updated when the message is read from the queue. Setting this property to TRUE may slow down the operation of the application.
WantBody
Optional (default is TRUE). If the Body of the message is not needed, set this property to FALSE to optimize the speed of the application.
WantConnectorType
Optional (default is FALSE). Set to TRUE if the receiving application wants to retrieve the MSMQMessage.ConnectorTypeGuid property. By default, Message Queuing does not retrieve the MSMQMessage.ConnectorTypeGuid property when it retrieves a message from the queue.

Return Values

MSMQMessage object (or Null message object if no message is available).

Remarks

MSMQQueue.PeekPreviousByLookupId is part of a set of methods that can be used to locate messages and navigate the queue without using cursors. For information on all the methods included in this set, see Message Lookup Identifier.

WantDestinationQueue and WantBody parameters

The WantDestinationQueue and WantBody parameters can be used to optimize the speed of the application.

Message body type

When peeking at message, you cannot look at the type of message body included in the message. Message Queuing will determine the body type based on the message's body type property (the body type property of the messages can be accessed only with Message Queuing functions). However, if the message was sent using MQSendMessage, the following situations can occur.

  • If the body type property was not set before MQSendMessage was called, the message body is treated as an array of bytes.
  • If the body type was set to an invalid body type (for valid types, see Message Body Types) before MQSendMessage was called, the message can be retrieved, but an error will occur when you try to read the message body.

Responding to Messages

The receiving application can determine if the sending application expects a response messages by retrieving the MSMQMessage.ResponseDestination (introduced in MSMQ 3.0) or MSMQMessage.ResponseQueueInfo property when reading the message. If the property is set to Null, the sending application is not expecting a response message. For information on requesting and returning response messages, see Response Messages.

Opening queues

Applications can peek at messages in queues opened with peek or receive access (see MSMQQueueInfo.Open).

Opening a queue with peek access requires a direct connection to the computer where the queue resides. You cannot peek at the messages in a queue that resides on a computer that has no direct connection to the computer where your application is running.

Equivalent API Function

When using API function calls, use MQReceiveMessageByLookupId to peek at messages based on their lookup identifier. To peek at messages using this function, set the dwLookupAction parameter to the appropriate value.

Requirements

Windows NT/2000 or later: Requires Whistler.
Windows 95/98/Me: Unsupported.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MQSendMessage, MSMQMessage, MSMQMessage.DestinationQueueInfo, MSMQMessage.LookupId, MSMQMessage.ResponseDestination, MSMQMessage.ResponseQueueInfo, MSMQQueue, MSMQQueueInfo.Open


MSMQQueue.Receive

The Receive method of the MSMQQueue object retrieves the first message in the queue, removing the message from the queue when the message is read.

set messageObject = queueObject.Receive( _
  [Transaction] _
  [, WantDestinationQueue] _
  [, WantBody] _
  [, ReceiveTimeout] _
  [, WantConnectorType] _
)

Parameters

messageObject
Message (MSMQMessage) object that represents the message retrieved from the queue.
queueObject
Queue (MSMQQueue) object that represents queue where the message resides.
Transaction
Optional. An MSMQTransaction object or one of the following constants:

MQ_NO_TRANSACTION: Specifies that the call is not part of a transaction.

MQ_MTS_TRANSACTION: Default. Specifies that the call is part of the current MTS (Microsoft Transaction Server) transaction.

MQ_XA_TRANSACTION: Specifies that the call is part of an externally coordinated, XA-compliant transaction.

WantDestinationQueue
Optional (default is FALSE). If TRUE, MSMQMessage.DestinationQueueInfo is updated when the message is read from the queue. Setting this property to TRUE may slow down the operation of the application.
WantBody
Optional (default is TRUE). If you do not need to retrieve the body of the message, set this property to FALSE to optimize the speed of the application.
ReceiveTimeout
Optional (default is INFINITE). Specifies how long (in milliseconds) Message Queuing waits for a message to arrive.
WantConnectorType
Optional (default is FALSE). Set to TRUE if the receiving application wants to retrieve the MSMQMessage.ConnectorTypeGuid property. By default, Message Queuing does not retrieve the MSMQMessage.ConnectorTypeGuid property when it retrieves a message from the queue.

Return Values

MSMQMessage object (or Null message object if no message is available).

Remarks

MSMQQueue.Receive retrieves the first message in the queue. It does not use the cursor created when the queue is opened, and should not be called when navigating the queue using the cursor.

ReceiveTimeout parameter

The ReceiveTimeout parameter is optional. If a timeout period is specified and a timeout occurs, a Null message object is returned to the application. However, if a timeout period is not specified the default value of ReceiveTimeout (INFINITE) forces the MSMQQueue.Peek call to block execution until a message arrives.

WantDestinationQueue and WantBody parameters

The WantDestinationQueue and WantBody parameters can be used to optimize the speed of the application.

Retrieving Messages Synchronously

For synchronous calls, execution is stopped until a message is retrieved from the queue or the message's timeout timer expires.

Retrieving Messages Asynchronously

The MSMQEvent object, used to read messages asynchronously, is implemented in terms of callbacks, and is limited to 64 callbacks per process. Internally, Message Queuing uses the WaitForMultipleObjects function which is limited to 64 objects per process.

Retrieving Message in Transactions

To retrieve a message within a transaction, set the Transaction parameter to an MSMQTransaction object or to one of the constants described in the preceding table, or use its default setting (the default setting of Transaction is MQ_MTS_TRANSACTION). If you need to guarantee that no transaction will be used (for example, if you are retrieving a message from a non-transactional queue within a transactional MTS component), set Transaction to MQ_NO_TRANSACTION.

Messages cannot be retrieved from remote queues within a transaction.

Message Queuing performs the following tasks when a transaction is specified.

  • In the case of a subsequent Abort, the message is returned to its original place in the queue.
  • In the case of a Commit, a positive acknowledgment message is sent to the administration queue of the sending application. The class property of the acknowledgment message is MQMSG_CLASS_ACK_RECEIVE.

Transaction objects cannot be reused after you commit to or abort the transaction. If you release the transaction object without calling Commit or Abort, the transaction is automatically aborted.

Opening queues

To retrieve messages, the queue must be opened with receive access (Access = MQ_RECEIVE_ACCESS). Messages retrieved from a queue are also removed from the queue.

Opening a queue requires a direct connection to the computer where the queue resides. You cannot retrieve messages from a queue that resides on a computer that has no direct connection to the computer where your application is running.

Responding to Messages

The receiving application can determine if the sending application expects a response messages by retrieving the MSMQMessage.ResponseDestination (introduced in MSMQ 3.0) or MSMQMessage.ResponseQueueInfo property when reading the message. If the property is set to Null, the sending application is not expecting a response message. For information on requesting and returning response messages, see Response Messages.

Message body type

When retrieving message, you cannot look at the type of message body included in the message. Message Queuing will determine the body type based on the message's body type property (the body type property of the messages can be accessed only with Message Queuing functions). However, if the message was sent using MQSendMessage, the following situations can occur.

  • If the body type property was not set before MQSendMessage was called, the message body is treated as an array of bytes.
  • If the body type was set to an invalid body type (for valid types, see Message Body Types) before MQSendMessage was called, the message can be retrieved, but an error will occur when you try to read the message body.

Equivalent API Function

When using API function calls, use MQReceiveMessage to retrieve messages in the queue. To retrieve messages using this function, set the dwAction parameter to the appropriate value.

For information on | See
Message Queuing transaction support, including types of transactions | Message Queuing Transactions.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQMessage, MSMQMessage.DestinationQueueInfo, MSMQMessage.ResponseQueueInfo, MSMQQueue, MSMQQueue.Peek, MSMQQueue.PeekCurrent, MSMQQueue.PeekNext, MSMQQueue.ReceiveCurrent, MSMQTransaction


MSMQQueue.ReceiveByLookupId

(Introduced in MSMQ 3.0.) The ReceiveByLookupId method of the MSMQQueue object returns the message referenced by the supplied lookup identifier and removes the message from the queue.

set messageObject = queueObject.ReceiveByLookupId( _
  LookupId
  [,Transaction]
  [, WantDestinationQueue] _
  [, WantBody]_
  [, WantConnectorType]_
)

Parameters

messageObject
Message (MSMQMessage) object that represents the message read from the queue.
queueObject
Queue (MSMQQueue) object that represents the queue where the message resides.
LookupId
Lookup identifier of the message.
Transaction
Optional. An MSMQTransaction object or one of the following constants:

MQ_NO_TRANSACTION: Specifies that the call is not part of a transaction.

MQ_MTS_TRANSACTION: Default. Specifies that the call is part of the current MTS (Microsoft Transaction Server) transaction.

MQ_XA_TRANSACTION: Specifies that the call is part of an externally coordinated, XA-compliant transaction.

WantDestinationQueue
Optional (default is FALSE). If TRUE, MSMQMessage.DestinationQueueInfo is updated when the message is read from the queue. Setting this property to TRUE may slow down the operation of the application.
WantBody
Optional (default is TRUE). If the Body of the message is not needed, set this property to FALSE to optimize the speed of the application.
WantConnectorType
Optional (default is FALSE). Set to TRUE if the receiving application wants to retrieve the MSMQMessage.ConnectorTypeGuid property. By default, Message Queuing does not retrieve the MSMQMessage.ConnectorTypeGuid property when it retrieves a message from the queue.

Return Values

MSMQMessage object (or Null message object if no message is available).

Remarks

MSMQQueue.ReceiveByLookupId is part of a set of methods that can be used to locate messages and navigate the queue without using cursors. For information on all the methods included in this set, see Message Lookup Identifier.

Retrieving message in transactions

To retrieve a message within a transaction, set the Transaction parameter to one of the following.

  • An MSMQTransaction object
  • One of the constants described in the preceding parameter description.
  • Use the default MQ_MTS_TRANSACTION setting of the Transaction parameter.

Message Queuing performs the following tasks when a transaction is specified.

  • In the case of a subsequent Abort, the message is returned to its original place in the queue.
  • In the case of a Commit, a positive acknowledgment message is sent to the administration queue of the sending application. The class property of the acknowledgment message is MQMSG_CLASS_ACK_RECEIVE.

Transaction objects cannot be reused after you commit to or abort the transaction. If you release the transaction object without calling Commit or Abort, the transaction is automatically aborted.

Messages cannot be retrieved from remote queues within a transaction.

WantDestinationQueue and WantBody parameters

The WantDestinationQueue and WantBody parameters can be used to optimize the speed of the application.

Message body type

When peeking at message, you cannot look at the type of message body included in the message. Message Queuing will determine the body type based on the message's body type property (the body type property of the messages can be accessed only with Message Queuing functions). However, if the message was sent using MQSendMessage, the following situations can occur.

  • If the body type property was not set before MQSendMessage was called, the message body is treated as an array of bytes.
  • If the body type was set to an invalid body type (for valid types, see Message Body Types) before MQSendMessage was called, the message can be retrieved, but an error will occur when you try to read the message body.

Responding to Messages

The receiving application can determine if the sending application expects a response messages by retrieving the MSMQMessage.ResponseDestination (introduced in MSMQ 3.0) or MSMQMessage.ResponseQueueInfo property when reading the message. If the property is set to Null, the sending application is not expecting a response message. For information on requesting and returning response messages, see Response Messages.

Opening queues

Applications can peek at messages in queues opened with peek or receive access (see MSMQQueueInfo.Open).

Opening a queue with peek access requires a direct connection to the computer where the queue resides. You cannot peek at the messages in a queue that resides on a computer that has no direct connection to the computer where your application is running.

Equivalent API Function

When using API function calls, use MQReceiveMessageByLookupId to retrieve messages based on their lookup identifier. To retrieve messages using this function, set the dwLookupAction parameter to the appropriate value.

Requirements

Windows NT/2000 or later: Requires Whistler.
Windows 95/98/Me: Unsupported.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MQSendMessage, MSMQMessage, MSMQMessage.DestinationQueueInfo, MSMQMessage.LookupId, MSMQMessage.ResponseDestination, MSMQMessage.ResponseQueueInfo, MSMQQueue, MSMQQueueInfo.Open, MSMQTransaction


MSMQQueue.ReceiveCurrent

The ReceiveCurrent method of the MSMQQueue object returns the message at the current cursor location and removes the message from the queue.

set messageObject = queueObject.ReceiveCurrent( _
  [ Transaction] _
  [, WantDestinationQueue] _
  [, WantBody] _
  [, ReceiveTimeout] _
  [, WantConnectorType] _
)

Parameters

messageObject
Message (MSMQMessage) object that represents the message retrieved from the queue.
queueObject
Queue (MSMQQueue) object that represents the open instance of the queue that is receiving messages.
Transaction
Optional. An MSMQTransaction object or one of the following constants:

MQ_NO_TRANSACTION: Specifies that the call is not part of a transaction.

MQ_MTS_TRANSACTION: Default. Specifies that the call is part of the current MTS (Microsoft Transaction Server) transaction.

MQ_XA_TRANSACTION: Specifies that the call is part of an externally coordinated, XA-compliant transaction.

WantDestinationQueue
Optional (default is FALSE). If TRUE, MSMQMessage.DestinationQueueInfo is updated when the message is read from the queue. Setting this property to TRUE may slow down the operation of the application.
WantBody
Optional (default is TRUE). If do not need the body of the message, set this property to FALSE to optimize the speed of the application.
ReceiveTimeout
Optional. Specifies how long (in milliseconds) Message Queuing waits for a message to arrive.
WantConnectorType
Optional (default is FALSE). Set to TRUE if the receiving application wants to retrieve the MSMQMessage.ConnectorTypeGuid property. By default, Message Queuing does not retrieve the MSMQMessage.ConnectorTypeGuid property when it retrieves a message from the queue.

Return Values

MSMQMessage object (or Null message object if no message is available).

Remarks

MSMQQueue.ReceiveCurrent uses the cursor created when the queue is opened to locate the message (this method should not be used when navigating the queue using lookup identifiers). It uses the cursor created when the queue is opened, and is typically used with MSMQQueue.PeekCurrent and MSMQQueue.PeekNext.

ReceiveTimeout parameter

The ReceiveTimeout parameter is optional. If a timeout period is specified and a timeout occurs, a Null message object is returned to the application. However, if a timeout period is not specified the default value of ReceiveTimeout (INFINITE) forces the MSMQQueue.Peek call to block execution until a message arrives.

WantDestinationQueue and WantBody parameters

The WantDestinationQueue and WantBody parameters can be used to optimize the speed of the application.

Retrieving Messages Synchronously

For synchronous calls, execution is stopped until a message is retrieved from the queue or the message's timeout timer expires.

Retrieving Messages Asynchronously

The MSMQEvent object, used to read messages asynchronously, is implemented in terms of callbacks, and is limited to 64 callbacks per process. Internally, Message Queuing uses the WaitForMultipleObjects function which is limited to 64 objects per process.

Retrieving Message in Transactions

To retrieve a message within a transaction, set the Transaction parameter to an MSMQTransaction object or to one of the constants described in the preceding table, or use its default setting (the default setting of Transaction is MQ_MTS_TRANSACTION). If you need to guarantee that no transaction will be used (for example, if you are retrieving a message from a non-transactional queue within a transactional MTS component), set Transaction to MQ_NO_TRANSACTION.

Messages cannot be retrieved from remote queues within a transaction.

Message Queuing performs the following tasks when a transaction is specified.

  • In the case of a subsequent Abort, the message is returned to its original place in the queue.
  • In the case of a Commit, a positive acknowledgment message is sent to the administration queue of the sending application. The class property of the acknowledgment message is MQMSG_CLASS_ACK_RECEIVE.

Transaction objects cannot be reused after you commit to or abort the transaction. If you release the transaction object without calling Commit or Abort, the transaction is automatically aborted.

Opening queues

To retrieve messages, the queue must be opened with receive access (Access = MQ_RECEIVE_ACCESS). Messages retrieved from a queue are also removed from the queue.

Opening a queue requires a direct connection to the computer where the queue resides. You cannot retrieve messages from a queue that resides on a computer that has no direct connection to the computer where your application is running.

Responding to Messages

The receiving application can determine if the sending application expects a response messages by retrieving the MSMQMessage.ResponseDestination (introduced in MSMQ 3.0) or MSMQMessage.ResponseQueueInfo property when reading the message. If the property is set to Null, the sending application is not expecting a response message. For information on requesting and returning response messages, see Response Messages.

Message body type

When retrieving message, you cannot look at the type of message body included in the message. Message Queuing will determine the body type based on the message's body type property (the body type property of the messages can be accessed only with Message Queuing functions). However, if the message was sent using MQSendMessage, the following situations can occur.

  • If the body type property was not set before MQSendMessage was called, the message body is treated as an array of bytes.
  • If the body type was set to an invalid body type (for valid types, see Message Body Types) before MQSendMessage was called, the message can be retrieved, but an error will occur when you try to read the message body.

Equivalent API Function

When using API function calls, use MQReceiveMessage to retrieve messages in the queue. To retrieve messages using this function, set the dwAction parameter to the appropriate value.

For information on | See
Message Queuing transaction support, including types of transactions | Message Queuing Transactions.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQMessage, MSMQMessage.DestinationQueueInfo, MSMQMessage.ResponseQueueInfo, MSMQQueue, MSMQQueue.PeekCurrent, MSMQQueue.PeekNext, MSMQQueueInfo, MSMQTransaction


MSMQQueue.ReceiveFirstByLookupId

(Introduced in MSMQ 3.0.) The ReceiveFirstByLookupId method of the MSMQQueue object returns the first message in the queue and removes the message from the queue.

set messageObject = queueObject.ReceiveFirstByLookupId( _
  [,Transaction]
  [, WantDestinationQueue] _
  [, WantBody]_
  [, WantConnectorType]_
)

Parameters

messageObject
Message (MSMQMessage) object that represents the message read from the queue.
queueObject
Queue (MSMQQueue) object that represents the queue where the message resides.
Transaction
Optional. An MSMQTransaction object or one of the following constants:

MQ_NO_TRANSACTION: Specifies that the call is not part of a transaction.

MQ_MTS_TRANSACTION: Default. Specifies that the call is part of the current MTS (Microsoft Transaction Server) transaction.

MQ_XA_TRANSACTION: Specifies that the call is part of an externally coordinated, XA-compliant transaction.

WantDestinationQueue
Optional (default is FALSE). If TRUE, MSMQMessage.DestinationQueueInfo is updated when the message is read from the queue. Setting this property to TRUE may slow down the operation of the application.
WantBody
Optional (default is TRUE). If the Body of the message is not needed, set this property to FALSE to optimize the speed of the application.
WantConnectorType
Optional (default is FALSE). Set to TRUE if the receiving application wants to retrieve the MSMQMessage.ConnectorTypeGuid property. By default, Message Queuing does not retrieve the MSMQMessage.ConnectorTypeGuid property when it retrieves a message from the queue.

Return Values

MSMQMessage object (or Null message object if no message is available).

Remarks

MSMQQueue.ReceiveFirstByLookupId is part of a set of methods that can be used to locate messages and navigate the queue without using cursors. For information on all the methods included in this set, see Message Lookup Identifier.

Retrieving message in transactions

To retrieve a message within a transaction, set the Transaction parameter to one of the following.

  • An MSMQTransaction object
  • One of the constants described in the preceding parameter description.
  • Use the default MQ_MTS_TRANSACTION setting of the Transaction parameter.

Message Queuing performs the following tasks when a transaction is specified.

  • In the case of a subsequent Abort, the message is returned to its original place in the queue.
  • In the case of a Commit, a positive acknowledgment message is sent to the administration queue of the sending application. The class property of the acknowledgment message is MQMSG_CLASS_ACK_RECEIVE.

Transaction objects cannot be reused after you commit to or abort the transaction. If you release the transaction object without calling Commit or Abort, the transaction is automatically aborted.

Messages cannot be retrieved from remote queues within a transaction.

WantDestinationQueue and WantBody parameters

The WantDestinationQueue and WantBody parameters can be used to optimize the speed of the application.

Message body type

When peeking at message, you cannot look at the type of message body included in the message. Message Queuing will determine the body type based on the message's body type property (the body type property of the messages can be accessed only with Message Queuing functions). However, if the message was sent using MQSendMessage, the following situations can occur.

  • If the body type property was not set before MQSendMessage was called, the message body is treated as an array of bytes.
  • If the body type was set to an invalid body type (for valid types, see Message Body Types) before MQSendMessage was called, the message can be retrieved, but an error will occur when you try to read the message body.

Responding to Messages

The receiving application can determine if the sending application expects a response messages by retrieving the MSMQMessage.ResponseDestination (introduced in MSMQ 3.0) or MSMQMessage.ResponseQueueInfo property when reading the message. If the property is set to Null, the sending application is not expecting a response message. For information on requesting and returning response messages, see Response Messages.

Opening queues

Applications can peek at messages in queues opened with peek or receive access (see MSMQQueueInfo.Open).

Opening a queue with peek access requires a direct connection to the computer where the queue resides. You cannot peek at the messages in a queue that resides on a computer that has no direct connection to the computer where your application is running.

Equivalent API Function

When using API function calls, use MQReceiveMessageByLookupId to retrieve messages based on their lookup identifier. To retrieve messages using this function, set the dwLookupAction parameter to the appropriate value.

Requirements

Windows NT/2000 or later: Requires Whistler.
Windows 95/98/Me: Unsupported.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MQSendMessage, MSMQMessage, MSMQMessage.DestinationQueueInfo, MSMQMessage.LookupId, MSMQMessage.ResponseDestination, MSMQMessage.ResponseQueueInfo, MSMQQueue, MSMQQueueInfo.Open, MSMQTransaction


MSMQQueue.ReceiveLastByLookupId

(Introduced in MSMQ 3.0.) The ReceiveLastByLookupId method of the MSMQQueue object returns the last message in the queue and removes the message from the queue.

set messageObject = queueObject.ReceiveLastByLookupId( _
  [,Transaction]
  [, WantDestinationQueue] _
  [, WantBody]_
  [, WantConnectorType]_
)

Parameters

messageObject
Message (MSMQMessage) object that represents the message read from the queue.
queueObject
Queue (MSMQQueue) object that represents the queue where the message resides.
Transaction
Optional. An MSMQTransaction object or one of the following constants:

MQ_NO_TRANSACTION: Specifies that the call is not part of a transaction.

MQ_MTS_TRANSACTION: Default. Specifies that the call is part of the current MTS (Microsoft Transaction Server) transaction.

MQ_XA_TRANSACTION: Specifies that the call is part of an externally coordinated, XA-compliant transaction.

WantDestinationQueue
Optional (default is FALSE). If TRUE, MSMQMessage.DestinationQueueInfo is updated when the message is read from the queue. Setting this property to TRUE may slow down the operation of the application.
WantBody
Optional (default is TRUE). If the Body of the message is not needed, set this property to FALSE to optimize the speed of the application.
WantConnectorType
Optional (default is FALSE). Set to TRUE if the receiving application wants to retrieve the MSMQMessage.ConnectorTypeGuid property. By default, Message Queuing does not retrieve the MSMQMessage.ConnectorTypeGuid property when it retrieves a message from the queue.

Return Values

MSMQMessage object (or Null message object if no message is available).

Remarks

MSMQQueue.ReceiveLastByLookupId is part of a set of methods that can be used to locate messages and navigate the queue without using cursors. For information on all the methods included in this set, see Message Lookup Identifier.

Retrieving message in transactions

To retrieve a message within a transaction, set the Transaction parameter to one of the following.

  • An MSMQTransaction object
  • One of the constants described in the preceding parameter description.
  • Use the default MQ_MTS_TRANSACTION setting of the Transaction parameter.

Message Queuing performs the following tasks when a transaction is specified.

  • In the case of a subsequent Abort, the message is returned to its original place in the queue.
  • In the case of a Commit, a positive acknowledgment message is sent to the administration queue of the sending application. The class property of the acknowledgment message is MQMSG_CLASS_ACK_RECEIVE.

Transaction objects cannot be reused after you commit to or abort the transaction. If you release the transaction object without calling Commit or Abort, the transaction is automatically aborted.

Messages cannot be retrieved from remote queues within a transaction.

WantDestinationQueue and WantBody parameters

The WantDestinationQueue and WantBody parameters can be used to optimize the speed of the application.

Message body type

When peeking at message, you cannot look at the type of message body included in the message. Message Queuing will determine the body type based on the message's body type property (the body type property of the messages can be accessed only with Message Queuing functions). However, if the message was sent using MQSendMessage, the following situations can occur.

  • If the body type property was not set before MQSendMessage was called, the message body is treated as an array of bytes.
  • If the body type was set to an invalid body type (for valid types, see Message Body Types) before MQSendMessage was called, the message can be retrieved, but an error will occur when you try to read the message body.

Responding to Messages

The receiving application can determine if the sending application expects a response messages by retrieving the MSMQMessage.ResponseDestination (introduced in MSMQ 3.0) or MSMQMessage.ResponseQueueInfo property when reading the message. If the property is set to Null, the sending application is not expecting a response message. For information on requesting and returning response messages, see Response Messages.

Opening queues

Applications can peek at messages in queues opened with peek or receive access (see MSMQQueueInfo.Open).

Opening a queue with peek access requires a direct connection to the computer where the queue resides. You cannot peek at the messages in a queue that resides on a computer that has no direct connection to the computer where your application is running.

Equivalent API Function

When using API function calls, use MQReceiveMessageByLookupId to retrieve messages based on their lookup identifier. To retrieve messages using this function, set the dwLookupAction parameter to the appropriate value.

Requirements

Windows NT/2000 or later: Requires Whistler.
Windows 95/98/Me: Unsupported.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MQSendMessage, MSMQMessage, MSMQMessage.DestinationQueueInfo, MSMQMessage.LookupId, MSMQMessage.ResponseDestination, MSMQMessage.ResponseQueueInfo, MSMQQueue, MSMQQueueInfo.Open, MSMQTransaction


MSMQQueue.ReceiveNextByLookupId

(Introduced in MSMQ 3.0.) The ReceiveNextByLookupId method of the MSMQQueue object returns the message that follows the message referenced by the supplied message lookup identifier and removes the message from the queue.

set messageObject = queueObject.ReceiveNextByLookupId( _
  LookupId
  [,Transaction]
  [, WantDestinationQueue] _
  [, WantBody]_
  [, WantConnectorType]_
)

Parameters

messageObject
Message (MSMQMessage) object that represents the message read from the queue.
queueObject
Queue (MSMQQueue) object that represents the queue where the message resides.
LookupId
Lookup identifier of the message.
Transaction
Optional. An MSMQTransaction object or one of the following constants:

MQ_NO_TRANSACTION: Specifies that the call is not part of a transaction.

MQ_MTS_TRANSACTION: Default. Specifies that the call is part of the current MTS (Microsoft Transaction Server) transaction.

MQ_XA_TRANSACTION: Specifies that the call is part of an externally coordinated, XA-compliant transaction.

WantDestinationQueue
Optional (default is FALSE). If TRUE, MSMQMessage.DestinationQueueInfo is updated when the message is read from the queue. Setting this property to TRUE may slow down the operation of the application.
WantBody
Optional (default is TRUE). If the Body of the message is not needed, set this property to FALSE to optimize the speed of the application.
WantConnectorType
Optional (default is FALSE). Set to TRUE if the receiving application wants to retrieve the MSMQMessage.ConnectorTypeGuid property. By default, Message Queuing does not retrieve the MSMQMessage.ConnectorTypeGuid property when it retrieves a message from the queue.

Return Values

MSMQMessage object (or Null message object if no message is available).

Remarks

MSMQQueue.ReceiveNextByLookupId is part of a set of methods that can be used to locate messages and navigate the queue without using cursors. For information on all the methods included in this set, see Message Lookup Identifier.

Retrieving message in transactions

To retrieve a message within a transaction, set the Transaction parameter to one of the following.

  • An MSMQTransaction object
  • One of the constants described in the preceding parameter description.
  • Use the default MQ_MTS_TRANSACTION setting of the Transaction parameter.

Message Queuing performs the following tasks when a transaction is specified.

  • In the case of a subsequent Abort, the message is returned to its original place in the queue.
  • In the case of a Commit, a positive acknowledgment message is sent to the administration queue of the sending application. The class property of the acknowledgment message is MQMSG_CLASS_ACK_RECEIVE.

Transaction objects cannot be reused after you commit to or abort the transaction. If you release the transaction object without calling Commit or Abort, the transaction is automatically aborted.

Messages cannot be retrieved from remote queues within a transaction.

WantDestinationQueue and WantBody parameters

The WantDestinationQueue and WantBody parameters can be used to optimize the speed of the application.

Message body type

When peeking at message, you cannot look at the type of message body included in the message. Message Queuing will determine the body type based on the message's body type property (the body type property of the messages can be accessed only with Message Queuing functions). However, if the message was sent using MQSendMessage, the following situations can occur.

  • If the body type property was not set before MQSendMessage was called, the message body is treated as an array of bytes.
  • If the body type was set to an invalid body type (for valid types, see Message Body Types) before MQSendMessage was called, the message can be retrieved, but an error will occur when you try to read the message body.

Responding to Messages

The receiving application can determine if the sending application expects a response messages by retrieving the MSMQMessage.ResponseDestination (introduced in MSMQ 3.0) or MSMQMessage.ResponseQueueInfo property when reading the message. If the property is set to Null, the sending application is not expecting a response message. For information on requesting and returning response messages, see Response Messages.

Opening queues

Applications can peek at messages in queues opened with peek or receive access (see MSMQQueueInfo.Open).

Opening a queue with peek access requires a direct connection to the computer where the queue resides. You cannot peek at the messages in a queue that resides on a computer that has no direct connection to the computer where your application is running.

Equivalent API Function

When using API function calls, use MQReceiveMessageByLookupId to retrieve messages based on their lookup identifier. To retrieve messages using this function, set the dwLookupAction parameter to the appropriate value.

Requirements

Windows NT/2000 or later: Requires Whistler.
Windows 95/98/Me: Unsupported.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MQSendMessage, MSMQMessage, MSMQMessage.DestinationQueueInfo, MSMQMessage.LookupId, MSMQMessage.ResponseDestination, MSMQMessage.ResponseQueueInfo, MSMQQueue, MSMQQueueInfo.Open, MSMQTransaction


MSMQQueue.ReceivePreviousByLookupId

(Introduced in MSMQ 3.0.) The ReceivePreviousByLookupId method of the MSMQQueue object returns the message that precedes the message referenced by the supplied message lookup identifier and removes the previous message from the queue.

set messageObject = queueObject.ReceivePreviousByLookupId( _
  LookupId
  [,Transaction]
  [, WantDestinationQueue] _
  [, WantBody]_
  [, WantConnectorType]_
)

Parameters

messageObject
Message (MSMQMessage) object that represents the message read from the queue.
queueObject
Queue (MSMQQueue) object that represents the queue where the message resides.
LookupId
Lookup identifier of the message.
Transaction
Optional. An MSMQTransaction object or one of the following constants:

MQ_NO_TRANSACTION: Specifies that the call is not part of a transaction.

MQ_MTS_TRANSACTION: Default. Specifies that the call is part of the current MTS (Microsoft Transaction Server) transaction.

MQ_XA_TRANSACTION: Specifies that the call is part of an externally coordinated, XA-compliant transaction.

WantDestinationQueue
Optional (default is FALSE). If TRUE, MSMQMessage.DestinationQueueInfo is updated when the message is read from the queue. Setting this property to TRUE may slow down the operation of the application.
WantBody
Optional (default is TRUE). If the Body of the message is not needed, set this property to FALSE to optimize the speed of the application.
WantConnectorType
Optional (default is FALSE). Set to TRUE if the receiving application wants to retrieve the MSMQMessage.ConnectorTypeGuid property. By default, Message Queuing does not retrieve the MSMQMessage.ConnectorTypeGuid property when it retrieves a message from the queue.

Return Values

MSMQMessage object (or Null message object if no message is available).

Remarks

MSMQQueue.ReceivePreviousByLookupId is part of a set of methods that can be used to locate messages and navigate the queue without using cursors. For information on all the methods included in this set, see Message Lookup Identifier.

Retrieving message in transactions

To retrieve a message within a transaction, set the Transaction parameter to one of the following.

  • An MSMQTransaction object
  • One of the constants described in the preceding parameter description.
  • Use the default MQ_MTS_TRANSACTION setting of the Transaction parameter.

Message Queuing performs the following tasks when a transaction is specified.

  • In the case of a subsequent Abort, the message is returned to its original place in the queue.
  • In the case of a Commit, a positive acknowledgment message is sent to the administration queue of the sending application. The class property of the acknowledgment message is MQMSG_CLASS_ACK_RECEIVE.

Transaction objects cannot be reused after you commit to or abort the transaction. If you release the transaction object without calling Commit or Abort, the transaction is automatically aborted.

Messages cannot be retrieved from remote queues within a transaction.

WantDestinationQueue and WantBody parameters

The WantDestinationQueue and WantBody parameters can be used to optimize the speed of the application.

Message body type

When peeking at message, you cannot look at the type of message body included in the message. Message Queuing will determine the body type based on the message's body type property (the body type property of the messages can be accessed only with Message Queuing functions). However, if the message was sent using MQSendMessage, the following situations can occur.

  • If the body type property was not set before MQSendMessage was called, the message body is treated as an array of bytes.
  • If the body type was set to an invalid body type (for valid types, see Message Body Types) before MQSendMessage was called, the message can be retrieved, but an error will occur when you try to read the message body.

Responding to Messages

The receiving application can determine if the sending application expects a response messages by retrieving the MSMQMessage.ResponseDestination (introduced in MSMQ 3.0) or MSMQMessage.ResponseQueueInfo property when reading the message. If the property is set to Null, the sending application is not expecting a response message. For information on requesting and returning response messages, see Response Messages.

Opening queues

Applications can peek at messages in queues opened with peek or receive access (see MSMQQueueInfo.Open).

Opening a queue with peek access requires a direct connection to the computer where the queue resides. You cannot peek at the messages in a queue that resides on a computer that has no direct connection to the computer where your application is running.

Equivalent API Function

When using API function calls, use MQReceiveMessageByLookupId to retrieve messages based on their lookup identifier. To retrieve messages using this function, set the dwLookupAction parameter to the appropriate value.

Requirements

Windows NT/2000 or later: Requires Whistler.
Windows 95/98/Me: Unsupported.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MQSendMessage, MSMQMessage, MSMQMessage.DestinationQueueInfo, MSMQMessage.LookupId, MSMQMessage.ResponseDestination, MSMQMessage.ResponseQueueInfo, MSMQQueue, MSMQQueueInfo.Open, MSMQTransaction


MSMQQueue.Reset

The Reset method of the MSMQQueue object returns the cursor to the start of the queue.

queueObject.Reset

Parameters

queueObject
Queue (MSMQQueue) object that represents an open instance of a queue.

Return Values

For information on return codes, see Message Queuing Error and Information Codes.

Remarks

When navigating the queue using the cursor, the MSMQQueue.Reset method moves the cursor to the front of the queue. To move the cursor from the front of the queue to the first message in the queue, call MSMQQueue.PeekCurrent or MSMQQueue.ReceiveCurrent.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQQueue, MSMQQueue.PeekCurrent, MSMQQueue.ReceiveCurrent


MSMQQueue.Access

Read-only. The Access property of the MSMQQueue object provides the access rights of the queue.

Type: | Long
Run time: | Read-only

queueObject.Access

Parameters

queueObject
Queue (MSMQQueue) object that represents an instance of the queue.

Return Values

The Access property returns one of the following values:

MQ_SEND_ACCESS
Messages can only be sent to the queue.
MQ_PEEK_ACCESS
Messages can only be looked at. They cannot be removed from the queue.
MQ_RECEIVE_ACCESS
Messages can be taken out of the queue or peeked at.

Remarks

The Access property returns the access rights specified when the queue was last opened, regardless of whether the queue is currently open or closed.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQQueue


MSMQQueue.Handle

Read-only. The Handle property of the MSMQQueue object indicates the handle of the opened queue.

Type: | Long
Run time: | Read-only

queueObject.Handle

Parameters

queueObject
Queue (MSMQQueue) object that represents the open instance of the queue.

Return Values

Queue handle.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQQueue


MSMQQueue.IsOpen

Read-only. The IsOpen property of the MSMQQueue object indicates whether or not the queue is open.

Type: | Short
Run time: | Read-only

queueObject.IsOpen

Parameters

queueObject
Queue (MSMQQueue) object that represents an instance of the queue.

Return Values

1
The queue is open.
0
The queue is not open.

Remarks

MSMQQueue.IsOpen returns 1 only when MSMQQueue.Handle is set to a valid queue handle. If Message Queuing has set MSMQQueue.Handle to INVALID_HANDLE_VALUE, MSMQQueue.IsOpen will always return 0.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQQueue, MSMQQueueInfo, MSMQQueueInfo.Create, MSMQQueueInfo.Open, MSMQQueueInfo.PathName


MSMQQueue.IsOpen2

(Read-only, introduced in Whistler.) The IsOpen2 property of the MSMQQueue object indicates whether or not the queue is open.

MSMQQueue.IsOpen2 is a Boolean property that supersedes the non-Boolean MSMQQueue.IsOpen.

Type: | Boolean
Run time: | Read-only

queueObject.IsOpen2

Parameters

queueObject
Queue (MSMQQueue) object that represents an instance of the queue.

Return Values

VARIANT_TRUE (-1)
The queue is open.
VARIANT_FALSE (0)
The queue is not open.

Remarks

MSMQQueue.IsOpen2 returns true only when MSMQQueue.Handle is set to a valid queue handle. If Message Queuing has set MSMQQueue.Handle to INVALID_HANDLE_VALUE, MSMQQueue.IsOpen2 will always return false.

MSMQQueue.IsOpen2 and MSMQQueue.IsOpen

MSMQQueue.IsOpen2 supersedes MSMQQueue.IsOpen and should be used whenever possible. MSMQMessage.IsOpen2 returns Boolean values that are consistent with Microsoft Visual Basic Boolean data types. Otherwise, both properties are functionally equivalent.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQQueue


MSMQQueue.QueueInfo

Read-only. The QueueInfo property of the MSMQQueue object retrieves the stored settings of the MSMQQueueInfo object used to open the queue.

Type: | MSMQQueueInfo
Run time: | Read-only

Set queueinfoObject = queueObject.QueueInfo

Parameters

queueinfoObject
Queue information (MSMQQueueInfo) object that defined the queue.
queueObject
Queue (MSMQQueue) object that represents the open instance of the queue.

Return Values

MSMQQueueInfo object.

Remarks

The QueueInfo property is used to access the settings of the MSMQQueueInfo object that were used to open the queue. These settings are stored in the directory service for public queues, and on the local computer for private queues.

This property is very useful when you want access the settings of the MSMQQueueInfo object after the MSMQQueue object has been passed as a parameter to another function or routine. Note that the MSMQQueueInfo object used to open the queue and the MSMQQueueInfo object of the QueueInfo property are two separate instances that both represent the same queue.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQQueue, MSMQQueue.Close, MSMQQueueInfo, MSMQQueueInfo.Create, MSMQQueueInfo.Label, MSMQQueueInfo.Open, MSMQQueueInfo.QueueGuid, MSMQQueueInfo.PathName


MSMQQueue.ShareMode

The ShareMode property of the MSMQQueue object indicates the share mode of the queue.

Type: | Long
Run time: | Read-only

queueObject.ShareMode

Parameters

queueObject
Queue (MSMQQueue) object that represents the open instance of the queue.

Return Values

The ShareMode property returns one of the following values:

MQ_DENY_NONE
The queue is available to everyone for sending, peeking, or retrieving messages. This is always returned if the queue is opened with Access set to MQ_PEEK_ACCESS or MQ_SEND_ACCESS.
MQ_DENY_RECEIVE_SHARE
Messages can only be retrieved by this process. This value is only returned if the queue is opened with Access set to MQ_RECEIVE_ACCESS.

Remarks

The ShareMode property returns the share mode of the queue when it was last opened, regardless if the queue is currently opened or closed.

When ShareMode returns MQ_DENY_NONE, several users can be using the queue at the same time.

Example Code

This example opens a queue for sending messages, and uses the value of ShareMode to test who can use the queue (with what share mode). To try this example using Microsoft Visual Basic (version 5.0), paste the code into the Code window of a form, run the example, and click the form.

Dim qinfo As MSMQQueueInfo
Dim q As MSMQQueue

Private Sub Form_Click()

  Set qinfo = New MSMQQueueInfo
  qinfo.PathName = ".\lShareModeTest"
  qinfo.Label = "Test Queue"
  qinfo.Create

  Set q = qinfo.Open(MQ_SEND_ACCESS, MQ_DENY_NONE)

  Select Case q.ShareMode
     Case MQ_DENY_NONE
          MsgBox "The queue is open for multiple users."
     Case MQ_DENY_RECEIVE_SHARE
          MsgBox "The queue is only open for this process."
     Case Else
          MsgBox "Not a valid return value!"
  End Select

  q.Close

End Sub

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQQueue, MSMQQueue.Close, MSMQQueueInfo, MSMQQueueInfo.Create, MSMQQueueInfo.Label, MSMQQueueInfo.Open, MSMQQueueInfo.PathName


MSMQQueueInfo

The MSMQQueueInfo object provides queue management for a single queue. It provides methods for creating a queue (either a transactional or non-transactional queue), opening a queue, changing the properties of a queue, and deleting a queue.

MSMQQueueInfo objects are either returned by a query or created by the sending or receiving application. There is a one-to-one relationship between each MSMQQueueInfo object and the queue it represents. However, as shown in the illustration below, there is a one-to-many relationship between the MSMQQueueInfo object of the queue and the MSMQQueue objects that represent open instances of the queue.

Methods

The following table lists the methods of the MSMQQueueInfo object.

Method | Description
Create | Creates a queue based on the queue properties of the MSMQQueueInfo object.
Delete | Deletes an existing queue.
Open | Opens a queue, returning an MSMQQueue object.
Refresh | Refreshes the property values of the MSMQQueueInfo object with the values stored in the directory service (for public queues) or the local computer (for private queues).
Update | Updates the directory service or the local computer with the current property values of the MSMQQueueInfo object.

Properties

The following table lists the properties of the MSMQQueueInfo object and gives their access, whether read-only or read/write; their data type; and a description.

Property | Description
Authenticate Access: Read/write Data type: Long | Specifies whether the queue accepts only authenticated messages.
BasePriority Access: Read/write Data type: Long | Specifies a base priority for all messages sent to a public queue.
CreateTime Access: Read-only Data type: Date Variant | (Read-only, introduced in MSMQ 2.0 for private queues.) Provides the time and date when the public or private queue was created.
FormatName Access: Read/write Data type: String | Specifies the format name of the queue.
IsTransactional Access: Read-only Data type: Short | Indicates whether the queue supports transactions.
IsWorldReadable Access: Read-only Data type: Short | Indicates whether everyone can read the messages in the queue.
Journal Access: Read/write Data type: Long | Specifies whether or not messages retrieved from the queue are stored in a queue journal.
JournalQuota Access: Read/write Data type: Long | Specifies the maximum size of the queue journal.
Label Access: Read/write Data type: String | Specifies a description of the queue or message.
ModifyTime Access: Read-only Data type: Date Variant | (Read-only, introduce in MSMQ 2.0 for private queues.) Provides the time and date when the stored properties of the queue were last updated.
PathName Access: Read/write Data type: String | Specifies the Message Queuing pathname of the queue.
PathNameDNS Access: Read-only Data type: String | (Read-only, introduced in MSMQ 2.0.) Provides the DNS pathname of the queue.
PrivLevel Access: Read/write Data type: Long | Specifies the privacy level of a queue or message.
QueueGuid Access: Read-only Data type: GUID | (Read-only.) Provides the identifier of the public queue associated with the MSMQQueueInfo object.
Quota Access: Read/write Data type: Long | Specifies the maximum size of the queue.
ServiceTypeGuid Access: Read/write Data type: GUID | Specifies the type of service provided by the queue.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.


MSMQQueueInfo.Create

The Create method of the MSMQQueueInfo object creates a public or private queue based on the properties of the MSMQQueueInfo object.

queueinfoObject.Create( _
  [IsTransactional] _
  [, IsWorldReadable] _
)

Parameters

queueinfoObject
Queue information (MSMQQueueInfo) object that defines queue.
IsTransactional
Optional (default is FALSE). BOOLEAN. When TRUE, indicates that the queue is a transactional queue. All messages sent to a transactional queue or read from a transactional queue must be done as part of a transaction.
IsWorldReadable
Optional (default is FALSE). BOOLEAN. When TRUE, anyone can read the messages in the queue and its queue journal. When FALSE, only the owner can read the messages.

Return Values

For information on return codes, see Message Queuing Error and Information Codes.

Remarks

You must always specify the pathname of the queue before calling MSMQQueueInfo.Create. The MSMQQueueInfo.PathName property tells Message Queuing where to store the messages of the queue, if the queue is public or private, and the name of the queue. When setting this property, you can specify the UNC or DNS pathname for the queue.

Optional queue properties

Setting other queue properties is optional. If a queue property is not set before Create is called, its default value is used when the queue is created.

Registering queues

Message Queuing registers public queues in the directory service and private queues on the local computer. All queues exist until deleted explicitly.

Creating private queues

Private queues can only be created on the local computer. It is the responsibility of the application to ensure that no other private queues with the same name exists on the local computer (if a queue with the same name already exists, an MQ_ERROR_QUEUE_EXISTS error is returned when Create is called).

Creating transactional queues

To create a transactional queue, set the IsTransactional parameter to TRUE.

Creating foreign queues

Foreign public queues (queues located outside the enterprise) are created in the same way as an Message Queuing public queue. For foreign queues, the MSMQQueueInfo.PathName property specifies the name of the foreign computer as it is defined in the directory service. For information on foreign computers, see MSMQ Connector Servers.

Specifying target journaling

To specify target journaling, set MSMQQueueInfo.Journal and MSMQQueueInfo.JournalQuota.

Creating public queues from a collection of queues

Typically queues are not created from MSMQQueueInfo objects found in a MSMQQueueInfos object because the queue already exists. However, you can create a new queue from an MSMQQueueInfo object if you delete the existing queue and then change the MSMQQueueInfo.PathName or MSMQQueueInfo.FormatName property of the queue. A new queue will be created based on the new pathname or format name.

Opening queues

After the queue is created, the MSMQQueueInfo object can be opened multiple times. For example, the same MSMQQueueInfo object can be used to open the queue for sending messages and for retrieving messages.

Changing access control on the queue

Access control can be changed by setting isWorldReadable. If this parameter is not set, its default value specifies Message Queuing default security. Following are the default values for the security descriptor.

Default Value | Meaning
Owner | The process user.
Group | The process group.
DACL | Full control for the creator of the queue. All other processes can get queue properties, get queue security, and send messages to the queue.
SACL | None.

For information on access control, see Access Control.

Offline operations

Applications that may be running offline cannot create public queues while they are offline. Applications must have access to the directory service to create a public queue. For information on offline operations, see Message Queuing Offline Support.

Directory service propagation delays

When creating a public queue, some clients may not be able to see the new queue registered in the directory service even though the queue exists. Changes to the directory service (such as creating a public queue) are propagated from domain controller to domain controller, which can cause delays in the availability of new information. Consequently, clients using a specific domain controller may not be able to open the queue, even though it exists. Propagation delays, including communication network delays such as down links, are controlled by the MSMQ Administrator.

For information on | See
The different types of queues provided by Message Queueing | Message Queuing Queues
What information Message Queuing needs to create queues | Creating Queues
Optional queue properties that can be set when creating a queue | Setting Queue Behavior
Transaction support provided by Message Queuing | Message Queuing Transactions

Example Code

The following example code is included in the Platform SDK.

For an example of | See
Creating a transactional queue | C/C++ COM Code Example Visual Basic Code Example: Creating a Transactional Queue

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQQueueInfo, MSMQQueueInfo.Journal, MSMQQueueInfo.JournalQuota, MSMQQueueInfo.PathName


MSMQQueueInfo.Delete

The Delete method of the MSMQQueueInfo object deletes an existing queue (it does not delete the MSMQQueueInfo object used to create the queue).

queueinfoObject.Delete

Parameters

queueinfoObject
The queue information (MSMQQueueInfo) object that defines the queue.

Return Values

For information on return codes, see Message Queuing Error and Information Codes.

Remarks

Deleting the queue does not delete the MSMQQueueInfo object, only the existing reference to the queue in the directory service (for public queues) or the local computer (for private queues). You can still create a new queue based on the current properties of the MSMQQueueInfo object.

Applications that may be running offline cannot delete public queues while they are offline. Applications must have access to the directory service to delete a public queue. For information on offline operations, see Message Queuing Offline Support.

When a public queue is deleted, some clients may still see the queue registered in the directory service after the queue has been deleted. Changes to the directory service (such as deleting a public queue) are propagated from domain controller to domain controller, which can cause delays in the availability of new information. Consequently, clients using a specific domain controller may still try to send messages to the queue, even though it has been deleted. Propagation delays, including communication network delays such as down links, are controlled by the MSMQ Administrator.

Private queues cannot be deleted if they are registered on a remote computer. Only local private queues can be deleted.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQQuery, MSMQQuery.LookupQueue, MSMQQueue.Reset, MSMQQueueInfo, MSMQQueueInfo.Label, MSMQQueueInfos, MSMQQueueInfos.Next


MSMQQueueInfo.Open

The Open method of the MSMQQueueInfo object opens a queue for sending, peeking at, or retrieving messages

The properties of the queue are based on the current properties of the queue information (MSMQQueueInfo) object.

set queueObject = queueinfoObject.Open( _
  Access, _
  ShareMode _
)

Parameters

queueinfoObject
Queue information (MSMQQueueInfo) object that defines the queue.
queueObject
Queue (MSMQQueue) object that represents the open instance of the queue.
Access
Specifies how the application accesses the queue (peek, send, or receive). This setting cannot be changed while the queue is open.

Access can be set to one of the following:

MQ_PEEK_ACCESS: Messages can only be looked at. They cannot be removed from the queue.

MQ_SEND_ACCESS: Messages can only be sent to the queue.

MQ_RECEIVE_ACCESS: Messages can be retrieved from the queue or peeked at. See the description of the ShareMode parameter for information on limiting who can retrieve messages from the queue.

ShareMode
Specifies who can access the queue. Set to one of the following:

MQ_DENY_NONE: Default. The queue is available to everyone. This setting must be used if Access is set to MQ_PEEK_ACCESS or MQ_SEND_ACCESS.

MQ_DENY_RECEIVE_SHARE: Limits those who can retrieve messages from the queue to this process. If the queue is already opened for retrieving messages by another process, this call fails and returns MQ_ERROR_SHARING_VIOLATION. Applicable only when Access is set to MQ_RECEIVE_ACCESS.

Return Values

For information on return codes, see Message Queuing Error and Information Codes.

Remarks

MSMQQueueInfo.Open returns an MSMQQueue object each time it is called. The is a one-to-many relationship between the MSMQQueueInfo object that represents the queue and the MSMQQueue objects that represent an open instance of the queue.

Opening multiple queues

To open multiple queues, call MSMQDestination.Open. For information on opening multiple queues using distribution lists and multiple-element format names, see Sending Messages to Multiple Destinations.

Queue access rights

If the calling application does not have sufficient access rights to a queue, two things can happen.

  • If Access is set to MQ_SEND_ACCESS, Open succeeds, but errors are thrown when the application tries to send a message.
  • If Access is set to MQ_PEEK_ACCESS or MQ_RECEIVE_ACCESS, Open fails and throws MQ_ERROR_ACCESS_DENIED.

To change the access rights of the queue, call MQSetQueueSecurity. The following table lists the access rights needed to open the queue in peek, send, or receive access mode.

Queue Access Mode | Queue Access Right
MQ_PEEK_ACCESS | MQSEC_PEEK_MESSAGE
MQ_SEND_ACCESS | MQSEC_WRITE_MESSAGE
MQ_RECEIVE_ACCESS | MQSEC_RECEIVE_MESSAGE

After opening a queue, there is no provision to change the access mode of the queue.

Opening queues on remote computers

When opening a queue to send messages to a remote computer (when dwAccess is set to MQ_SEND_ACCESS ), Message Queuing does not check for the existence of the queue. When opening a queue to read messages from a remote computer (when dwAccess is set to MQ_RECEIVE_ACCESS or MQ_PEEK_ACCESS), the computer opening the queue must support the same protocol as the remote computer where the queue is located. To read messages from a queue on a remote computer, there must be a direct connection between both computers.

Opening journal, dead-letter, and connector queues

Sending applications cannot open journal queues, dead-letter queues, or connector queues for sending messages. These queues can only be opened with Access set to MQ_PEEK_ACCESS or MQ_RECEIVE_ACCESS.

Opening foreign queues

Foreign queues cannot be opened using a direct format name. Message Queuing needs the routing information stored in the directory service to find a MSMQ Connector Server for the foreign queue.

Setting share mode

Setting ShareMode to MQ_DENY_RECEIVE_SHARE means that until the calling application calls the MSMQQueue object's MSMQQueue.Close method, no other Message Queuing applications can read the messages in the queue. This includes applications that may have the correct access rights to read messages from the queue.

Direct format names

Direct format names can only be used when sending messages to a queue. A direct format name tells Message Queuing not to use the directory service (for public queues) or the local computer (for private queues) to get routing information. When a direct format name is used, all routing information is taken from the format name and Message Queuing sends the messages to the queue in a single hop.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQQueue, MSMQQueueInfo, MSMQDestination.Open


MSMQQueueInfo.Refresh

The Refresh method of the MSMQQueueInfo object refreshes the property values of the MSMQQueueInfo object. These values are retrieved from the directory service (public queues) or from the local computer (private queues).

queueinfoObject.Refresh

Parameters

queueinfoObject
The queue information (MSMQQueueInfo) object that defines the queue.

Remarks

All queue properties can be retrieved. However, you can only retrieve the properties of private queues if they are located on your local computer.

Refresh is typically used when more than one user is using the queue. For example, if user 1 locates the queue and then user 2 modifies the queue's properties, user 1 needs to call Refresh to sync up with user 2's changes.

After a queue is created, the properties of the MSMQQueueInfo object are not updated until Refresh is explicitly called, or the queue is closed and reopened. For example, even though Message Queuing sets MSMQQueueInfo.CreateTime, MSMQQueueInfo.ModifyTime, or MSMQQueueInfo.QueueGuid when it creates the queue, the application must call Refresh to update the properties of the MSMQQueueInfo object before it can read those properties.

Equivalent API Function

To retrieve the properties of a queue using function calls, see the MQGetQueueProperties function.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MQGetQueueProperties, MSMQQueueInfo


MSMQQueueInfo.Update

The Update method of the MSMQQueueInfo object updates the directory service (public queues) or the local computer (private queues) with the current property values of the MSMQQueueInfo object.

queueinfoObject.Update

Parameters

queueinfoObject
The queue information (MSMQQueueInfo) object that defines the public queue.

Remarks

The MSMQQueueInfo.Update method can update the property values of existing public and local private queues. It cannot be called on an MSMQQueueInfo object before the queue is created or after the queue is deleted. (Message Queuing updates queue property values only when a queue is created, when a queue is opened, and whenever MSMQQueueInfo.Update is explicitly called.)

Calling MSMQQueueInfo.Update

When MSMQQueueInfo.Update is called, the local queue property values of the MSMQQueueInfo object are stored in one of two places. For public queues, these property values are stored in the directory service. For private queues, these property values are stored on the local computer.

Queue Properties that cannot be Updated

The MSMQQueueInfo.Update method cannot updated the following queue properties.

  • MSMQQueueInfo.BasePriority

    This property cannot be updated for private queues.

  • MSMQQueueInfo.CreateTime

    This property is set by Message Queueing.

  • MSMQQueueInfo.ModifyTime

    This property is set by Message Queueing.

  • MSMQQueueInfo.PathName

    This property is set only when the queue is created.

  • MSMQQueueInfo.PathNameDNS

    This property is set not stored by Message Queueing. The DNS pathname of a queue is generated each time this property is referenced.

  • MSMQQueueInfo.QueueGuid

    This property is set by Message Queueing.

Propagation Delays

When setting the properties of a public queue, some clients may still see the old settings registered in the directory service after the properties are changed. Changes to the directory service (such as setting properties) are propagated from domain controller to domain controller, which can cause delays in the availability of new information. Consequently, clients using a specific domain controller may still see the old property settings, even though the settings of the properties were changed by Update. Propagation delays, including communication network delays such as down links, are controlled by the MSMQ Administrator.

Equivalent API Function

To set the properties of a queue using function calls, see the MQSetQueueProperties function.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQQueueInfo


MSMQQueueInfo.Authenticate

Optional. The Authenticate property of the MSMQQueueInfo object specifies whether the queue only accepts authenticated messages.

Type: | Long
Run time: | Read/write

queueinfoObject.Authenticate

Parameters

queueinfoObject
Queue information (MSMQQueueInfo) object that defines the queue.

Property Values

Set Authenticate to one of the following values:

MQ_AUTHENTICATE_NONE
The default. The queue accepts authenticated and non-authenticated messages.
MQ_AUTHENTICATE
The queue only accepts authenticated messages.

Remarks

This property sets the authentication level of the queue. For information on how Message Queuing authenticates messages, see Message Authentication.

When a non-authenticated messages is sent to a queue that only accepts authenticated messages, the message is rejected. If the sending application has also requested negative acknowledgment messages, a negative acknowledgment message with the message class MQMSG_CLASS_BAD_SIGNATURE is returned to the sending application to indicate the message was rejected.

Setting and Retrieving the Queue Authentication Level

To specify the authentication level when creating the queue, set the MSMQQueueInfo.Authenticate property and call the MSMQQueueInfo.Create method.

To reset the authentication level of an open queue, set MSMQQueueInfo.Authenticate to a new level and call the MSMQQueueInfo.Update method. This method updates the queue information stored by Message Queueing. For public queues, this information is stored in the directory service. For private queues, this information is stored on the computer where the messages of the queue are stored.

To retrieve the stored authentication level of a queue, call the MSMQQueueInfo.Refresh method and inspect the MSMQQueueInfo.Authenticate property.

Requesting Message Authentication

The sending application requests authentication by setting the MSMQMessage.AuthLevel message property when the message is sent.

Verifying Message Authentication

To verify that the sending application requested authentication, peek at the MSMQMessage.IsAuthenticated2 property of the message.

Equivalent API function property

When using API function calls, the authentication level of the queue can be set and retrieved using the PROPID_Q_AUTHENTICATE property.

Example Code

The following example code is included in the Platform SDK.

For an example of | See
Setting and retrieving the authentication level of an existing queue | Setting MSMQQueueInfo.Authenticate Retrieving MSMQQueueInfo.Authenticate

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQMessage.AuthLevel, MSMQMessage.IsAuthenticated2, MSMQQueueInfo, MSMQQueueInfo.Create, MSMQQueueInfo.Refresh, MSMQQueueInfo.Update, PROPID_Q_AUTHENTICATE


MSMQQueueInfo.BasePriority

Optional. The BasePriority property of the MSMQQueueInfo object specifies a single base priority for all messages sent to a public queue.

Type: | Long
Run time: | Read/write

queueinfoObject.BasePriority

Parameters

queueinfoObject
Queue information (MSMQQueueInfo) object that defines the queue.

Property Values

Integer value between -32768 and +32767 (default is 0).

Remarks

A public queue's base priority is used for routing the queue's messages over the network. It can be used to give the messages sent to the queue a higher (or lower) priority than messages sent to other queues. When a queue's base priority is set, all the messages sent to it are given a higher priority than messages sent to queues with a lower base priority. The queue's base priority has no effect on the order of the messages in the queue or how messages are read from the queue.

BasePriority only applies to public queues that can be located through the directory service (using a public format name). The base priority of private queues, as well as public queues accessed directly, is always 0.

Message Queuing combines the queue's base priority with the message's priority (MSMQMessage.Priority) to determine the overall priority of a message when it is sent to the queue.

Setting and Retrieving the Queue Priority Level

To specify the priority level when creating a public queue, set the MSMQQueueInfo.BasePriority property and call the MSMQQueueInfo.Create method.

To reset the priority level of an open public queue, set MSMQQueueInfo.BasePriority to a new level and call the MSMQQueueInfo.Update method. This method updates the queue information stored by Message Queueing. For public queues, this information is stored in the directory service.

To retrieve the stored priority level of a queue, call the MSMQQueueInfo.Refresh method and inspect the MSMQQueueInfo.BasePriority property.

Equivalent API function property

When using API function calls, the priority level of the queue can be set and retrieved using the PROPID_Q_BASEPRIORITY property.

Example Code

The following example code is included in the Platform SDK.

For an example of | See
Setting and retrieving the priority level of an existing queue | Setting MSMQQueueInfo.BasePriority Retrieving MSMQQueueInfo.BasePriority

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQMessage.Priority, MSMQQueueInfo, MSMQQueueInfo.Create, MSMQQueueInfo.Refresh, MSMQQueueInfo.Update, PROPID_Q_BASEPRIORITY


MSMQQueueInfo.CreateTime

Read-only. The CreateTime property of the MSMQQueueInfo object indicates when the public queue or private queue (introduced in MSMQ 2.0) was created.

Type: | Date Variant
Run time: | Read-only

queueinfoObject.CreateTime

Parameters

queueinfoObject
Queue information (MSMQQueueInfo) object that defines the queue.

Return Values

Date and time when queue was created.

Remarks

Message Queuing sets this property, storing the value of the property when the queue is created. Once retrieved, the value of MSMQQueueInfo.CreateTime can be manipulated using standard Microsoft® Visual Basic® date and time functions such as Date$ and Time$. For descriptions of Visual Basic functions, see the Visual Basic documentation.

When MSMQQueueInfo.CreateTime is displayed, Visual Basic automatically converts the property value to the local system time and system date.

Locating Queues Based on Create Time

The MSMQQueueInfo.CreateTime property can be used as search criteria when making a query of existing public queues. See the MSMQQuery.LookupQueue method for details on running a query.

Retrieving the Create Time

To retrieve the stored create time of a queue, call the MSMQQueueInfo.Refresh method and inspect the MSMQQueueInfo.CreateTime property. Message Queuing stores the create time in the directory service (for public queues) and on the local computer (for private queues). The local value of MSMQQueueInfo object is not updated until the MSMQQueueInfo.Refresh method is called.

Equivalent API function property

When using API function calls, the date and time the queue was created can be retrieved using the PROPID_Q_CREATE_TIME property.

Example Code

The following example code is included in the Platform SDK.

For an example of | See
Retrieving the date and time when an existing queue was created | Retrieving MSMQQueueInfo.CreateTime

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQQuery, MSMQQuery.LookupQueue, MSMQQueueInfo, MSMQQueueInfo.Refresh, PROPID_Q_CREATE_TIME


MSMQQueueInfo.FormatName

The FormatName property of the MSMQQueueInfo object specifies the format name of the queue. This property is used by Message Queuing to open the queue.

Type: | String
Run time: | Read/write

queueinfoObject.FormatName

Parameters

queueinfoObject
The queue (MSMQQueueInfo) object in question.

Property Values

String. Possible strings are:

PUBLIC=QueueGUID
DIRECT=Protocol:MachineAddress\QueueName
DIRECT=OS:MachineName\QueueName
PRIVATE=MachineGUID\QueueNumber

Remarks

The MSM<QQueueInfo.FormatName property must be specified to open the queue. Message Queuing uses the format name of the queue to identify which queue to open and how to access the opened queue.

When creating a queue, if a format name is not provided by the application, Message Queuing generates a format name based on the pathname of the queue (MSMQQueueInfo.PathName). After the queue is created, you can use the name generated by Message Queuing or specify a different one. For example, to open the journal of the queue modify the format name of the destination queue and then use the MSMQQueueInfo object to open the journal.

The format name of a queue cannot be changed while the queue is open. For information on how Message Queuing uses format names to reference queues and the different types of format names, see Format Names.

Opening queues for Direct Messaging

To send messages directly to and read messages directly from a queue the MSMQQueueInfo.FormatName property must contain a direct format name (as shown below). For information on direct format names see, Direct Format Names.

DIRECT=AddressSpecification\QueueName  (For public queues.)
DIRECT=AddressSpecification\PRIVATE$\QueueName  (For private queues.)
DIRECT=AddressSpecification\SYSTEM$;computersystemqueue  (Introduced in MSMQ 2.0)
DIRECT=HTTP://URLAddressSpecification\msmq\QueueName  (introduced in MSMQ 3.0)
DIRECT=HTTPS://URLAddressSpecification\msmq\QueueName  (introduced in MSMQ 3.0)

Setting and Retrieving the Format Name

To specify the format name of the queue when opening a queue, set the MSMQQueueInfo.FormatName property and call the MSMQQueueInfo.Open method.

To retrieve the stored format name of a queue, call the MSMQQueueInfo.Refresh method and inspect the MSMQQueueInfo.FormatName property. For public queues, this information is stored in the directory service. For private queues, this information is stored on the computer where the messages of the queue are stored.

Using Null characters in Format Name strings

Message Queuing COM components ignore any characters that follow the first Null character in a string without returning an error.

Equivalent API function property

There is no equivalent API function property for the format name of the queue. When using API function calls, the format name of the queue is specified as a parameter of the MQOpenQueue function call.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MQOpenQueue, MSMQQueueInfo, MSMQQueueInfo.Open, MSMQQueueInfo.PathName, MSMQQueueInfo.Refresh


MSMQQueueInfo.IsTransactional

Read-only. The IsTransactional property of the MSMQQueueInfo object indicates whether the queue supports transactions.

This property is superseded by the MSMQQueueInfo.IsTransactional2 property (introduced in MSMQ 3.0).

Type: | Short
Run time: | Read-only

queueinfoObject.IsTransactional

Parameters

queueinfoObject
Queue information (MSMQQueueInfo) object that defines the queue.

Return Values

1
The queue is only used in transactions.
0
The queue is not used in transactions.

Remarks

If a queue is transactional, it can only accept messages that are sent as part of a transaction. In a similar way, messages read from a transactional queue must also be done as part of a transaction. For information on transactions, see Message Queuing Transactions.

Equivalent API Function Property

When using API function calls, the transactional level of the queue can be set (when creating the queue) and retrieved using the PROPID_Q_TRANSACTION property.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQQueueInfo, MSMQQueueInfo.IsTransactional2, MSMQQueueInfo.Refresh, PROPID_Q_TRANSACTION


MSMQQueueInfo.IsTransactional2

(Read-only, introduced in MSMQ 3.0.) The IsTransactional2 property of the MSMQQueueInfo object indicates whether the queue supports transactions.

MSMQQueueInfo.IsTransactional2 is a Boolean property that supersedes the non-Boolean MSMQQueueInfo.IsTransactional property.

Type: | Boolean
Run time: | Read-only

queueinfoObject.IsTransactional2

Parameters

queueinfoObject
Queue information (MSMQQueueInfo) object that defines the queue.

Return Values

VARIANT_TRUE (-1)
The queue is only used in transactions.
VARIANT_FALSE (0)
The queue is not used in transactions.

Remarks

Sending and receiving applications can use MSMQQueueInfo.IsTransactional2 to test whether a queue must be used within the context of a transaction. If a queue is transactional, sending applications must send messages as part of a transaction, and receiving applications must read messages as part of a transaction.

For information on transactions, see Message Queuing Transactions.

MSMQQueueInfo.IsTransactional2 and MSMQQueueInfo.IsTransactional

MSMQQueueInfo.IsTransactional2 supersedes MSMQQueueInfo.IsTransactional and should be used whenever possible. MSMQQueueInfo.IsTransactional2 returns Boolean values that are consistent with Microsoft Visual Basic Boolean data types. Otherwise, both properties are functionally equivalent.

Equivalent API Function Property

When using API function calls, the transactional level of the queue can be set (when creating the queue) and retrieved using the PROPID_Q_TRANSACTION property.

Requirements

Windows NT/2000 or later: Requires Whistler.
Windows 95/98/Me: Unsupported.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQQueueInfo, PROPID_Q_TRANSACTION


MSMQQueueInfo.IsWorldReadable

Read-only. The IsWorldReadable property of the MSMQQueueInfo object indicates whether everyone can read the messages in the queue.

This property is superseded by the MSMQQueueInfo.IsWorldReadable2 property (introduced in MSMQ 3.0).

Type: | Short
Run time: | Read-only

queueinfoObject.IsWorldReadable

Parameters

queueinfoObject
Queue information (MSMQQueueInfo) object that defines the queue.

Return Values

1
Everyone can read messages in the queue and its queue journal.
0
Default. Only the owner of the queue can read the messages in the queue.

Remarks

Message Queuing initially sets this property based on the IsWorldReadable parameter of the MSMQQueueInfo.Create method. After the queue is created, Message Queuing resets IsWorldReadable whenever the security descriptor of the queue is changed to allow or disallow read access to everyone. For information on security descriptors and access control, see Access Control.

This property has no effect on sending messages to the queue.

Equivalent API Function Property

There is no equivalent API function property for this property.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQQueueInfo, MSMQQueueInfo.Create


MSMQQueueInfo.IsWorldReadable2

(Read-only, introduced in MSMQ 3.0.) The IsWorldReadablel2 property of the MSMQQueueInfo object indicates whether everyone can read the messages in the queue.

MSMQQueueInfo.IsWorldReadable2 is a Boolean property that supersedes the non-Boolean MSMQQueueinfo.IsWorldreadable property.

Type: | Boolean
Run time: | Read-only

queueinfoObject.IsWorldReadable2

Parameters

queueinfoObject
Queue information (MSMQQueueInfo) object that defines the queue.

Return Values

VARIANT_TRUE (-1)
Everyone can read messages in the queue and its queue journal.
VARIANT_FALSE (0)
Default. Only the owner of the queue can read the messages in the queue.

Remarks

Message Queuing initially sets the MSMQQueueInfo.IsWorldReadable2 property based on setting of the IsWorldReadable parameter of the MSMQQueueInfo.Create call when the queue is created. After the queue is created, Message Queuing resets MSMQQueueInfo.IsWorldReadable2 whenever the security descriptor of the queue is changed to allow or disallow read access to everyone. For information on security descriptors and access control, see Access Control.

This property has no effect on sending messages to the queue.

MSMQQueueInfo.IsWorldReadable2 and MSMQQueueInfo.IsWorldReadable

MSMQQueueInfo.IsWorldReadable2 supersedes MSMQQueueinfo.IsWorldreadable and should be used whenever possible. MSMQQueueInfo.IsWorldReadable2 returns Boolean values that are consistent with Microsoft Visual Basic Boolean data types. Otherwise, both properties are functionally equivalent.

Equivalent API Function Property

There is no equivalent API function property when using API function calls.

Requirements

Windows NT/2000 or later: Requires Whistler.
Windows 95/98/Me: Unsupported.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQQueueInfo, MSMQQueueInfo.Create, MSMQQueueinfo.IsWorldreadable


MSMQQueueInfo.Journal

Optional. The Journal property of the MSMQQueueInfo object specifies the journaling level of the destination queue. The journaling level determines whether or not messages retrieved from the destination queue are stored in the journal of the queue.

Type: | Long
Run time: | Read/write

queueinfoObject.Journal

Parameters

queueinfoObject
Queue information (MSMQQueueInfo) object used to define a queue.

Property Values

Set Journal to one of the following values:

MQ_JOURNAL
When a message is removed from the queue, it is stored in the queue journal.
MQ_JOURNAL_NONE
The default. Messages are not stored in a queue journal when they are removed from the queue.

Remarks

The MSMQQueueInfo.Journal property is used to enforce target journaling for the destination queue. When target journaling is enabled, Message Queuing stores a copy of each message removed from the queue in the destination queue's journal. For information on target journaling, see Target Journaling.

The size of the queue journal can be set using the MSMQQueueInfo.JournalQuota property.

Setting the MSMQQueueInfo.Journal property does not create a queue journal. Queue journals are system queues generated by MSMQ. For information on queue journals, see Journal Queues.

Setting and Retrieving the Journaling Level

To specify the journaling level when creating the queue, set the MSMQQueueInfo.Journal property and call the MSMQQueueInfo.Create method.

To reset the journaling level of an open queue, set MSMQQueueInfo.Journal to a new level and call the MSMQQueueInfo.Update method. This method updates the queue information stored by Message Queueing. For public queues, this information is stored in the directory service. For private queues, this information is stored on the computer where the messages of the queue are stored.

To retrieve the stored journaling level of a queue, call the MSMQQueueInfo.Refresh method and inspect the MSMQQueueInfo.Journal property.

Equivalent API Function Property

When using API function calls, the journaling level of the queue can be set and retrieve using the PROPID_Q_JOURNAL property.

Example Code

The following example code is included in the Platform SDK.

For an example of | See
Setting and retrieving the journaling level of an existing queue | Setting MSMQQueueInfo.Journal Retrieving MSMQQueueInfo.Journal

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQQueueInfo, MSMQQueueInfo.Create, MSMQQueueInfo.JournalQuota, MSMQQueueInfo.Refresh, MSMQQueueInfo.Update, PROPID_Q_JOURNAL


MSMQQueueInfo.JournalQuota

Optional. The JournalQuota property of the MSMQQueueInfo object specifies the maximum size (in kilobytes) of the queue journal.

Type: | Long
Run time: | Read/write

queueinfoObject.Journal

Parameters

queueinfoObject
Queue information (MSMQQueueInfo) object that defines the queue.

Property Values

Maximum size (in kilobytes) of the queue journal (the default is INFINITE).

Remarks

MSMQQueueInfo.JournalQuota is used along with MSMQQueueInfo.Journal to request target journaling. For information on target journaling, see Target Journaling.

Setting and Retrieving the Journal Quota

To specify the maximum size of the queue journal when creating a destination queue, set the MSMQQueueInfo.JournalQuota property and call the MSMQQueueInfo.Create method.

To reset the maximum size of the queue journal, set MSMQQueueInfo.JournalQuota to a new level and call the MSMQQueueInfo.Update method. This method updates the queue information stored by Message Queueing. For public queues, this information is stored in the directory service. For private queues, this information is stored on the computer where the messages of the queue are stored.

To retrieve the stored maximum size of a queue journal, call the MSMQQueueInfo.Refresh method and inspect the MSMQQueueInfo.JournalQuota property.

Equivalent API Function Property

When using API function calls, the maximum size of the queue journal can be set and retrieved using PROPID_Q_JOURNAL_QUOTA.

Example Code

The following example code is included in the Platform SDK.

For an example of | See
Setting and retrieving maximum size of a queue journal | Setting MSMQQueueInfo.JournalQuota Retrieving MSMQQueueInfo.JournalQuota

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQQueueInfo, MSMQQueueInfo.Create, MSMQQueueInfo.Journal, MSMQQueueInfo.Refresh, MSMQQueueInfo.Update, PROPID_Q_JOURNAL_QUOTA


MSMQQueueInfo.Label

Optional. The Label property of the MSMQQueueInfo object specifies a description of the queue.

Type: | String
Run time: | Read/write

queueinfoObject.Label

Parameters

queueinfoObject
The queue information (MSMQQueueInfo) object that defines the queue.

Property Values

Queue label
Application-defined string (default is ""). The maximum length of the string is MQ_MAX_Q_LABEL_LEN (124 Unicode characters).

Remarks

The label of the queue can be used to identify the queue. For example, queues that accept incoming message may all use the label "Incoming Queue". (The examples provided in the Platform SDK create only queues with the label "Test Queue".)

Locating Queues based on Labels

The MSMQQueueInfo.Label property can be used as search criteria when making a query of existing public queues. See the MSMQQuery.LookupQueue method for details on running a query.

Setting and Retrieving the Queue Label

To specify the label when creating the queue, set the MSMQQueueInfo.Label property and call the MSMQQueueInfo.Create method.

To reset the label of an open queue, set MSMQQueueInfo.Label to a new value and call the MSMQQueueInfo.Update method. This method updates the queue information stored by Message Queueing. For public queues, this information is stored in the directory service. For private queues, this information is stored on the computer where the messages of the queue are stored.

To retrieve the stored label of a queue, call the MSMQQueueInfo.Refresh method and inspect the MSMQQueueInfo.Label property.

Using Null characters in strings

Message Queuing COM components ignore any characters that follow the first Null character in a string without returning an error.

Equivalent API function property

When using API function calls, the label of the queue can be set and retrieved using the PROPID_Q_LABEL property.

Example Code

The following example code is included in the Platform SDK.

For an example of | See
Setting and retrieving the label of an existing queue | Setting MSMQQueueInfo.Label Retrieving MSMQQueueInfo.Label

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQQueueInfo, MSMQQueueInfo.Create, MSMQQueueInfo.Refresh, MSMQQueueInfo.Update, PROPID_Q_LABEL


MSMQQueueInfo.ModifyTime

Read-only. The ModifyTime property of the MSMQQueueInfo object indicates when the queue properties of a public and private queue (introduced in MSMQ 2.0) were last updated.

Type: | Date Variant
Run time: | Read-only

queueinfoObject.ModifyTime

Parameters

queueinfoObject
Queue information (MSMQQueueInfo) object that defines the queue.

Return Values

Date and time when the queue properties were last updated (includes when the queue was created and the last time MSMQQueueInfo.Update was called).

Remarks

Message Queuing sets this property, storing the value of the property when the queue is created and when MSMQQueueInfo.Update is called. Once retrieved, the value of MSMQQueueInfo.ModifyTime can be manipulated using standard Microsoft® Visual Basic® date and time functions such as Date$ and Time$. For descriptions of Visual Basic functions, see the Visual Basic documentation.

When MSMQQueueInfo.ModifyTime is displayed, Visual Basic automatically converts the property value to the local system time and system date.

Locating Queues Based on Modify Time

The MSMQQueueInfo.ModifyTime property can be used as search criteria when making a query of existing public queues. See the MSMQQuery.LookupQueue method for details on running a query.

Retrieving the Modify Time

To retrieve the stored modify time of a queue, call the MSMQQueueInfo.Refresh method and inspect the MSMQQueueInfo.ModifyTime property. Message Queuing stores the modify time in the directory service (for public queues) and on the local computer (for private queues). The local value of MSMQQueueInfo object is not updated until the MSMQQueueInfo.Refresh method is called.

Equivalent API function property

When using API function calls, the date and time the queue properties were last modified can be retrieved using the PROPID_Q_MODIFY_TIME property.

Example Code

The following example code is included in the Platform SDK.

For an example of | See
Example code of retrieving the date and time when the properties of an existing queue were last modified | Retrieving MSMQQueueInfo.ModifyTime

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQQueueInfo, MSMQQueueInfo.Refresh, MSMQQueueInfo.Update, PROPID_Q_MODIFY_TIME


MSMQQueueInfo.MulticastAddress

(Introduced in MSMQ 3.0.) The MulticastAddress property of the MSMQQueueInfo object specifies the multicast address associated with the queue.

Type: | String
Run time: | Read/write

queueinfoObject.MulticastAddress

Parameters

queueinfoObject
Queue information (MSMQQueueInfo) object that defines the queue.

Return Value

A string containing a valid multicast address (in the form shown below) or a zero length string. A zero length sting "" indicates that the queue is not associated with a multicast address.

<address>:<port>

Remarks

The MSMQQueueInfo.MulticastAddress property is used to associate a queue with a multicast address that can be used when sending messages. When the sending application sends messages to a multicast address, Message Queuing sends a copy of the message to every queue associated with that address.

Locating Queues Based on Multicast Addresses

The MSMQQueueInfo.MulticastAddress property can be used as search criteria when making a query of existing public queues. See the MSMQQuery.LookupQueue method for details on running a query.

Disassociating a Queue from a Multicast Address

The following example disassociates a know queue from a multicast address.

Dim qinfo as New MSMQQueueInfo
qinfo.Pathname = ".\testqueue"
qinfo.Refresh
qinfo.MulticastAddress = ""
qinfo.Update

Setting and Retrieving the Multicast Address

To specify the multicast address when creating the queue, set the MSMQQueueInfo.MulticastAddress property and call the MSMQQueueInfo.Create method.

To reset the multicast address of an open queue, set MSMQQueueInfo.MulticastAddress to a new value and call the MSMQQueueInfo.Update method. This method updates the queue information stored by Message Queueing. For public queues, this information is stored in the directory service. For private queues, this information is stored on the computer where the messages of the queue are stored.

To retrieve the stored multicast address of a queue, call the MSMQQueueInfo.Refresh method and inspect the MSMQQueueInfo.MulticastAddress property.

Using Null characters in strings

Message Queuing COM components ignore any characters that follow the first Null character in a string without returning an error.

Equivalent API function property

When using API functions, the multicast address associated with the queue can be set and retrieved using the PROPID_Q_MULTICAST_ADDRESS property.

Requirements

Windows NT/2000 or later: Requires Whistler.
Windows 95/98/Me: Unsupported.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQQuery.LookupQueue, MSMQQueueInfo.Create, MSMQQueueInfo.Refresh , MSMQQueueInfo.Update, PROPID_Q_MULTICAST_ADDRESS


MSMQQueueInfo.PathName

Required. The PathName property of the MSMQQueueInfo object specifies the name of the computer where the queue's messages are stored, if the queue is public or private, and the name of the queue.

Type: | String
Run time: | Read/write

queueinfoObject.PathName

Parameters

queueinfoObject
Queue information (MSMQQueueInfo) object that defines the queue.

Property Values

String. The maximum length for the complete Message Queuing pathname is MQ_MAX_Q_NAME_LEN (124 Unicode characters).

Remarks

The MSMQQueueInfo.PathName property is the only property required when calling the MSMQQueueInfo.Create method. For information on how Message Queuing creates queues, see Creating Queues.

When setting this property, you can use specify the UNC or DNS pathname for the queue. For information on queue pathnames, see Queue Pathnames.

The MSMQQueueInfo.PathName property cannot be reset after the queue is created. An MQ_ERROR_PROPERTY_NOTALLOWED error is returned if any attempt is made to set this property after the queue is created.

Pathname Syntax

Here are three examples of Message Queuing pathnames. The first two examples indicate two public queues (one on a local computer and the other on a remote computer), and the third example indicates a private queue.

"myMachine\myPublicQueue"
"otherMachine\otherPublicQueue"
"myMachine\Private$\myPrivateQueue"

As a shortcut, you can substitute a period "." for the local machine. So myPublicQueue and myPrivateQueue could be specified on the local machine as:

".\myPublicQueue"
".\Private$\myPrivateQueue"

Valid Characters and Maximum Size

The set of valid characters for the queue pathname vary depending on the version of Message Queuing that is creating the queue. The following table lists the characters that cannot be used.

Message Queuing version | Invalid queue name characters
MSMQ 1.0 | \ (back slash) ; semicolons) CR (ascii 13); private queues only LF (ascii 10); private queues only
MSMQ 2.0 and later | \ (back slash) ; (semicolons) CR (ascii 13) LF (ascii 10) + (plus) , (comma) " (double quote)

The name of the queue is case insensitive (for example, "MyQueue" and "myQueue" are treated as the same name) and can be up to 124 Unicode characters.

The maximum length of the name of the queue is 124 Unicode characters, However, using names longer than 64 Unicode characters may cause a slight reduction in performance. Furthermore, they are not easily displayed in the directory service.

Public and Private Queues

Public queues are available to other applications and are registered in the directory service.

Private queues are not available to other applications and are registered on the local computer. They are only created on the local computer and it is the application's responsibility to ensure that all queue names on the local computer are unique. If a private queue name already exists when MSMQQueueInfo.Create is called, Message Queuing returns an MQ_ERROR_QUEUE_EXISTS error to the application.

For information about public and private queues, see Destination Queues. Both types of queues exist until deleted explicitly.

Foreign Queues

Foreign public queues (queues located outside the enterprise) are created in the same way as an Message Queuing public queue. For foreign queues, the PathName property specifies the name of the foreign computer as it is defined in the directory service. For information on foreign computers, see MSMQ Connector Servers.

Referencing queues within a cluster

To access a queue within a cluster, use the virtual server or node in place of the name of the computer. Note that Message Queuing runs on the node independently from any virtual servers that are currently running on the node.

Null characters in strings

Message Queuing COM components ignore any characters that follow the first Null character in a string without returning an error.

Setting and Retrieving the Queue Pathname

To specify the pathname when creating the queue, set the MSMQQueueInfo.PathName property and call the MSMQQueueInfo.Create method.

To retrieve the stored pathname of a queue, call the MSMQQueueInfo.Refresh method and inspect the MSMQQueueInfo.PathName property.

Equivalent API function property

When using API functions, the pathname of the queue can be set and retrieved using the PROPID_Q_PATHNAME property.

Example Code

The following example code is included in the Platform SDK.

For an example of | See
Specifying the pathname when creating a queue | Creating a Transactional Queue
Retrieving the pathname of an existing queue | Retrieving MSMQQueueInfo.Pathname

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQQueueInfo, MSMQQueueInfo.Create, MSMQQueueInfo.Refresh, PROPID_Q_PATHNAME


MSMQQueueInfo.PathNameDNS

(Read-only, introduced in MSMQ 2.0.) The PathNameDNS property indicates the DNS pathname of the queue. Message Queuing generates the DNS pathname whenever this property is specified.

Type: | String
Run time: | Read-only

queueinfoObject.PathNameDNS

Parameters

queueinfoObject
Queue information (MSMQQueueInfo) object that defines the queue.

Property Values

A string value that includes the DNS pathname of the queue.

Remarks

The MSMQQueueInfo.PathNameDNS property can be used to only retrieve the DNS pathname of the queue. It cannot be used to specify the pathname of a queue when creating the queue, or when retrieving queue properties within a query.

Equivalent API function property

When using API functions, the DNS pathname of an existing queue can be retrieved using the PROPID_Q_PATHNAME_DNS property.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQQueueInfo, PROPID_Q_PATHNAME_DNS


MSMQQueueInfo.PrivLevel

Optional. The PrivLevel property of the MSMQQueueInfo object specifies whether the queue accepts private (encrypted) messages, non-private messages, or both.

Type: | Long
Run time: | Read/write

queueinfoObject.PrivLevel

Parameters

queueinfoObject
The queue information (MSMQQueueInfo) object that defines the queue.

Property Values

Set PrivLevel to one of the following values:

MQ_PRIV_LEVEL_NONE
The queue accepts only non-private (clear) messages.
MQ_PRIV_LEVEL_BODY
The queue accepts only private (encrypted) messages.
MQ_PRIV_LEVEL_OPTIONAL
The default. The queue does not force privacy. It accepts private (encrypted) messages and non-private (clear) messages.

Remarks

The application can set the privacy level of queues and messages. If the privacy level of the message does not correspond to the privacy level of the queue, the message is rejected by the queue, and, if the sending application requested a negative acknowledgment message when it sent the message, MQMSG_CLASS_BAD_ENCRYPTION is returned to the sending application to indicate the message was rejected.

Setting and Retrieving the Privacy Level

To specify the privacy level when creating the queue, set MSMQQueueInfo.PrivLevel and call the MSMQQueueInfo.Create method.

To reset the privacy level of an open queue, set MSMQQueueInfo.PrivLevel to a new level and call the MSMQQueueInfo.Update method. This method updates the queue information stored by Message Queueing. This method updates the queue information stored by Message Queueing. For public queues, this information is stored in the directory service.

To retrieve the stored privacy level of a queue, call the MSMQQueueInfo.Refresh method and inspect the MSMQQueueInfo.PrivLevel property.

Encrypting messages

Private messages can be encrypted in two ways.

  • By the sending queue manager. For information on how the sending Queue manager encrypts messages, see MSMQ-Encrypted Messages.
  • By the sending application. For information on how an application encrypts messages, see Application-Encrypted Messages

Equivalent API function property

When using API functions, the privacy level of the queue can be set and retrieved using the PROPID_Q_PRIV_LEVEL property.

Example Code

The following example code is included in the Platform SDK.

For an example of | See
Setting and retrieving the privacy level of an existing queue | Setting MSMQQueueInfo.PrivLevel Retrieving MSMQQueueInfo.PrivLevel

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQQueueInfo, MSMQQueueInfo.Create, MSMQQueueInfo.Refresh, MSMQQueueInfo.Update, PROPID_Q_PRIV_LEVEL


MSMQQueueInfo.QueueGuid

Read-only. The QueueGuid property of the MSMQQueueInfo object identifies the public queue associated with the MSMQQueueInfo object. The queue identifier is created by Message Queuing when the queue is created.

Type: | String (GUID format)
Run time: | Read-only

queueinfoObject.QueueGuid

Parameters

queueinfoObject
Queue information (MSMQQueueInfo) object that defines the queue.

Return Values

GUID of public queue.

Remarks

Message Queuing sets MSMQQueueInfo.QueueGuid when the queue is created. This property identifies the queue defined by the MSMQQueueInfo object. It does not identify an open instance of the queue.

Locating Queues Based on Identifiers

The MSMQQueueInfo.QueueGuid property can be used as search criteria when making a query of existing public queues. See the MSMQQuery.LookupQueue method for details on running a query.

Retrieving the Create Time

To retrieve the stored create time of a queue, call the MSMQQueueInfo.Refresh method and inspect the MSMQQueueInfo.QueueGuid property. Message Queuing stores the identifier in the directory service (for public queues) and on the local computer (for private queues). The local value of MSMQQueueInfo object is not updated until the MSMQQueueInfo.Refresh method is called.

Equivalent API Function Property

When using API function calls, you can retrieve the QUID identifier of an existing queue by retrieving PROPID_Q_INSTANCE.

Example Code

The following example code is included in the Platform SDK.

For an example of | See
Retrieving the GUID identifier of an existing queue | Retrieving MSMQQueueInfo.QueueGuid

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQQueueInfo, MSMQQueueInfo.Refresh, PROPID_Q_INSTANCE


MSMQQueueInfo.Quota

Optional. The Quota property of the MSMQQueueInfo object specifies the maximum size (in kilobytes) of the queue.

Type: | Long
Run time: | Read/write

queueinfoObject.Quota

Parameters

queueinfoObject
Queue information (MSMQQueueInfo) object that defines the queue.

Property Values

Long integer (default is INFINITE). Maximum size is based on the memory available on the computer where the queue's messages are stored.

Remarks

MSMQQueue.Quota is typically set when the queue is created. However, the maximum size of an existing queue can be changed as well.

Setting and Retrieving the Quota

To specify the quota when creating a queue, set MSMQQueueInfo.Quota and call the MSMQQueueInfo.Create method.

To reset the quota of an existing queue, set MSMQQueueInfo.Quota to a new level and call the MSMQQueueInfo.Update method. This method updates the queue information stored by Message Queueing.

To retrieve the quota of a queue, call the MSMQQueueInfo.Refresh method. For public queues, this information is retrieved from the Directory Service. For private queues, this information is retrieved from the local computer.

Equivalent API function property

When using API functions, the quota of the queue can be set and retrieved using the PROPID_Q_QUOTA property.

Example Code

The following example code is included in the Platform SDK.

For an example of | See
Example code of setting and retrieving the maximum size of an existing queue | Setting MSMQQueueInfo.Quota Retrieving MSMQQueueInfo.Quota

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQQueueInfo, MSMQQueueInfo.Create, MSMQQueueInfo.Refresh, MSMQQueueInfo.Update, PROPID_Q_QUOTA


MSMQQueueInfo.ServiceTypeGuid

Optional. The ServiceTypeGuid property of the MSMQQueueInfo object specifies the type of service provided by the queue.

Type: | String (GUID format)
Run time: | Read/write

queueinfoObject.ServiceTypeGuid

Parameters

queueinfoObject
Queue information (MSMQQueueInfo) object that defines the queue.

Property Values

GUID. Predefined or application generated.

Remarks

MSMQQueueInfo.ServiceTypeGuid is used to identify the queue by its type of service. This property is typically set when the queue is created, however, the service type identifier of an existing queue can be changed as well.

Using the Service Type to Locate Queues

The service type identifier of a queue can be used to locate public queues registered in the directory service (see MSMQQuery.LookupQueue).

Setting and Retrieving the Service Type Identifier

To specify the service type identifier when creating a queue, set MSMQQueueInfo.ServiceTypeGuid and call the MSMQQueueInfo.Create method.

Note To generate a GUID, run the Uuidgen.exe program provided by MSDN.

To reset the service type of an open queue, set MSMQQueueInfo.ServiceTypeGuid to a new GUID and call the MSMQQueueInfo.Update method. This method updates the queue information stored by Message Queueing.

To retrieve the service type identifier of a queue, call the MSMQQueueInfo.Refresh method.

Equivalent API function property

When using API functions, the service type identifier of the queue can be set and retrieved using the PROPID_Q_TYPE property.

Example Code

The following example code is included in the Platform SDK.

For an example of | See
Setting and retrieving the service type identifier of an existing queue | Setting MSMQQueueInfo.ServiceTypeGuid Retrieving MSMQQueueInfo.ServiceTypeGuid

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQQuery.LookupQueue, MSMQQueueInfo, MSMQQueueInfo.Authenticate, MSMQQueueInfo.Create, MSMQQueueInfo.Refresh, MSMQQueueInfo.Update, PROPID_Q_TYPE


MSMQQueueInfos

The MSMQQueueInfos object provides methods for enumerating through the collection of public queues returned by the MSMQQuery.LookupQueue method.

Queue collections are dynamic

The information in the collection of queues is dynamic, with other clients looking at the queues or deleting them from the collection at any time. As a consequence, there is no queue count available for enumerating through the collection. In place of a queue count, MSMQQueueInfos provides an end-of-list (EOL) mechanism to indicate when you have completely enumerated through the collection.

The following example shows how the EOL mechanism is used in a standard Microsoft® Visual Basic® type While loop.

'Display the format name of all MAPI input queues.
Dim queryMyQuery as new MSMQQuery
Dim qinfoCurrent as MSMQQueueInfo
'Get some interesting queues.
Dim qs as MSMQQueueInfos
Set qs = queryMyQuery.LookupQueue (
    ServiceTypeGuid := "{5EADC0D0-7182-11CF-A8FF-0020AFB8FB50}")
qs.Reset
Set qinfoCurrent = qs.Next
While not qinfoCurrent is Nothing
      msgbox qinfoCurrent.FormatName
      Set qinfoCurrent = qs.Next
Wend

Methods

The following table lists the methods of the MSMQQueueInfos object.

Method | Description
Next | Returns the next queue in the collection.
Reset | Returns the cursor to the start of the results of a query.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQQuery, MSMQQuery.LookupQueue


MSMQQueueInfos.Next

The Next method of the MSMQQueueInfos object returns the next queue in the collection.

queueinfosObject.Next

Parameters

queueinfosObject
Collection that contains the queues.

Return Values

MSMQQueueInfo object.

For information on return codes, see Message Queuing Error and Information Codes.

Remarks

When the collection of queues is returned by the MSMQQuery.LookupQueue method, the collection cursor is not pointing at the first queue in the collection. The receiving application must call MSMQQueueInfos.Reset to set the cursor to the front of the collection and then call MSMQQueueInfos.Next to move the cursor to the first queue. After the cursor is pointing at the first queue, MSMQQueueInfos.Next can be called repeatedly to enumerate through the collection.

MSMQQueueInfos.Next returns Null if there are no queues in the collection or the cursor is at the end of the collection (EOL).

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQQuery.LookupQueue, MSMQQueue.Reset, MSMQQueueInfo, MSMQQueueInfos


MSMQQueueInfos.Reset

The Reset method of the MSMQQueueInfos object returns the collection cursor to the start of the collection.

queueinfosObject.Reset

Parameters

queueinfosObject
Collection (MSMQQuery) object that represents a collection of queues.

Return Values

For information on return codes, see Message Queuing Error and Information Codes.

Remarks

The MSMQQueueInfos.Reset method moves the cursor to the start of the collection. To move the cursor to the first queue of the collection, call MSMQQueueInfos.Next.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQQuery, MSMQQueueInfos


MSMQTransaction

The MSMQTransaction object represents a transaction object obtained externally using MSMQCoordinatedTransactionDispenser object, or created internally using MSMQTransactionDispenser object.

The MSMQTransaction object provides methods for committing to or terminating the transaction, as well as one read-only property that represents the underlying transaction object.

To use the transaction object, the MSMQTransaction object must be specified by the Transaction parameter of one of the following methods

When sending messages:

  • MSMQMessage.Send

When retrieving messages without using message lookup identifiers:

  • MSMQQueue.Receive
  • MSMQQueue.ReceiveCurrent

When retrieving messages using message lookup identifiers:

  • MSMQQueue.ReceiveFirstByLookupId
  • MSMQQueue.ReceivePreviousByLookupId
  • MSMQQueue.ReceiveByLookupId
  • MSMQQueue.ReceiveNextByLookupId
  • MSMQQueue.ReceiveLastByLookupId

Methods

The following table lists the methods of the MSMQTransaction object.

Method | Description
Abort | Terminates the transaction associated with the MSMQTransaction object.
Commit | Commits the operations requested by the transaction.
InitNew | (Introduce in MSMQ 2.0.) Creates an MSMQTransaction object based on an existing transaction.

Properties

The following table lists the properties of the MSMQTransaction object and gives their access, whether read-only or read/write; their data type; and a description.

Property | Description
Transaction Access: Read-only Data type: Long | Provides the underlying transaction object used by this transaction.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQCoordinatedTransactionDispenser, MSMQTransactionDispenser, MSMQQueue.Receive, MSMQQueue.ReceiveByLookupId, MSMQQueue.ReceiveCurrent, MSMQQueue.ReceiveFirstByLookupId, MSMQQueue.ReceiveLastByLookupId, MSMQQueue.ReceiveNextByLookupId, MSMQQueue.ReceivePreviousByLookupId, MSMQMessage.Send


MSMQTransaction.Abort

The Abort method of the MSMQTransaction object terminates the transaction associated with the MSMQTransaction object.

transactionObject.Abort( _
  [fRetaining] _
  [, fAsync] _
)

Parameters

transactionObject
Transaction (MSMQTransaction) object that identifies the transaction.
fRetaining
Optional. Boolean.
fAsync
Optional. Boolean.

Remarks

After an abort, all actions taken on the queue are rolled back. For example, if a message is sent to a queue and the transaction is aborted, the messages are not sent to the queue.

Abort is a wrapper for lTransaction::Abort. (For information on ITransaction::Abort, see the Platform SDK.)

For information on | See
The Message Queuing transaction model | Message Queuing Transactions
The types of transaction supported by MSMQ | Transaction Types
How Message Queuing sends and retrieves messages within a transaction | Sending and Retrieving Messages within a Transaction

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQCoordinatedTransactionDispenser.BeginTransaction, MSMQTransaction


MSMQTransaction.Commit

The Commit method of the MSMQTransaction object commits the operations requested by the transaction.

transactionObject.Commit( _
  [fRetaining] _
  [, grfTC] _
  [, grfRM] _
)

Parameters

transactionObject
Transaction (MSMQTransaction) object that identifies the transaction.
fRetaining
Optional. Reserved by Microsoft DTC.
grfTC
Optional. Specifies if the commit is synchronous (default) or asynchronous.

XACTTC_ASYNC: When specified, the call to commit returns as soon as the two-phase commit protocol is initiated.

XACTTC_SYNCPHASEONE: When specified, the call to commit returns after phase one of the two-phase commit protocol.

grfRM
Optional. Reserved by Microsoft DTC.

Remarks

Calling Commit does not mean that the operations requested are performed. It only means that Message Queuing guarantees that the operations will be performed as an atomic unit.

Commit is a wrapper for lTransaction::Commit. (For information on ITransaction::Commit, see the Platform SDK.)

An application must call Commit for the messages to be sent. If Commit is not called, the transaction will be terminated when the application exits.

For information on Microsoft® DTC, refer to the Microsoft Distributed Transaction Coordinator.

For information on | See
The Message Queuing transaction model | Message Queuing Transactions
The types of transaction supported by MSMQ | Transaction Types
How Message Queuing sends and retrieves messages within a transaction | Sending and Retrieving Messages within a Transaction

For information of | See
Example code of sending messages using an internal transaction | Sending a Message Using an Internal Transaction

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQCoordinatedTransactionDispenser.BeginTransaction, MSMQTransaction


MSMQTransaction.InitNew

(Introduced in MSMQ 2.0.) The InitNew method of the MSMQTransaction object creates an MSMQTransaction object based on an existing transaction, allowing Message Queuing to participate in the existing transaction.

transactionObject.InitNew( _
  varTransaction _
)

Parameters

transactionObject
An MSMQTransaction object.
varTransaction
Existing transaction that supports ITransaction.

Remarks

MSMQTransaction.InitNew is used to create an MSMQTransaction object based on an existing non-Message Queuing transaction. For example, you can associate an existing ADO transaction with an MSMQTransaction object, allowing you to perform Message Queuing operations on the ADO transaction. Subsequent calls to commit or abort the transaction would be made using MSMQTransaction.Commit and MSMQTransaction.Abort.

Note MSMQTransaction objects are also created using MSMQCoordinatedTransactionDispenser.BeginTransaction or MSMQTransactionDispenser.BeginTransaction.

A transaction object can be associated with only one MSMQTransaction object. MSMQTransaction.InitNew will fail if the transaction object is already associated with another MSMQTransaction object. For example:

  • MSMQTransaction.InitNew will fail if it is called twice on the same MSMQTransaction object.
  • MSMQTransaction.InitNew will fail if MSMQTransactionDispenser.BeginTransaction or MSMQCoordinatedTransactionDispenser.BeginTransaction is called to obtain the MSMQTransaction object before the MSMQTransaction.InitNew.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQCoordinatedTransactionDispenser.BeginTransaction, MSMQTransaction, MSMQTransaction.Abort, MSMQTransaction.Commit, MSMQTransactionDispenser.BeginTransaction


MSMQTransaction.Transaction

The Transaction property of the MSMQTransaction object provides the underlying transaction object used by this transaction.

Type: | Long
Run time: | Read-only

transactionObject.Transaction

Parameters

transactionObject
The MSMQTransaction object that represents the transaction.

Return Values

Transaction object.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQTransaction


MSMQTransactionDispenser

The MSMQTransactionDispenser object is used to create a MSMQTransaction object that represents a new internal transaction object. The new MSMQTransaction object can then be used in calls to send or retrieve messages.

For information on internal transactions, see Message Queuing Internal Transactions.

Methods

The following table lists the methods of the MSMQTransactionDispenser object.

Method | Description
BeginTransaction | Creates a new Message Queuing transaction object.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQTransaction


MSMQTransactionDispenser.BeginTransaction

The BeginTransaction method of the MSMQTransactionDispenser object creates a new MSMQTransaction object that is used to send or retrieve messages within an internal transaction.

Set transactionObject = transactiondispenserObject.BeginTransaction

Parameters

transactionObject
Transaction (MSMQTransaction) object that identifies the transaction.
transactiondispenserObject
Transaction dispenser (MSMQTransactionDispenser) object that creates the transaction.

Return Values

MSMQTransaction object that represents the transaction.

Remarks

The MSMQTransaction object returned by BeginTransaction must be associated with all transactional queues and messages associated with this transaction. However, this does not mean that a transactional queue associated with this transaction cannot be used by other transactions. A single transactional queue can be associated with any number of transactions.

For information on | See
The Message Queuing transaction model | Message Queuing Transactions
The types of transaction supported by MSMQ | Transaction Types
How Message Queuing sends and retrieves messages within a transaction | Sending and Retrieving Messages within a Transaction

For an example of | See
Using an Message Queuing internal transaction | Sending Messages Using an Internal Transaction (COM)

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqoai.h.
Library: Use Mqoa.lib.

See Also

MSMQTransaction, MSMQTransactionDispenser


Message Queuing Mail Reference

[The Message Queuing Mail Service is available only on Windows NT4 and Windows 2000.]

This reference section describes the functions, properties, structures, and COM components provided by the Message Queuing Mail Software Development Kit (SDK).

Note For information on the basic Message Queuing functions, properties, structures, and COM components provided by the Message Queuing (MSMQ) API, refer to the Message Queuing Reference. For background information on Message Queuing concepts, refer to About Message Queuing.

For information on | See
Mail functions | Message Queuing Mail Functions
Mail structures | Message Queuing Mail Structures
Mail COM object classes, methods, properties, and events | Message Queuing Mail COM Components
Background information about the MSMQ Exchange Connector | MSMQ Exchange Connector


Message Queuing Mail Functions

[The Message Queuing Mail Service is available only on Windows NT4 and Windows 2000.]

The following topics describe the Message Queuing mail functions. These functions allow you to parse and compose messages, and free the memory allocated when using these functions.

Message Queuing mail functions include the following.

Function | Description
MQMailComposeBody | Composes a message body from information provided by an e-mail data structure.
MQMailFreeMemory | Frees memory allocated by Message Queuing mail functions.
MQMailParseBody | Parses the body of an Message Queuing mail message and places the information in a mail data structure.


MQMailComposeBody

[The Message Queuing Mail Service is available only on Windows NT4 and Windows 2000.]

The MQMailComposeBody function composes a message body from information provided by an e-mail data structure. The message body is formatted in Message Queuing mail format.

STDAPI MQMailComposeBody(
  LPMQMailEMail pEMail,
  ULONG FAR *pcbBuffer,
  LPBYTE FAR ppbBuffer
);

Parameters

pEMail
[in] Pointer to an MQMailEMail structure that contains mail information.
pcbBuffer
[out] Pointer to the location of the size of the newly allocated message body buffer.
ppbBuffer
[out] Pointer to the address of the newly allocated message body buffer.

Return Values

S_OK
Indicates success.
E_INVALIDARG
Invalid arguments.
Other system errors
Use the FAILED(hr) macro to test for errors.

Remarks

The MQMailComposeBody function is used to create the body of an Message Queuing mail message. It allocates a message body buffer and fills it with an Message Queuing mail format representation of the data specified by the pEMail parameter.

Mail messages can be sent to MAPI clients via the MSMQ MAPI Transport Provider, Microsoft® Exchange users via the MSMQ Exchange Connector, or other Message Queuing applications.

When this function succeeds, the application must free the memory allocated for the message body buffer by calling MQMailFreeMemory after the buffer is used.

The following table defines which members of the MQMailEMail structure are required to compose a message body for each type of e-mail. Required properties are marked with an X (default values can be used). When composing an e-mail object, all required members must have valid values, otherwise an error condition is raised by MQMailComposeBody.

MQMailEMail | Text Message | Form | Tnef | Delivery Report | Non- Delivery Report
pFrom | X | X |  |  |
szSubject | X (Empty string) | (Empty string) |  |  |
fRequestDeliveryReport | X (False) | X (False) |  |  |
fRequestNonDeliveryReport | X (False) | X (False) |  |  |
pftDate | X (Current time) | X (Current time) |  | X (Current time) | X (Current time)
pRecips | X | X | X | X | X
iType | X | X | X | X | X
form |  | X |  |  |
message | X |  |  |  |
tnef |  |  | X |  |
DeliveryReport |  |  |  | X |
NonDeliveryReport |  |  |  |  | X

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqmail.h.
Library: Use Mqmail.lib.

See Also

MQMailEMail, MQMailFreeMemory


MQMailFreeMemory

[The Message Queuing Mail Service is available only on Windows NT4 and Windows 2000.]

The MQMailFreeMemory function frees memory allocated by MQMailComposeBody and MQMailParseBody.

STDAPI_(void) MQMailFreeMemory(
  LPVOID lpBuffer
);

Parameters

lpBuffer
[in] Pointer to allocated memory.

Return Values

None.

Remarks

The application should free all memory allocated by MQMailComposeBody and MQMailParseBody.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqmail.h.
Library: Use Mqmail.lib.

See Also

MQMailComposeBody, MQMailParseBody


MQMailParseBody

[The Message Queuing Mail Service is available only on Windows NT4 and Windows 2000.]

The MQMailParseBody function parses the body of an Message Queuing mail message and places the information in a mail data structure.

STDAPI MQMailParseBody(
  ULONG cbBuffer,
  LPBYTE FAR *pbBuffer,
  LPMQMailEMail FAR *ppEMail
);

Parameters

cbBuffer
[in] Buffer size.
pbBuffer
[in] Pointer to the buffer containing the body of the Message Queuing mail message.
ppEMail
[out] Pointer to the address of the newly allocated MQMailEMail structure that contains the copied mail information.

Return Values

If the function succeeds, the return value is S_OK.

If the function has invalid arguments, the return value is E_INVALIDARG.

If the function returns other system errors, use the FAILED(hr) macro to test for errors.

Remarks

The MQMailParseBody function is used to convert the body of an Message Queuing mail message so its information can be used by an Message Queuing application.

The application must free the memory allocated for the MQMailEMail object once the parsed information is used. To free the memory, call MQMailFreeMemory.

Message Queuing mail messages can be received from another Message Queuing application or either of the two Message Queuing mail services: MSMQ MAPI Transport Provider or the MSMQ Exchange Connector.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqmail.h.
Library: Use Mqmail.lib.

See Also

MQMailEMail, MQMailFreeMemory


Message Queuing Mail Structures

[The Message Queuing Mail Service is available only on Windows NT4 and Windows 2000.]

The following topics describe the Message Queuing mail structures.

These Message Queuing mail structures include the following.

Structure | Description
MQMailDeliveryReportData | Describes a delivery report message.
MQMailEMail | Describes mail information in a mail format.
MQMailEMailType | Describes the type of mail: text message, form, TNEF message, delivery report, or non-delivery report e-mail.
MQMailFormData | Describes a message form, giving the name of the form and listing the fields the form contains.
MQMailFormField | Describes a form field.
MQMailFormFieldData | Describes the data in a form field.
MQMailFormFieldList | Describes a list of form fields.
MQMailFormFieldType | Describes the field type.
MQMailMessageData | Describes a mail message.
MQMailNonDeliveryReportData | Describes a non-delivery report message.
MQMailRecip | Describes a recipient.
MQMailRecipList | Lists the recipients of the mail.
MQMailRecipType | Describes the type of recipient.
MQMailTnefData | Describes a TNEF message, providing the binary TNEF data.


MQMailDeliveryReportData

[The Message Queuing Mail Service is available only on Windows NT4 and Windows 2000.]

The MQMailDeliveryReportData structure describes a delivery report message. It lists the recipients who received the original mail, the original mail subject, and the original mail submission time.

The pftDeliverTime member of each recipient in the pDeliveredRecips recipient list specifies the time when the original mail was delivered to the recipient.

typedef struct MQMailDeliveryReportData_tag
  {
   LPMQMailRecipList  pDeliveredRecips;  //Delivered recipients.
   LPSTR              szOriginalSubject; //Original subject.
   LPFILETIME         pftOriginalDate;   //Original submission time.
} MQMailDeliveryReportData, FAR * LPMQMailDeliveryReportData;

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqmail.h.

See Also

MQMailEMail, MQMailRecipList


MQMailEMail

[The Message Queuing Mail Service is available only on Windows NT4 and Windows 2000.]

The MQMailEMail structure describes mail information in a mail format. It is used for translating information between the basic mail format and the Message Queuing mail format used by Message Queuing mail services.

typedef struct  MQMailEMail_tag
{
  LPSTR                 szSubject;  //Subject of mail.
  BOOL                  fRequestDeliveryReport;
  BOOL                  fRequestNonDeliveryReport;
  LPFILETIME            pftDate;    //Time sent.
  LPMQMailRecip         pFrom;      //Sender.
  LPMQMailRecipList     pRecips;    //List of recipients.
  LPMQMailEMailType     iType;      //Type of Email (message, form)
  union                             //Union of available Email types.
  {
     MQMailFormData     form;      //when type is MQMailEMail_FORM
     MQMailMessageData  message;   //when type is MQMailEMail_MESSAGE
     MQMailTnefData     tnef       //when type is MQMailEMail_TNEF
     MQMailDeliveryReportData       DeliveryReport; //when type is MQMailEMail_DELIVERY_REPORT
     MQMailNonDeliveryReportData    NonDeliveryReport; //when type is MQMailEMail_NON_DELIVERY_REPORT
  };
  LPVOID                pReserved;  //Should be set to NULL.
} MQMailEMail, FAR* LPMQMailEMail;

For information on Message Queuing mail services, see MSMQ MAPI Transport Provider and MSMQ Exchange Connector.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqmail.h.

See Also

MQMailEMailType, MQMailFormData, MQMailDeliveryReportData, MQMailMessageData, MQMailNonDeliveryReportData, MQMailRecip, MQMailRecipList, MQMailTnefData


MQMailEMailType

[The Message Queuing Mail Service is available only on Windows NT4 and Windows 2000.]

The MQMailEMailType structure describes the type of mail: text message, form, TNEF message, delivery report, or non-delivery report e-mail.

typedef enum  MQMailEMailType_enum
{
  MQMailEMail_MESSAGE,               //Mail is text message.
  MQMailEMail_FORM,                  //Mail is form with fields.
  MQMailEMail_TNEF,                  //Mail is in MAPI TNEF format.
  MQMailEMail_DELIVERY_REPORT        //Mail is a delivery report.
  MQMailEMail_NON_DELIVERY_REPORT    //Mail is a non-delivery report.
} MQMailEMailType;

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqmail.h.

See Also

MQMailEMail


MQMailFormData

[The Message Queuing Mail Service is available only on Windows NT4 and Windows 2000.]

The MQMailFormData structure describes a message form, giving the name of the form and listing the fields the form contains.

typedef struct  MQMailFormData_tag
{
  LPSTR                   szName;     //Name of form.
  LPMQMailFormFieldList   pFields;    //List of fields.
} MQMailFormData, FAR* LPMQMailFormData;

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqmail.h.

See Also

MQMailEMail, MQMailFormFieldList


MQMailFormField

[The Message Queuing Mail Service is available only on Windows NT4 and Windows 2000.]

The MQMailFormField structure describes a form field. The Message Queuing mail API supports String, Integer, Boolean, Double, and Currency fields.

typedef struct  MQMailFormField_tag
{
  LPSTR                szName;   //Name of field.
  MQMailFormFieldType  iType;    //Type of value.
  MQMailFormFieldData  Value;    //Union of available types.
} MQMailFormField, FAR*LPMQMailFormField;

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqmail.h.

See Also

MQMailEMail, MQMailFormFieldData, MQMailFormFieldType


MQMailFormFieldData

[The Message Queuing Mail Service is available only on Windows NT4 and Windows 2000.]

The MQMailFormFieldData structure describes the data in a form field.

typedef union  MQMailFormFieldData_tag
{
  BOOL              b;     //Specifies MQMailFormField_BOOL.
  LPSTR             lpsz;  //Specifies MQMailFormField_STRING.
  LONG              l      //Specifies MQMailFormField_LONG.
  CY                cy     //Specifies MQMailFormField_CURRENCY.
  double            dbl    //Specifies MQMailFormField_DOUBLE.

} MQMailFormFieldData, FAR*LPMQMailFormFieldData;

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqmail.h.

See Also

MQMailEMail, MQMailFormField


MQMailFormFieldList

[The Message Queuing Mail Service is available only on Windows NT4 and Windows 2000.]

The MQMailFormFieldList structure describes a list of form fields.

typedef struct  MQMailFormFieldList_tag
{
  ULONG                    cFields;  //Number of fields.
  LPMQMailFormField FAR*   apField;  //Pointer to array of field ptrs.
} MQMailFormFieldList, FAR*LPMQMailFormFieldList;

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqmail.h.

See Also

MQMailEMail, MQMailFormField


MQMailFormFieldType

[The Message Queuing Mail Service is available only on Windows NT4 and Windows 2000.]

The MQMailFormFieldType structure describes the field type.

typedef enum  MQMailFormFieldType_enum
{
  MQMailFormField_BOOL,          //Boolean data.
  MQMailFormField_STRING,        //String data.
  MQMailFormField_LONG,          //Long data.
  MQMailFormField_CURRENCY,      //Currency data.
  MQMailFormField_DOUBLE,        //Double data.
} MQMailFormFieldType;

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqmail.h.

See Also

MQMailEMail, MQMailFormField


MQMailMessageData

[The Message Queuing Mail Service is available only on Windows NT4 and Windows 2000.]

The MQMailMessageData structure describes a mail message.

typedef struct  MQMailMessageData_tag
{
  LPSTR szText;                        //Text of message.
} MQMailMessageData, FAR* LPMQMailMessageData;

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqmail.h.

See Also

MQMailEMail


MQMailNonDeliveryReportData

[The Message Queuing Mail Service is available only on Windows NT4 and Windows 2000.]

The MQMailNonDeliveryReportData structure describes a non-delivery report message. It contains the recipients to whom the original mail was not delivered and the original mail in the pOriginalEMail member.

The szNonDeliveryReason member of each recipient in the pNonDeliveredRecips recipient list specifies the reason why the original mail was not delivered to the recipient.

typedef struct MQMailNonDeliveryReportData_tag
  {
  LPMQMailRecipList  pNonDeliveredRecips;  //Non-delivered recipients.
  LPMQMailEMail      pOriginalEMail;       //Original mail.
} MQMailNonDeliveryReportData, FAR * LPMQMailNonDeliveryReportData;

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqmail.h.

See Also

MQMailEMail, MQMailRecipList


MQMailRecip

[The Message Queuing Mail Service is available only on Windows NT4 and Windows 2000.]

The MQMailRecip structure describes a recipient.

typedef struct  MQMailMessageData_tag
{
  LPSTR      szName;               //Name of recipient.
  LPSTR      szQueueLabel;         //Label of recipient's queue.
  LPSTR      szAddress;            //Recipient address.
  LPFILETIME pftDeliveryTime;      //Used in delivery reports.
  LPSTR      szNonDeliveryReason;  //Used in non-delivery reports.
} MQMailRecip, FAR*LPMQMailRecip;

Remarks

The recipient address can be an application input queue label (for Message Queuing applications), a MAPI client queue label (for the MSMQ MAPI Transport Provider), or the MSMQ Exchange user mail alias plus the MSMQ Exchange Connector's queue label in the format user-mail-alias@Exchange connector-queue-label (for MSMQ Exchange Connector).

pftDeliveryTime is valid only when the recipient is in a delivery report recipient list (for example, the pDeliveredRecips member of the MQMailDeliveryReportData structure).

szNonDeliveryReason is valid only when the recipient is in a non-delivery report recipient list, e.g. the pNonDeliveredRecips member of the MQMailNonDeliveryReportData structure.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqmail.h.

See Also

MQMailEMail, MQMailDeliveryReportData, MQMailNonDeliveryReportData, MQMailRecipList


MQMailRecipList

[The Message Queuing Mail Service is available only on Windows NT4 and Windows 2000.]

The MQMailRecipList structure lists the recipients of the mail.

typedef struct  MQMailRecipList_tag
{
  ULONG               cRecips;  //Number of recipients.
  LPMQMailRecip FAR*  apRecip;  //Array of recipient pointers.
} MQMailRecipList, FAR*LPMQMailRecipList;

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqmail.h.

See Also

MQMailEMail, MQMailRecip


MQMailRecipType

[The Message Queuing Mail Service is available only on Windows NT4 and Windows 2000.]

The MQMailRecipType structure describes the type of recipient.

typedef enum MQMailRecipType_enum
{
  MQMailRecip_TO,    //Primary recipient.
  MQMailRecip_CC,    //Copied recipient.
  MQMailRecip_BCC,   //Hidden (blind copied) recipient.

} MQMailRecipType;

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqmail.h.

See Also

MQMailEMail


MQMailTnefData

[The Message Queuing Mail Service is available only on Windows NT4 and Windows 2000.]

The MQMailTnefData structure describes a TNEF message, providing the binary TNEF data.

TNEF is a MAPI internal format that encapsulates the MAPI properties and is used by the Message Queuing mail services (the MSMQ Exchange Connector and the MSMQ MAPI Transport) to send mail to recipients who are defined as rich-text recipients. Rich-text recipients are recipients who have the Send to this recipient in Microsoft Exchange rich text format check box checked in their Exchange/MAPI address.

typedef struct MQMailTnefData_tag
{
  ULONG    cbData;               //Size of the TNEF data.
  LPBYTE lpbData;            //The tnef data buffer.
} MQMailTnefData, FAR * LPMQMailTnefData;

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in Mqmail.h.

See Also

MQMailEMail


Message Queuing Mail COM Components

[The Message Queuing Mail Service is available only on Windows NT4 and Windows 2000.]

The Message Queuing mail objects include.

Objects | Description
MSMQMailDeliveryReportData | Represents a delivery report e-mail.
MSMQMailEMail | Represents an e-mail message.
MSMQMailFormData | Represents an e-mail form.
MSMQMailFormField | Represents a field of a specific e-mail form.
MSMQMailFormFieldList | Represents a list of all the fields of a specific e-mail form.
MSMQMailNonDeliveryReportData | Represents a non-delivery report e-mail.
MSMQMailRecipient | Represents an e-mail recipient.
MSMQMailRecipientList | Represents a list of e-mail recipients.
MSMQMailTextMessageData | Represents an e-mail text message.
MSMQMailTnefData | Represents an e-mail in Transport-Neutral Encapsulation Format (TNEF) format.


MSMQMailDeliveryReportData

[The Message Queuing Mail Service is available only on Windows NT4 and Windows 2000.]

The MSMQMailDeliveryReportData object represents a delivery report e-mail. A delivery report consists of the recipients, subject, and submission time of the original e-mail.

Properties

The following table lists the properties of the MSMQMailDeliveryReportData object and gives their access, whether read-only or read/write; their data type; and a description.

Property | Description
DeliveredRecipients Access: Read/write Data type: MSMQMailRecipientList | Specifies the recipients to whom the original mail was delivered.
OriginalSubject Access: Read/write Data type: String | Specifies the subject of the original e-mail.
OriginalSubmissionTime Access: Read/write Data type: Date | Specifies the submission time of the original e-mail.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Library: Included as a resource in Mqmailoa.dll.


MSMQMailDeliveryReportData.DeliveredRecipients

[The Message Queuing Mail Service is available only on Windows NT4 and Windows 2000.]

The DeliveredRecipients property of the MSMQMailDeliveryReportData object specifies the recipients to whom the original e-mail was sent.

Type: | MSMQMailRecipientList
Run time: | Read-write

emailObject.deliveryreportdataObject.DeliveredRecipients

Parameters

emailObject
E-mail (MSMQMailEMail) object that defines the delivery report.
deliveryreportdataObject
Delivery report data (MSMQMailDeliveryReportData) object that represents the delivery report information.

Settings

MSMQMailRecipientList object.

Remarks

Each recipient in the delivered recipient list is represented by an MSMQMailRecipient object. Each recipient object includes the name and address of the recipient, the input queue of the recipient, how the message was sent to recipient, and when the message was delivered.

The MSMQMailRecipient.DeliveryTime property of the MSMQMailRecipient object specifies when the original e-mail was delivered to the recipient.

Example

This example defines a delivery report, adding two delivered recipients to the delivered recipient list of the report. The e-mail object is composed into a mail message, and each delivered recipient is displayed.

To try this example using Microsoft® Visual Basic® version 5.0, paste the code into the Code window of a form, enter a valid user address for each recipient, run the example, and click the form.

Dim email As New MSMQMailEMail
Dim msg As New MSMQMessage

Private Sub Form_Click()

   '*********************
   '*  Define e-mail
   '*********************

   'Set e-mail type to delivery report.
   email.ContentType = MSMQMAIL_EMAIL_DELIVERY_REPORT

   'Add the Recipient of the report (usually the original e-mail sender).
   email.Recipients.Add "Exchange_User", "UserAlias@ServerInputQueueLabel", MSMQMAIL_RECIPIENT_TO

   'Set subject of original mail.
   email.DeliveryReportData.OriginalSubject = "Original subject "

   'Set submission time of original mail.
   email.DeliveryReportData.OriginalSubmissionTime = CDate("5/20/94 10:16:07 PM")

  'Add two delivered recipients.
   email.DeliveryReportData.DeliveredRecipients.Add "Exchange_User2", "UserAlias2@ServerInputQueueLabel", MSMQMAIL_RECIPIENT_TO, DeliveryTime:= CDate("5/20/94 10:17:00 PM")
   email.DeliveryReportData.DeliveredRecipients.Add "Exchange_User3", "UserAlias3@ServerInputQueueLabel", MSMQMAIL_RECIPIENT_CC, DeliveryTime:= CDate("5/20/94 11:01:00 PM")

   'Compose message Body
   msg.Body = email.ComposeBody

   '*********************
   '* Display Delivered Recipients.
   '*********************

   Dim recipient As MSMQMailRecipient

   For Each recipient In email.DeliveryReportData.DeliveredRecipients
       MsgBox "Delivered To Recipient: " + recipient.Name + " at " + recipient.Address + " on " + recipient.DeliveryTime
   Next recipient

End Sub

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Library: Included as a resource in Mqmailoa.dll.

See Also

Add, Address, ComposeBody, ContentType, FormData, FormFields, MSMQMailEMail, Name, Sender, Subject, DeliveryReportData


MSMQMailDeliveryReportData.OriginalSubject

[The Message Queuing Mail Service is available only on Windows NT4 and Windows 2000.]

The OriginalSubject property of the MSMQMailDeliveryReportData object specifies the subject of the original e-mail.

Type: | String
Run time: | Read-write

emailObject.deliveryreportdataObject.OriginalSubject

Parameters

emailObject
E-mail (MSMQMailEMail) object that defines the e-mail report.
deliveryreportdataObject
Delivery report data (MSMQMailDeliveryReportData) object that represents the delivery report information.

Settings

String representation of the original e-mail message's subject.

Remarks

OriginalSubject should be set to the subject of the original e-mail.

Example

This example defines a delivery report, adding two delivered recipients to the delivered recipient list of the report. The e-mail object is composed into a mail message, and each delivered recipient is displayed.

To try this example using Microsoft® Visual Basic® (version 5.0), paste the code into the Code window of a form, enter a valid user address for each recipient, run the example, and click the form.

Dim email As New MSMQMailEMail
Dim msg As New MSMQMessage

Private Sub Form_Click()

   '*********************
   '*  Define e-mail
   '*********************

   'Set e-mail type to delivery report.
   email.ContentType = MSMQMAIL_EMAIL_DELIVERY_REPORT

   'Add the Recipient of the report (usually the original e-mail sender).
   email.Recipients.Add "Exchange_User", "UserAlias@ServerInputQueueLabel", MSMQMAIL_RECIPIENT_TO

   'Set subject of original mail.
   email.DeliveryReportData.OriginalSubject = "Original subject "

   'Set submission time of original mail.
   email.DeliveryReportData.OriginalSubmissionTime = CDate("5/20/94 10:16:07 PM")

  'Add two delivered recipients.
   email.DeliveryReportData.DeliveredRecipients.Add "Exchange_User2", "UserAlias2@ServerInputQueueLabel", MSMQMAIL_RECIPIENT_TO, DeliveryTime:= CDate("5/20/94 10:17:00 PM")
email.DeliveryReportData.DeliveredRecipients.Add "Exchange_User3", "UserAlias3@ServerInputQueueLabel", MSMQMAIL_RECIPIENT_CC, DeliveryTime:= CDate("5/20/94 11:01:00 PM")

   'Compose message Body
   msg.Body = email.ComposeBody

   '*********************
   '* Display Delivered Recipients.
   '*********************

   Dim recipient As MSMQMailRecipient

   For Each recipient In email.DeliveryReportData.DeliveredRecipients
       MsgBox "Delivered To Recipient: " + recipient.Name + " at " + recipient.Address + " on " + recipient.DeliveryTime
   Next recipient

End Sub

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Library: Included as a resource in Mqmailoa.dll.

See Also

Add, Address, Body, ComposeBody, ContentType, MSMQMailEMail, MSMQMessage, Name, Recipients, Sender, Text, TextMessageData


MSMQMailDeliveryReportData.OriginalSubmissionTime

[The Message Queuing Mail Service is available only on Windows NT4 and Windows 2000.]

The OriginalSubmissionTime property of the MSMQMailDeliveryReportData object specifies the submission time of the original e-mail.

Type: | Date
Run time: | Read-write

emailObject.deliveryreportdataObject.OriginalSubmissionTime

Parameters

emailObject
E-mail (MSMQMailEMail) object that defines the e-mail report.
deliveryreportdataObject
Delivery report data (MSMQMailDeliveryReportData) object that represents the delivery report information.

Settings

Date representation of the submission time of the original e-mail.

Remarks

OriginalSubmissionTime should be set to the MSMQMailEMail.SubmissionTime property of the original e-mail.

Example

This example defines a delivery report, adding two delivered recipients to the delivered recipient list of the report. The e-mail object is composed into a mail message, and each delivered recipient is displayed.

To try this example using Microsoft® Visual Basic® (version 5.0), paste the code into the Code window of a form, enter a valid user address for each recipient, run the example, and click the form.

Dim email As New MSMQMailEMail
Dim msg As New MSMQMessage

Private Sub Form_Click()

   '*********************
   '*  Define e-mail
   '*********************

   'Set e-mail type to delivery report.
   email.ContentType = MSMQMAIL_EMAIL_DELIVERY_REPORT

   'Add the Recipient of the report (usually the original e-mail sender).
   email.Recipients.Add "Exchange_User", "UserAlias@ServerInputQueueLabel", MSMQMAIL_RECIPIENT_TO

   'Set subject of original mail.
   email.DeliveryReportData.OriginalSubject = "Original subject "

   'Set submission time of original mail.
   email.DeliveryReportData.OriginalSubmissionTime = CDate("5/20/94 10:16:07 PM")

  'Add two delivered recipients.
   email.DeliveryReportData.DeliveredRecipients.Add "Exchange_User2", "UserAlias2@ServerInputQueueLabel", MSMQMAIL_RECIPIENT_TO, DeliveryTime:= CDate("5/20/94 10:17:00 PM")
email.DeliveryReportData.DeliveredRecipients.Add "Exchange_User3", "UserAlias3@ServerInputQueueLabel", MSMQMAIL_RECIPIENT_CC, DeliveryTime:= CDate("5/20/94 11:01:00 PM")

   'Compose message Body
   msg.Body = email.ComposeBody

   '*********************
   '* Display Delivered Recipients.
   '*********************

   Dim recipient As MSMQMailRecipient

   For Each recipient In email.DeliveryReportData.DeliveredRecipients
       MsgBox "Delivered To Recipient: " + recipient.Name + " at " + recipient.Address + " on " + recipient.DeliveryTime
   Next recipient

End Sub

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Library: Included as a resource in Mqmailoa.dll.

See Also

Add, Address, Body, ComposeBody, ContentType, MSMQMailEMail, MSMQMessage, Name, Recipients, Sender, Text, TextMessageData


MSMQMailEMail

[The Message Queuing Mail Service is available only on Windows NT4 and Windows 2000.]

The MSMQMailEMail object represents an e-mail message. The e-mail message can be a form with several fields, a text message with a single text body, a MAPI TNEF message, or a delivery or non-delivery report.

Methods

The following table lists the methods of the MSMQMailEMail object.

Method | Description
ComposeBody | Creates the body of an Message Queuing mail message based on an e-mail message.
ParseBody | Sets the properties of an e-mail message object based on the body of an Message Queuing mail message.

Properties

The following table lists the properties of the MSMQMailEMail object and gives their access, whether read-only or read/write; their data type; and a description.

Property | Description
ContentType Access: Read/write Data type: Long | Specifies the type of e-mail object (MSMQMailEMail).
DeliveryReportData Access: Read/write Data type: MSMQMailDeliveryReportData | Defines a delivery report.
DestinationQueueLabels Access: Read-only Data type: Collection of Strings | Provides the label of each destination queue needed to send the Message Queuing mail message.
FormData Access: Read/write Data type: MSMQMailFormData | Specifies the name of the form and lists all the fields in the form.
NonDeliveryReportData Access: Read/write Data type: MSMQMailNonDeliveryReportData | Defines a non-delivery report.
Recipients Access: Read/write Data type: MSMQMailRecipientList | Specifies the intended list of recipients for the e-mail message.
RequestDeliveryReport Access: Read/write Data type: Boolean | Specifies whether the receiving application should return a delivery report when the e-mail is received.
RequestNonDeliveryReport Access: Read/write Data type: Boolean | Specifies whether a non-delivery report is sent back to those recipients whom did not receive the e-mail.
Sender Access: Read/write Data type: MSMQMailRecipient | Specifies who is sending the e-mail message.
Subject Access: Read/write Data type: String | Specifies the subject of the e-mail.
SubmissionTime Access: Read/write Data type: Date | Specifies when the e-mail object was submitted.
TextMessageData Access: Read/write Data type: MSMQMailTextMessageData | Defines a text message.
TnefData Access: Read/write Data type: MSMQMailTnefData | Defines the TNEF data.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Library: Included as a resource in Mqmailoa.dll.


MSMQMailEMail.ComposeBody

[The Message Queuing Mail Service is available only on Windows NT4 and Windows 2000.]

The ComposeBody method of the MSMQMailEMail object creates the body of an Message Queuing mail message based on an e-mail message.

varBody=object.ComposeBody

Parameters

object
E-mail message (MSMQMailEMail) object that defines the e-mail message.
varBody
Variant type (array of bytes) body of an Message Queuing mail message.

Return Values

Byte-array message body.

Remarks

The returned byte-array can be used as the body of an Message Queuing mail message.

The following table defines the properties of the MSMQMailEMail object that are required to compose a message body for each type of e-mail. Required properties are marked with an X (default values can be used). When composing an e-mail object, all required properties must have valid values, otherwise an error condition is raised by ComposeBody.

MSMQMailEMail | Text Message | Form | TNEF | Delivery Report | Non- Delivery Report
ContentType | X | X | X | X | X
DeliveryReportData |  |  |  | X |
DestinationQueueLabels |  |  |  |  |
FormData |  | X |  |  |
NonDeliveryReportData |  |  |  |  | X
Recipients | X | X | X | X | X
RequestDeliveryReport | X (False) | X (False) |  |  |
RequestNonDeliveryReport | X (False) | X (False) |  |  |
Sender | X | X |  |  |
Subject | X (Empty string) | X (Empty string) |  |  |
SubmissionTime | X (Creation time of e-mail object) | X (Creation time of e-mail object) |  | X (Creation time of e-mail object) | X (Creation time of e-mail object)
TextMessageData | X |  |  |  |
TnefData |  |  | X |  |

Example

This example defines an e-mail message, composes the body of an Message Queuing message (formatted in Message Queuing mail format), and prints out the body of the message.

To try this example using Microsoft Visual Basic (version 5.0), paste the code into the Code window of a form, run the example, and click the form.

Dim email As New MSMQMailEMail
Dim msg As New MSMQMessage

Private Sub Form_Click()

   '*********************
   '*  Define the e-mail
   '*********************

   'Set e-mail type as text message
   email.ContentType = MSMQMAIL_EMAIL_TEXTMESSAGE

   'Set who receives the e-mail.
   email.Recipients.Add "RecipientName", "RecipientQueueLabel", MSMQMAIL_RECIPIENT_TO

   'Set who sent the e-mail.
   email.Sender.Name = "Our name"
   email.Sender.Address = "Our queue label"

   'Set the subject of the e-mail.
   email.Subject = "Test mail."

   'Set the Body of the e-mail.
   email.TextMessageData.Text = "This is the Body of the e-mail message."

   'Compose the MSMQ mail message Body.
   msg.Body = email.ComposeBody

   '*********************************
   '*  Display the MSMQ message Body.
   '*********************************

   'Display the mail message Body.
   Dim lTmp As Long
   For lTmp = LBound(msg.Body) To UBound(msg.Body)
       Debug.Print Chr$(msg.Body(lTmp));
   Next lTmp

End Sub

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Library: Included as a resource in Mqmailoa.dll.

See Also

Add, Address, Body, ContentType, MSMQMailEMail, MSMQMessage, Name, Recipients, Sender, Subject, Text, TextMessageData


MSMQMailEMail.ParseBody

[The Message Queuing Mail Service is available only on Windows NT4 and Windows 2000.]

The ParseBody method of the MSMQMailEMail object sets the properties of an e-mail message object based on the body of an Message Queuing mail message.

object.ParseBody varBody

Parameters

object
E-mail message (MSMQMailEMail) object that defines the e-mail message.
varBody
Variant type (array of bytes) body of an Message Queuing mail message.

Remarks

The body of the Message Queuing mail message is formatted in Message Queuing Mail format.

Example

This example defines an e-mail message object, composes the body of a mail message, and parses the message body into a second e-mail object and displays its subject.

To try this example using Microsoft Visual Basic (version 5.0), paste the code into the Code window of a form, run the example, and click the form.

Dim email1 As New MSMQMailEMail
Dim email2 As New MSMQMailEMail
Dim msg As New MSMQMessage

Private Sub Form_Click()

   '*********************
   '*  Define e-mail
   '*********************

   'Set e-mail type as form.
   email1.ContentType = MSMQMAIL_EMAIL_FORM

   'Set who receives the e-mail.
   email1.Recipients.Add "RecipientName", "RecipientQueueLabel", MSMQMAIL_RECIPIENT_TO

   'Set who sent the e-mail.
   email1.Sender.Name = "Our name"
   email1.Sender.Address = "Our queue label"

   'Set the subject of the e-mail.
   email1.Subject = "Test mail."

   '**********************
   ' Define the form.
   '**********************

   'Set the form name.
   email1.formdata.Name = "Test Form"

   'Set single field of form
   email1.formdata.FormFields.Add "Field1", "Field1 text."

   '******************************
   'Compose the mail message Body.
   '******************************
   msg.Body = email1.ComposeBody

   '*********************
   'Parse message Body as
   'new e-mail object.
   '*********************

   email2.ParseBody msg.Body

   '*****************************************
   'Display the subject of new e-mail object.
   '*****************************************

   MsgBox "The subject of the new mail is: " + email2.Subject

End Sub

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Library: Included as a resource in Mqmailoa.dll.

See Also

MSMQMailEMail.ComposeBody, MSMQMailEMail.ContentType, MSMQMailEMail.FormData, MSMQMailEMail.Recipients, MSMQMailEMail.Sender, MSMQMailEMail.Subject, MSMQMailEMail, MSMQMailFormData.FormFields, MSMQMailFormFieldList.Add, MSMQMailRecipient.Add, MSMQMailRecipient.Address, MSMQMailRecipient.Name, MSMQMessage.Body, MSMQMessage


MSMQMailEMail.ContentType

[The Message Queuing Mail Service is available only on Windows NT4 and Windows 2000.]

The ContentType property of the MSMQMailEMail object specifies the type of e-mail object (MSMQMailEMail).

Type: | Long
Run time: | Read-write

object.ContentType

Parameters

object
An e-mail (MSMQMailEMail) object that defines an e-mail message.

Settings

When specifying the type of e-mail message, ContentType can have any one of the following values:

MSMQMAIL_EMAIL_TEXTMESSAGE
The e-mail message consists of a text message (see TextMessageData).
MSMQMAIL_EMAIL_FORM
The e-mail message is a form (see FormData).
MSMQMAIL_EMAIL_TNEF
The e-mail message is a TNEF message (see TnefData).
MSMQMAIL_EMAIL_DELIVERY_REPORT
The e-mail message is a delivery report (see DeliveryReportData).
MSMQMAIL_EMAIL_NON_DELIVERY_REPORT
The e-mail message is a non-delivery report (see NonDeliveryReportData).

Remarks

This property must be set when defining an e-mail object.

Example

This example prints out the form-specific information of a e-mail form or the text-message information of an e-mail text message.

To try this example using Microsoft® Visual Basic® (version 5.0), paste the code into the Code window of a form, run the example, and click the form.

Dim email As New MSMQMailEMail
Dim msg As New MSMQMessage

Private Sub Form_Click()

   '*********************
   '*  Define form e-mail
   '*********************
   'Set e-mail type to form message.
   email.ContentType = MSMQMAIL_EMAIL_FORM

   'Add primary recipient.
   email.Recipients.Add "Exchange_User", "ExchangeUser@ServerInputQueueLabel", MSMQMAIL_RECIPIENT_TO

   'Set who sent the e-mail.
   email.Sender.Name = "Our name"
   email.Sender.Address = "Our queue label"

   'Set subject of mail.
   email.Subject = "Test form."

   'Set form name.
   email.FormData.Name = "Test Form"

   'Set form field list.
   email.FormData.FormFields.Add "Name", "Test Field"

  '************************
  '* Compose message bodies.
  '************************
  msg.Body = email.ComposeBody

  MsgBox "The e-mail form object was created."

End Sub

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Library: Included as a resource in Mqmailoa.dll.

See Also

Add, Address, ComposeBody, FormData, MSMQMailEMail, MSMQMessage, Name, Recipients, Subject


MSMQMailEMail.DeliveryReportData

[The Message Queuing Mail Service is available only on Windows NT4 and Windows 2000.]

The DeliveryReportData property of the MSMQMailEMail object defines a delivery report. This report contains a list of the recipients who received the original e-mail, when the original e-mail was submitted, and the subject of the original e-mail.

This property is only meaningful if ContentType is set to MSMQMAIL_EMAIL_DELIVERY_REPORT.

Type: | MSMQMailDeliveryReportData
Run time: | Read-write

object.DeliveryReportData

Parameters

object
E-mail message (MSMQMailEMail) object that defines the e-mail message.

Settings

MSMQMailDeliveryReportData object.

Remarks

When defining a delivery report, set ContentType to MSMQMAIL_EMAIL_DELIVERY_REPORT.

After parsing an Message Queuing mail message, verify that ContentType is set to MSMQMAIL_EMAIL_DELIVERY_REPORT, before looking at DeliveryReportData. This property is empty if ContentType indicates another e-mail type.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Library: Included as a resource in Mqmailoa.dll.


MSMQMailEMail.DestinationQueueLabels

[The Message Queuing Mail Service is available only on Windows NT4 and Windows 2000.]

The DestinationQueueLabels property of the MSMQMailEMail object provides the label of each destination queue needed to send the Message Queuing mail message. These labels are taken from the recipient addresses defined by the e-mail object.

Type: | Collection of Strings
Run time: | Read-only

object.DestinationQueueLabels

Parameters

object
An e-mail (MSMQMailEMail) object that defines an e-mail message.

Returned Value

String representation of each queue label needed to send message.

Remarks

Typically, a query is used to locate the destination queues of an e-mail. When running a query, make sure the queue type is added to the search criteria as well as the destination queue label. All application input queues, MAPI user input queues, and Exchange service input queues use the following Message Queuing-defined queue type: MSMQMAIL_SERVICE_MAIL.

When sending mail to several Microsoft Exchange users by means of the MSMQ Exchange Connector, only one label is stored in the destination queue collection. Only one label is needed because the Exchange Connector has only one input queue.

Example

This example sends mail to each destination queue.

To try this example using Microsoft Visual Basic (version 5.0), paste the code into the Code window of a form, enter a valid user address for each recipient, run the example, and click the form.

Dim email As New MSMQMailEMail
Dim msg As New MSMQMessage

Private Sub Form_Click()

   '*********************
   '*  Define e-mail
   '*********************

   'Set e-mail type to text message.
   email.ContentType = MSMQMAIL_EMAIL_TEXTMESSAGE

   'Add recipient.
   email.Recipients.Add "User1", "User1Address", MSMQMAIL_RECIPIENT_TO
   email.Recipients.Add "User2", "User2Address", MSMQMAIL_RECIPIENT_CC

   'Set who sent the e-mail.
   email.Sender.Name = "Our name"
   email.Sender.Address = "Our queue label"

   'Set subject of mail.
   email.Subject = "Test form."

   'Set message text
   email.TextMessageData.Text = "This is a test message."

   '******************
   '* Compose message
   '******************
   msg.Body = email.ComposeBody

   '******************
   '* Send Message
   '******************

   Dim qLabel As Variant

   For Each qLabel In email.DestinationQueueLabels
       Dim query As MSMQQuery
       Dim qinfos As MSMQQueueInfos
       Dim qinfo As MSMQQueueInfo

       Set query = New MSMQQuery
       Set qinfos = query.LookupQueue(Label:=qLabel, ServiceTypeGuid:=MSMQMAIL_SERVICE_MAIL)

       qinfos.Reset
       Set qinfo = qinfos.Next

       If Not (qinfo Is Nothing) Then
          Dim qdestination As MSMQQueue
          Set qdestination = qinfo.Open(MQ_SEND_ACCESS, MQ_DENY_NONE)
          msg.Send qdestination
       End If

   Next qLabel

End Sub

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Library: Included as a resource in Mqmailoa.dll.

See Also

Add, Address, Body, ComposeBody, ContentType, LookupQueue, MSMQMailEMail, MSMQMessage, MSMQQuery, MSMQQueue, MSMQQueueInfo, MSMQQueueInfos, Name, Open, Recipients, Send, Sender, Subject, Text, TextMessageData


MSMQMailEMail.FormData

[The Message Queuing Mail Service is available only on Windows NT4 and Windows 2000.]

The FormData property of the MSMQMailEMail object defines the form. It specifies the name of the form and lists all the fields in the form.

This property is only meaningful if ContentType is set to MSMQMAIL_EMAIL_FORM.

Type: | MSMQMailFormData
Run time: | Read-write

object.FormData

Parameters

object
E-mail message (MSMQMailEMail) object that defines the e-mail message.

Settings

MSMQMailFormData object.

Remarks

When defining an e-mail object that represent a form, set ContentType to MSMQMAIL_EMAIL_FORM.

After parsing an Message Queuing mail message, verify that ContentType is set to MSMQMAIL_EMAIL_FORM, before looking at FormData. This property is empty if ContentType indicates another e-mail type.

Example

This example defines an e-mail form with three fields, composes the body of an Message Queuing mail message, and displays a name of the form plus the number of fields in the form.

To try this example using Microsoft Visual Basic (version 5.0), paste the code into the Code window of a form, run the example, and click the form.

Option Explicit
Dim email As New MSMQMailEMail
Dim msg As New MSMQMessage

Private Sub Form_Click()

   '*********************
   '*  Define e-mail
   '*********************

   'Set e-mail type as form.
   email.ContentType = MSMQMAIL_EMAIL_FORM

   'Set who receives the e-mail.
   email.Recipients.Add "RecipientName", "RecipientQueueLabel", MSMQMAIL_RECIPIENT_TO

   'Set who sent the e-mail.
   email.Sender.Name = "Our name"
   email.Sender.Address = "Our queue label"

   'Set the subject of the e-mail.
   email.Subject = "Test mail."

   '**********************
   '* Define the form.
   '**********************

   'Set the form name.
   email.FormData.Name = "Test Form"

   'Set fields of form
   email.FormData.FormFields.Add "Field1", "Field1 text."
   email.FormData.FormFields.Add "Field2", True
   email.FormData.FormFields.Add "Field3", Date

   '******************************
   'Compose the mail message Body.
   '******************************
   msg.Body = email.ComposeBody

   MsgBox "Defined the form " + email.FormData.Name + " with " + CStr(email.FormData.FormFields.Count) + " fields."

End Sub

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Library: Included as a resource in Mqmailoa.dll.

See Also

Add, Address, ComposeBody, ContentType, FormFields, MSMQMailEMail, MSMQMessage, Name (MSMQMailFormData), Name (MSMQMailRecipient), Recipients, Sender, Subject


MSMQMailEMail.NonDeliveryReportData

[The Message Queuing Mail Service is available only on Windows NT4 and Windows 2000.]

The NonDeliveryReportData property of the MSMQMailEMail object defines a non-delivery report. The non-delivery report lists the recipients who did not receive the original e-mail.

This property is only meaningful if ContentType is set to MSMQMAIL_EMAIL_NON_DELIVERY_REPORT.

Type: | MSMQMailNonDeliveryReportData
Run time: | Read-write

object.NonDeliveryReportData

Parameters

object
E-mail message (MSMQMailEMail) object that defines the e-mail message.

Settings

MSMQMailNonDeliveryReportData object.

Remarks

When defining a non-delivery report, set ContentType to MSMQMAIL_EMAIL_NON_DELIVERY_REPORT.

After parsing an Message Queuing mail message, verify that ContentType is set to MSMQMAIL_EMAIL_NON_DELIVERY_REPORT, before looking at NonDeliveryReportData. This property is empty if ContentType indicates another e-mail type.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Library: Included as a resource in Mqmailoa.dll.


MSMQMailEMail.Recipients

[The Message Queuing Mail Service is available only on Windows NT4 and Windows 2000.]

The Recipients property of the MSMQMailEMail object specifies the intended list of recipients for the e-mail message.

Type: | MSMQMailRecipientList
Run time: | Read-write

object.Recipients

Parameters

object
An e-mail (MSMQMailEMail) object that defines an e-mail message.

Settings

MSMQMailRecipientList object.

Remarks

Each recipient in the e-mail's recipient list is represented by an MSMQMailRecipient object. Each recipient object includes a name and address for the recipient, an input queue of the recipient, and how the message is sent to the recipient.

Example

This example defines an e-mail form, adding three recipients to the e-mail's recipient list. The e-mail object is composed into a mail message, and each recipient is displayed.

To try this example using Microsoft® Visual Basic® (version 5.0), paste the code into the Code window of a form, enter a valid user address for each recipient, run the example, and click the form.

Dim email As New MSMQMailEMail
Dim msg As New MSMQMessage

Private Sub Form_Click()

   '*********************
   '*  Define e-mail
   '*********************

   'Set e-mail type to form message.
   email.ContentType = MSMQMAIL_EMAIL_FORM

   'Add Recipients.
   email.Recipients.Add "Exchange_User", "UserAlias@ServerInputQueueLabel", MSMQMAIL_RECIPIENT_TO
   email.Recipients.Add "MAPI_User", "MAPIUserInputQueueLabel", MSMQMAIL_RECIPIENT_CC
   email.Recipients.Add "MSMQApplication", "ApplicationInputQueueLabel", MSMQMAIL_RECIPIENT_BCC

   'Set who sent the e-mail.
   email.Sender.Name = "Our name"
   email.Sender.Address = "Our queue label"

   'Set subject of mail.
   email.Subject = "Test mail"

   'Set name of form
   email.FormData.Name = "Test form"

   'Set form field list.
   email.FormData.FormFields.Add "StringField", "Test Field"

   'Compose message Body
   msg.Body = email.ComposeBody

   '*********************
   '* Display Recipients.
   '*********************

   Dim recipient As MSMQMailRecipient

   For Each recipient In email.Recipients
       MsgBox "Recipient: " + recipient.Name + " at " + recipient.Address
   Next recipient

End Sub

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Library: Included as a resource in Mqmailoa.dll.

See Also

Add, Address, ComposeBody, ContentType, FormData, FormFields, MSMQMailEMail, Name, Sender, Subject


MSMQMailEMail.RequestDeliveryReport

[The Message Queuing Mail Service is available only on Windows NT4 and Windows 2000.]

The RequestDeliveryReport property of the MSMQMailEMail object specifies whether the receiving application should return a delivery report when the e-mail is received.

Type: | Boolean
Run time: | Read-write

object.RequestDeliveryReport

Parameters

object
E-mail (MSMQMailEMail) object that represents the e-mail message.

Settings

Boolean (default is False).

Remarks

If RequestDeliveryReport is set to True, the receiving application should send a delivery report e-mail for the delivered recipients.

The default setting of this property is False.

Example

This example defines a text-message e-mail, setting its RequestDeliveryReport to True. The e-mail object is then used to compose the body of a mail message, and a message box displays the e-mail's subject.

To try this example using Microsoft Visual Basic (version 5.0), paste the code into the Code window of a form, run the example, and click the form.

Dim email As New MSMQMailEMail
Dim msg As New MSMQMessage

Private Sub Form_Click()

   '***********************
   '*  Define e-mail object
   '***********************

   'Set e-mail type to text message
   email.ContentType = MSMQMAIL_EMAIL_TEXTMESSAGE

   'Add Recipients
   email.Recipients.Add "Connector Recipient Name", "ExchangeUser@ServerInputQueueLabel", MSMQMAIL_RECIPIENT_TO
   email.Recipients.Add "MAPI Recipient Name", "MAPIUserInputQueueLabel", MSMQMAIL_RECIPIENT_CC

   'Set who sent the e-mail.
   email.Sender.Name = "Our name"
   email.Sender.Address = "Our queue label"

   'Set the subject of the e-mail.
   email.Subject = "Test mail."

   'Request delivery report.
   email.RequestDeliveryReport = True

   'Set the Body of the e-mail.
   email.TextMessageData.Text = "This is the Body of the message."

   '**********************
   '* Compose message Body
   '**********************
   msg.Body = email.ComposeBody

   '******************
   '* Display delivery report flag.
   '******************
   MsgBox "Request a delivery report for the e-mail:" + email.RequestDeliveryReport

End Sub

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Library: Included as a resource in Mqmailoa.dll.

See Also

Add, Address, Body, ComposeBody, ContentType, MSMQMailEMail, MSMQMessage, Name, Recipients, Sender, Text, TextMessageData


MSMQMailEMail.RequestNonDeliveryReport

[The Message Queuing Mail Service is available only on Windows NT4 and Windows 2000.]

The RequestNonDeliveryReport of the MSMQMailEMail object property specifies whether a non-delivery report is sent back for the recipients that did not receive the e-mail.

Type: | Boolean
Run time: | Read-write

object.RequestNonDeliveryReport

Parameters

object
E-mail (MSMQMailEMail) object that represents the e-mail message.

Settings

Boolean (default is False).

Remarks

If RequestNonDeliveryReport is set to True, the sender receives a non-delivery report for the recipients that did not receive the e-mail.

Example

This example defines a text-message e-mail, setting its RequestNonDeliveryReport to True. The e-mail object is then used to compose the body of a mail message, and a message box displays the e-mail's non-delivery report request.

To try this example using Microsoft Visual Basic (version 5.0), paste the code into the Code window of a form, run the example, and click the form.

Dim email As New MSMQMailEMail
Dim msg As New MSMQMessage

Private Sub Form_Click()

   '***********************
   '*  Define e-mail object
   '***********************

   'Set e-mail type to text message
   email.ContentType = MSMQMAIL_EMAIL_TEXTMESSAGE

   'Add Recipients
   email.Recipients.Add "Connector Recipient Name", "ExchangeUser@ServerInputQueueLabel", MSMQMAIL_RECIPIENT_TO
   email.Recipients.Add "MAPI Recipient Name", "MAPIUserInputQueueLabel", MSMQMAIL_RECIPIENT_CC

   'Set who sent the e-mail.
   email.Sender.Name = "Our name"
   email.Sender.Address = "Our queue label"

   'Set the subject of the e-mail.
   email.Subject = "Test mail."

   'Request non-delivery report.
   email.RequestNonDeliveryReport = True

   'Set the Body of the e-mail.
   email.TextMessageData.Text = "This is the Body of the message."

   '**********************
   '* Compose message Body
   '**********************
   msg.Body = email.ComposeBody

   '******************
   '* Display delivery report flag.
   '******************
   MsgBox "Request a non-delivery report for the e-mail:" + email.RequestNonDeliveryReport

End Sub

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Library: Included as a resource in Mqmailoa.dll.

See Also

Add, Address, Body, ComposeBody, ContentType, MSMQMailEMail, MSMQMessage, Name, Recipients, Sender, Text, TextMessageData


MSMQMailEMail.Sender

[The Message Queuing Mail Service is available only on Windows NT4 and Windows 2000.]

The Sender property of the MSMQMailEMail object specifies who is sending the e-mail message. It includes the name and address of the sender.

Type: | MSMQMailRecipient
Run time: | Read-write

object.Sender

Parameters

object
An e-mail (MSMQMailEMail) object that defines an e-mail message.

Settings

MSMQMailRecipient object.

Remarks

When setting the Sender property, the RecipientType property of the MSMQMailRecipient object can be ignored. The RecipientType property has no meaning when specifying who sent the message.

Sender can be used to create a Reply or Reply-All e-mail. To do this, add the Sender to the recipient list of the Reply e-mail.

Example

This example defines an e-mail form, specifying who sent the message. The e-mail object is composed into a mail message, and the sender recipient is displayed.

To try this example using Microsoft Visual Basic (version 5.0), paste the code into the Code window of a form, enter a valid user address for each recipient, run the example, and click the form.

Dim email As New MSMQMailEMail
Dim msg As New MSMQMessage

Private Sub Form_Click()

   '*********************
   '*  Define e-mail
   '*********************

   'Set e-mail type to form message.
   email.ContentType = MSMQMAIL_EMAIL_FORM

   'Add Recipients.
   email.Recipients.Add "Exchange_User", "UserAlias@ServerInputQueueLabel", MSMQMAIL_RECIPIENT_TO

   'Set who sent the e-mail.
   email.Sender.Name = "Sender"
   email.Sender.Address = "Sender Application Input Queue"

   'Set subject of mail.
   email.Subject = "Test mail"

   'Set name of form
   email.FormData.Name = "Test form"

   'Set form field list.
   email.FormData.FormFields.Add "StringField", "Test Field"

   'Compose message Body
   msg.Body = email.ComposeBody

   '***************************
   '* Display recipient Sender.
   '***************************

   MsgBox "Recipient sender: " + email.Sender.Name + " at " + email.Sender.Address

End Sub

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Library: Included as a resource in Mqmailoa.dll.

See Also

Add, Address, ComposeBody, ContentType, FormData, FormFields, MSMQMailEMail, Name, Sender, Subject


MSMQMailEMail.Subject

[The Message Queuing Mail Service is available only on Windows NT4 and Windows 2000.]

The Subject property of the MSMQMailEMail object specifies the subject of the e-mail.

Type: | String
Run time: | Read-write

object.Subject

Parameters

object
E-mail (MSMQMailEMail) object that represents the e-mail message.

Settings

String representation of the subject of the e-mail.

Remarks

Subject can be set to any valid string. There are no restrictions on this property.

Example

This example defines a text-message e-mail, setting its subject to "Test mail". The e-mail object is then used to compose the body of a mail message, and a message box displays the e-mail's subject.

To try this example using Microsoft Visual Basic (version 5.0), paste the code into the Code window of a form, run the example, and click the form.

Dim email As New MSMQMailEMail
Dim msg As New MSMQMessage

Private Sub Form_Click()

   '***********************
   '*  Define e-mail object
   '***********************

   'Set e-mail type to text message
   email.ContentType = MSMQMAIL_EMAIL_TEXTMESSAGE

   'Add Recipients
   email.Recipients.Add "Connector Recipient Name", "ExchangeUser@ServerInputQueueLabel", MSMQMAIL_RECIPIENT_TO
   email.Recipients.Add "MAPI Recipient Name", "MAPIUserInputQueueLabel", MSMQMAIL_RECIPIENT_CC

   'Set who sent the e-mail.
   email.Sender.Name = "Our name"
   email.Sender.Address = "Our queue label"

   'Set the subject of the e-mail.
   email.Subject = "Test mail."

   'Set the Body of the e-mail.
   email.TextMessageData.Text = "This is the Body of the message."

   '**********************
   '* Compose message Body
   '**********************
   msg.Body = email.ComposeBody

   '******************
   '* Display subject.
   '******************
   MsgBox "Subject of e-mail is:" + email.Subject

End Sub

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Library: Included as a resource in Mqmailoa.dll.

See Also

Add, Address, Body, ComposeBody, ContentType, MSMQMailEMail, MSMQMessage, Name, Recipients, Sender, Text, TextMessageData


MSMQMailEMail.SubmissionTime

[The Message Queuing Mail Service is available only on Windows NT4 and Windows 2000.]

The SubmissionTime property of the MSMQMailEMail object specifies when the e-mail object was submitted.

Type: | Date
Run time: | Read-write

object.SubmissionTime

Parameters

object
E-mail (MSMQMailEMail) object that defines the e-mail message.

Settings

Date e-mail was submitted.

Remarks

Typically, mail is sent at the same time the e-mail object is submitted. However, some applications may need to store the e-mail objects (such as when communication is broken) and send the actual mail at another time.

The returned value for this property can be manipulated using standard Microsoft® Visual Basic® date and time functions such as Date$ and Time$. For descriptions of Visual Basic functions, see Visual Basic documentation.

When SubmissionTime is displayed, Visual Basic automatically converts the returned value to the local system time and system date.

Example

This example defines an e-mail message as a form, and displays the date and time when the e-mail object was submitted.

To try this example using Microsoft Visual Basic (version 5.0), paste the code into the Code window of a form, run the example, and click the form.

Dim email As New MSMQMailEMail

Private Sub Form_Click()

   '****************
   '* Define eimail
   '****************

   'Set e-mail type to text message
   email.ContentType = MSMQMAIL_EMAIL_TEXTMESSAGE

   'Add Recipients.
   email.Recipients.Add "Exchange_User", "ExchangeUser@ServerInputQueueLabel", MSMQMAIL_RECIPIENT_TO

   'Set who is sending the e-mail.
   email.Sender.Name = "Our name"
   email.Sender.Address = "Our queue label"

   'Set the subject of the e-mail.
   email.Subject = "Test mail."

   'Set the Body of the e-mail.
   email.TextMessageData.Text = "This is the Body of the message."

   '************************
   '* Display SubmissionTime time.
   '************************

   MsgBox "The e-mail object was submitted at: " + CStr(email.SubmissionTime)

End Sub

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Library: Included as a resource in Mqmailoa.dll.

See Also

Add, Address, ContentType, MSMQMailEMail, Name, Recipients, Sender, Subject, Text, TextMessageData


MSMQMailEMail.TextMessageData

[The Message Queuing Mail Service is available only on Windows NT4 and Windows 2000.]

The TextMessageData of the MSMQMailEMail object property defines a text message.

This property is only meaningful if ContentType is set to MSMQMAIL_EMAIL_TEXTMESSAGE.

Type: | MSMQMailTextMessageData
Run time: | Read-write

object.TextMessageData

Parameters

object
E-mail message (MSMQMailEMail) object that defines the text message.

Settings

MSMQMailTextMessageData object.

Remarks

When composing the body of an Message Queuing mail message that represents a text message, set ContentType to MSMQMAIL_EMAIL_TEXTMESSAGE.

When parsing the body of an Message Queuing message, verify that ContentType is set to MSMQMAIL_EMAIL_TEXTMESSAGE before looking at TextMessageData. This property is empty if ContentType indicates another e-mail type.

Example

This example defines an e-mail object as a text message, setting the text message body to "This is a text message". The e-mail object is then used to compose the body of a mail message, and a message box displays the text of the mail.

To try this example using Microsoft Visual Basic (version 5.0), paste the code into the Code window of a form, run the example, and click the form.

Dim email As New MSMQMailEMail
Dim msg As New MSMQMessage

Private Sub Form_Click()

   '***********************
   '*  Define e-mail object
   '***********************

   'Set e-mail type to text message
   email.ContentType = MSMQMAIL_EMAIL_TEXTMESSAGE

   'Add Recipients
   email.Recipients.Add "Connector Recipient Name", "ExchangeUser@ServerInputQueueLabel", MSMQMAIL_RECIPIENT_TO
   email.Recipients.Add "MAPI Recipient Name", "MAPIUserInputQueueLabel", MSMQMAIL_RECIPIENT_CC

   'Set who sent the e-mail.
   email.Sender.Name = "Our name"
   email.Sender.Address = "Our queue label"

   'Set the subject of the e-mail.
   email.Subject = "Test mail."

   'Set the Body of the e-mail.
   email.TextMessageData.Text = "This is the Body of the message."

   '**********************
   '* Compose message Body
   '**********************
   msg.Body = email.ComposeBody

   '******************
   '* Display subject.
   '******************
   MsgBox "The text of the message is:" + email.TextMessageData.Text

End Sub

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Library: Included as a resource in Mqmailoa.dll.

See Also

Add, Address, Body, ComposeBody, ContentType, MSMQMailEMail, MSMQMessage, Name, Recipients, Sender, Subject, Text


MSMQMailEMail.TnefData

[The Message Queuing Mail Service is available only on Windows NT4 and Windows 2000.]

The TnefData property of the MSMQMailEMail object defines the TNEF data.

This property is only meaningful if ContentType is set to MSMQMAIL_EMAIL_TNEF.

Type: | MSMQMailTnefData
Run time: | Read-write

object.TnefData

Parameters

object
E-mail message (MSMQMailEMail) object that defines the e-mail message.

Settings

MSMQMailTnefData object.

Remarks

When defining TNEF data, set ContentType to MSMQMAIL_EMAIL_TNEF whenever TnefData is set.

After parsing an Message Queuing mail message, verify that ContentType is set to MSMQMAIL_EMAIL_TNEF before looking at TnefData. This property is empty if ContentType indicates another e-mail type.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Library: Included as a resource in Mqmailoa.dll.


MSMQMailFormData

[The Message Queuing Mail Service is available only on Windows NT4 and Windows 2000.]

The MSMQMailFormData object represents an e-mail form.

Properties

The following table lists the properties of the MSMQMailFormData object and gives their access, whether read-only or read/write; their data type; and a description.

Property | Description
FormFields Access: Read/write Data type: MSMQMailFormFieldList | Specifies a list of the fields in the e-mail form.
Name Access: Read/write Data type: String | Identifies the name of the form.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Library: Included as a resource in Mqmailoa.dll.


MSMQMailFormData.FormFields

[The Message Queuing Mail Service is available only on Windows NT4 and Windows 2000.]

The FormFields property of the MSMQMailFormData object specifies a list of the fields in the e-mail form.

Type: | MSMQMailFormFieldList
Run time: | Read-write

emailObject.formdataObject.FormFields

Parameters

emailObject
E-mail message (MSMQMailEMail) object that defines the e-mail message.
formdataObject
The form data (MSMQMailFormData) object that defines the form.

Settings

MSMQMailFormFieldList object.

Remarks

The MSMQMailFormFieldList object specifies all the fields in the form.

Example

This example defines an e-mail form with three fields, composes the body of an Message Queuing mail message, and displays a name of the form plus the number of fields in the form.

To try this example using Microsoft Visual Basic (version 5.0), paste the code into the Code window of a form, run the example, and click the form.

Option Explicit
Dim email As New MSMQMailEMail
Dim msg As New MSMQMessage

Private Sub Form_Click()

   '*********************
   '*  Define e-mail
   '*********************

   'Set e-mail type as form.
   email.ContentType = MSMQMAIL_EMAIL_FORM

   'Set who receives the e-mail.
   email.Recipients.Add "RecipientName", "RecipientQueueLabel", MSMQMAIL_RECIPIENT_TO

   'Set who sent the e-mail.
   email.Sender.Name = "Our name"
   email.Sender.Address = "Our queue label"

   'Set the subject of the e-mail.
   email.Subject = "Test mail."

   '**********************
   '* Define the form.
   '**********************

   'Set the form name.
   email.FormData.Name = "Test Form"

   'Set fields of form
   email.FormData.FormFields.Add "Field1", "Field1 text."
   email.FormData.FormFields.Add "Field2", True
   email.FormData.FormFields.Add "Field3", Date

   '******************************
   'Compose the mail message Body.
   '******************************
   msg.Body = email.ComposeBody

   MsgBox "Defined the form " + email.FormData.Name + " with " + CStr(email.FormData.FormFields.Count) + " fields."

End Sub

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Library: Included as a resource in Mqmailoa.dll.

See Also

Add, Address, ComposeBody, ContentType, FormFields, MSMQMailEMail, MSMQMessage, Name (MSMQMailFormData), Name (MSMQMailRecipient), Recipients, Sender, Subject


MSMQMailFormData.Name

[The Message Queuing Mail Service is available only on Windows NT4 and Windows 2000.]

The Name property of the MSMQMailFormData object identifies the name of a form (MSMQMailFormData.

Type: | String
Run time: | Read-write

emailObject.formdataObject.Name

Parameters

emailObject
An e-mail (MSMQMailEMail) object that defines an e-mail message.
formdataObject
Form data (MSMQMailFormData) object that defines the form.

Settings

String that specifies the name of the form.

Remarks

When sending a form to a Microsoft Exchange user, this name should match the name of the field's Item Type as specified in the Exchange Form Designer. The Item Type can be found on the General page of the Field Properties dialog box of the Exchange Form Designer. If they do not match, Microsoft Exchange may not display the form correctly.

Example

This example defines an e-mail message as a form, setting the sender's name to "Our name", the recipient's name to "Exchange user", the form name to "Test form", and the field name to "StringField". Then a message body is composed and all names are displayed.

To try this example using Microsoft Visual Basic (version 5.0), paste the code into the Code window of a form, run the example, and click the form.

Dim email As New MSMQMailEMail
Dim msg As New MSMQMessage

Private Sub Form_Click()

   '*********************
   '*  Define e-mail
   '*********************

   'Set e-mail type to form message.
   email.ContentType = MSMQMAIL_EMAIL_FORM

   'Set who sent the e-mail.
   email.Sender.Name = "Our name"
   email.Sender.Address = "Our queue label"

   'Add Recipients.
   email.Recipients.Add "Exchange user", "UserAlias@ServerInputQueueLabel", MSMQMAIL_RECIPIENT_TO, "Test"

   'Set subject of mail.
   email.Subject = "Test mail"

   '***************
   '*  Define form
   '***************

   'Set name of form
   email.FormData.Name = "Test form"

   'Set form field list.
   email.FormData.FormFields.Add "StringField", "Test Field", "Test"

   'Compose message Body
   msg.Body = email.ComposeBody

   '*****************
   '* Display names.
   '*****************

   MsgBox "Form name: " + email.FormData.Name
   MsgBox "Field name is: " + email.FormData.FormFields.Item("test").Name
   MsgBox "Sender recipient is: " + email.Sender.Name
   MsgBox "To recipient is: " + email.Recipients.Item("test").Name

End Sub

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Library: Included as a resource in Mqmailoa.dll.

See Also

Add, Address, Body, ComposeBody, ContentType, FormData, FormFields, Item, MSMQMailEMail, MSMQMessage, Recipients, Sender, Subject


MSMQMailFormField

[The Message Queuing Mail Service is available only on Windows NT4 and Windows 2000.]

The MSMQMailFormField object represents a field of an e-mail form. Its properties specify the name and value of the field.

Every MSMQMailFormField object is an item of an MSMQMailFormFieldList object.

Properties

The following table lists the properties of the MSMQMailFormField object and gives their access, whether read-only or read/write; their data type; and a description.

Property | Description
Name Access: Read/write Data type: String | Identifies the name of a field on the form (MSMQMailFormField).
Value Access: Read/write Data type: Variant | Specifies the value of a field.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Library: Included as a resource in Mqmailoa.dll.


MSMQMailFormField.Name

[The Message Queuing Mail Service is available only on Windows NT4 and Windows 2000.]

The Name property of the MSMQMailFormField object identifies the name of a field on the form (MSMQMailFormField).

Type: | String
Run time: | Read-write

emailObject.formdataObject.formfieldObject.Item(IndexKey),Name

Parameters

emailObject
An e-mail (MSMQMailEMail) object that defines an e-mail message.
formdataObject
Form data (MSMQMailFormData) object that defines the form.
formfieldObject
Form field (MSMQMailFormField) object that defines the field.
IndexKey
Specifies the position in the field list or a specific field key.

Numeric indexes range from 1 to Count.

Keys are added when the field is added to the list.

Settings

String that specifies the form field.

Remarks

When used to specify the field of a form, this name should correspond to the name of the field's Reference Name as specified in the Exchange Form Designer. The Reference Name can be found on the General page of the Field Properties dialog of the Exchange Form Designer

If the correct Reference Name is not used, Microsoft Exchange may not display the field correctly.

Example

This example defines an e-mail message as a form, setting the sender's name to "Our name", the recipient's name to "Exchange user", the form name to "Test form", and the field name to "StringField". Then a message body is composed and all names are displayed.

To try this example using Microsoft Visual Basic (version 5.0), paste the code into the Code window of a form, run the example, and click the form.

Dim email As New MSMQMailEMail
Dim msg As New MSMQMessage

Private Sub Form_Click()

   '*********************
   '*  Define e-mail
   '*********************

   'Set e-mail type to form message.
   email.ContentType = MSMQMAIL_EMAIL_FORM

   'Set who sent the e-mail.
   email.Sender.Name = "Our name"
   email.Sender.Address = "Our queue label"

   'Add Recipients.
   email.Recipients.Add "Exchange user", "UserAlias@ServerInputQueueLabel", MSMQMAIL_RECIPIENT_TO, "Test"

   'Set subject of mail.
   email.Subject = "Test mail"

   '***************
   '*  Define form
   '***************

   'Set name of form
   email.FormData.Name = "Test form"

   'Set form field list.
   email.FormData.FormFields.Add "StringField", "Test Field", "Test"

   'Compose message Body
   msg.Body = email.ComposeBody

   '*****************
   '* Display names.
   '*****************

   MsgBox "Form name: " + email.FormData.Name
   MsgBox "Field name is: " + email.FormData.FormFields.Item("test").Name
   MsgBox "Sender recipient is: " + email.Sender.Name
   MsgBox "To recipient is: " + email.Recipients.Item("test").Name

End Sub

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Library: Included as a resource in Mqmailoa.dll.

See Also

Add, Address, Body, ComposeBody, ContentType, FormData, FormFields, Item, MSMQMailEMail, MSMQMessage, Recipients, Sender, Subject


MSMQMailFormField.Value

[The Message Queuing Mail Service is available only on Windows NT4 and Windows 2000.]

The Value property of the MSMQMailFormField object specifies the value of a field.

Type: | Variant
Run time: | Read-write

object.Value

Parameters

object
Field (MSMQMailFormField) object that represents the field of the form.

Settings

String, Integer, Boolean, Double, or Currency value of field.

Example

This example defines an e-mail form that has three fields (String, Boolean, and Date). Then it composes a message body and displays the values of each field.

To try this example using Microsoft Visual Basic (version 5.0), paste the code into the Code window of a form, run the example, and click the form.

Dim email As New MSMQMailEMail
Dim msg As New MSMQMessage

Private Sub Form_Click()

   '*********************
   '*  Define e-mail
   '*********************

   'Set e-mail type to form message.
   email.ContentType = MSMQMAIL_EMAIL_FORM

   'Add primary recipient.
   email.Recipients.Add "Exchange_User", "ExchangeUser@ServerInputQueueLabel", MSMQMAIL_RECIPIENT_TO

   'Set who sent the e-mail.
   email.Sender.Name = "Our name"
   email.Sender.Address = "Our queue label"

   'Set subject of mail.
   email.Subject = "Test form."

   '***************
   '* Define form
   '***************

   'Set form name
   emaile.FormData.Name = "Our name"

   'Set form field list.
   email.FormData.FormFields.Add "StringField", "Test String"
   email.FormData.FormFields.Add "BooleanField", True
   email.FormData.FormFields.Add "DateField", "Current Date"

   '***********************
   '* Compose mail message.
   '***********************

   msq.Body = email.ComposeBody

   '*********************
   '* Display Recipients.
   '*********************

   Dim formfield As MSMQMailFormField

   For Each formfield In email.FormData.FormFields
       MsgBox "Form: " + formfield.Name + " = " + CStr(formfield.Value)
   Next formfield

End Sub

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Library: Included as a resource in Mqmailoa.dll.

See Also

Add, Address, Body, ComposeBody, ContentType, FormData, FormFields, MSMQMailEMail, MSMQMessage, Name, Recipients, Sender, Subject


MSMQMailFormFieldList

[The Message Queuing Mail Service is available only on Windows NT4 and Windows 2000.]

The MSMQMailFormFieldList object represents a list of all the fields of a specific e-mail form. It references a collection of MSMQMailFormField objects.

Methods

The following table lists the methods of the MSMQMailFormFieldList object.

Method | Description
Add | Adds a recipient to the recipient list.
Remove | Removes a specific recipient from the recipient list.

Properties

The following table lists the properties of the MSMQMailFormFieldList object and gives their access, whether read-only or read/write; their data type; and a description.

Property | Description
Count Access: Read-only Data type: Long | Indicates the number of recipients in the form field list.
Item Access: Read-only Data type: MSMQMailFormField | Provides read access to the fields of a form field list (MSMQMailFormFieldList).

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Library: Included as a resource in Mqmailoa.dll.


MSMQMailFormFieldList.Add

[The Message Queuing Mail Service is available only on Windows NT4 and Windows 2000.]

The Add method of the MSMQMailFormFieldList object adds a field to a form field list (MSMQMailFormFieldList).

emailObject.formfielddataObject.formfieldlistObject.Add Name, Value[, Key]

Parameters

emailObject
E-mail message (MSMQMailEMail) object that defines the e-mail message.
formfielddataObject
Form field data (MSMQMailFormData) object that defines the form.
formfieldlistObject
Form field list (MSMQMailFormFieldList) object that represents the list of fields in the form.
Name
String representation of the name of the field. This name should correspond to the name of the field's Reference Name as specified in the Exchange Form Designer. The Reference Name can be found on the General page of the Field Properties dialog of the Exchange Form Designer.

If the correct Reference Name is not used, Microsoft Exchange may not display the field correctly.

Value
String, Integer, Boolean, Double, or Currency value of field.
Key
Optional. Key used when removing the field from the form field list (see IndexKey parameter of Remove).

Remarks

Fields can be one of the following types: String, Integer, Boolean, Double, or Currency value of field.

Example

This example defines an e-mail message with three fields (String, Boolean, and Date) and then displays the value given to each field.

To try this example using Microsoft Visual Basic (version 5.0), paste the code into the Code window of a form, run the example, and click the form.

Dim email As New MSMQMailEMail

Private Sub Form_Click()

   '*********************
   '*  Define e-mail
   '*********************

   'Set e-mail type to form message.
   email.ContentType = MSMQMAIL_EMAIL_FORM

   'Add primary recipient.
   email.Recipients.Add "Exchange_User", "ExchangeUser@ServerInputQueueLabel", MSMQMAIL_RECIPIENT_TO

   'Set who sent the e-mail.
   email.Sender.Name = "Our name"
   email.Sender.Address = "Our queue label"

   'Set the subject of the mail.
   email.Subject = "Test form."

   '**********************
   '* Define the form.
   '**********************

   'Set the form name.
   email.formdata.Name = "Test Form"

   'Set form field list.
    email.formdata.FormFields.Add "StringField", "Test Field"
    email.formdata.FormFields.Add "BooleanField", True
    email.formdata.FormFields.Add "DateField", "DateString"

   '*********************
   '* Display fields.
   '*********************

   Dim formfield As MSMQMailFormField

   For Each formfield In email.formdata.FormFields
    MsgBox "Form: " + formfield.Name + " = " +    CStr(formfield.Value)

   Next formfield

End Sub

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Library: Included as a resource in Mqmailoa.dll.

See Also

Add (MSMQMailRecipientList), Address, ContentType, FormData, FormFields, MSMQMailEMail, MSMQMailRecipient, Name (MSMQMailFormData), Name (MSMQMailFormField), Name (MSMQMailRecipient), Sender, Subject


MSMQMailFormFieldList.Remove

[The Message Queuing Mail Service is available only on Windows NT4 and Windows 2000.]

The Remove method of the MSMQMailFormFieldList object removes a field from the form field list (MSMQMailFormFieldList).

emailObject.formfielddataObject.formfieldlistObject.Remove IndexKey

Parameters

emailObject
E-mail message (MSMQMailEMail) object that defines the e-mail message.
formfielddataObject
Form field data (MSMQMailFormData) object that defines the form.
formfieldlistObject
Form field (MSMQMailFormFieldList) list object.
IndexKey
Index of the Item array, or the key specified when the field was added to the list (see Key parameter of Add).

Example

This example creates an e-mail form with three fields, setting the index key of the date field. It then displays the names and values of all fields, removes the date field using its index key, and displays the names of the fields remaining in the form.

To try this example using Microsoft Visual Basic (version 5.0), paste the code into the Code window of a form, run the example, and click the form.

Dim email As New MSMQMailEMail

Private Sub Form_Click()

   '*********************
   '*  Define e-mail
   '*********************

   'Set e-mail type to form message.
   email.ContentType = MSMQMAIL_EMAIL_FORM

   'Add primary recipient.
   email.Recipients.Add "Exchange_User", "ExchangeUser@ServerInputQueueLabel", MSMQMAIL_RECIPIENT_TO

   'Set who sent the e-mail.
   email.Sender.Name = "Our name"
   email.Sender.Address = "Our queue label"

   'Set subject of mail.
   email.Subject = "Test form."

  'Set form name.
  email.formdata.Name = "Test Form"

 'Set form field list.
   email.formdata.FormFields.Add "StringField", "Test Field"
   email.formdata.FormFields.Add "BooleanField", True
   email.formdata.FormFields.Add "DateField", "DateString", "SentDate"

   '**********************
   '* Remove Date field.
   '**********************

   Dim formfield As MSMQMailFormField

   Debug.Print "**Old Field List**"
   For Each formfield In email.formdata.FormFields
       Debug.Print formfield.Name + ": " + CStr(formfield.Value)
   Next formfield

   email.formdata.FormFields.Remove "SentDate"

   Debug.Print "**New Field List**"
   For Each formfield In email.formdata.FormFields
       Debug.Print formfield.Name + ": " + CStr(formfield.Value)
   Next formfield

End Sub

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Library: Included as a resource in Mqmailoa.dll.

See Also

Add (MSMQMailFormFieldList), Add (MSMQMailRecipientList), Address, ContentType, FormData, FormFields, MSMQMailEMail, MSMQMailFormField, Name (MSMQMailFormData), Name (MSMQMailFormField), Name (MSMQMailRecipient), Recipients, Sender, Subject, Value


MSMQMailFormFieldList.Count

[The Message Queuing Mail Service is available only on Windows NT4 and Windows 2000.]

The Count property of the MSMQMailFormFieldList object indicates the number of fields in the field list.

Type: | Long
Run time: | Read-only

emailObject.formfielddataObject.object3.Count

Parameters

emailObject
E-mail message (MSMQMailEMail) object that defines the e-mail message.
formfielddataObject
Form field data (MSMQMailFormData) object that defines the form.
formfieldlistObject
The field list (MSMQMailFormFieldList) object that defines the fields on a form.

Return Values

Number of items in list.

Remarks

Count is updated each time the Add or Remove method is called.

Example

This example defines an e-mail object as a form, adds three fields to the form, and displays the number of fields followed by each field name.

To try this example using Microsoft Visual Basic (version 5.0), paste the code into the Code window of a form, run the example, and click the form.

Dim email As New MSMQMailEMail

Private Sub Form_Click()

   '*********************
   '*  Define e-mail
   '*********************

   'Set e-mail type to form message.
   email.ContentType = MSMQMAIL_EMAIL_FORM

   'Add primary recipient.
   email.Recipients.Add "Exchange_User", "ExchangeUser@ServerInputQueueLabel", MSMQMAIL_RECIPIENT_TO

   'Set who sent the e-mail.
   email.Sender.Name = "Our name"
   email.Sender.Address = "Our queue label"

   'Set subject of the mail.
   email.Subject = "Test form."

  'Set form name.
  email.formdata.Name = "Test Form"

  'Set form field list.
   email.formdata.FormFields.Add "StringField", "Test Field"
   email.formdata.FormFields.Add "BooleanField", True
   email.formdata.FormFields.Add "DateField", "DateString", "SentDate"

   '*******************************
   '* Count fields.
   '*******************************

   Dim formfield As MSMQMailFormField

   Debug.Print "**Number of Fields in Form**"
   Debug.Print CStr(email.formdata.FormFields.Count)

   Debug.Print "**Fields**"
   For Each formfield In email.formdata.FormFields
       Debug.Print formfield.Name
   Next formfield

End Sub

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Library: Included as a resource in Mqmailoa.dll.

See Also

Add (MSMQMailRecipientList), Add (MSMQMailFormFieldList), Address, ContentType, FormData, FormFields, MSMQMailEMail, MSMQMailFormField, Name (MSMQMailFormData), Name (MSMQMailFormField), Name (MSMQMailRecipient), Recipients, Sender, Subject


MSMQMailFormFieldList.Item

[The Message Queuing Mail Service is available only on Windows NT4 and Windows 2000.]

The Item property of the MSMQMailFormFieldList object provides read access to the fields of a form field list (MSMQMailFormFieldList).

Type: | MSMQMailFormField object
Run time: | Read-only

set formfieldObject=emailObject.formdataObject.formfieldlistObject.Item (IndexKey)

Parameters

emailObject
E-mail message (MSMQMailEMail) object that defines the e-mail message.
formdataObject
Form data (MSMQMailFormData) object that defines the form.
formfieldlistObject
Form field list (MSMQMailFormFieldList) object that references the field.
formfieldObject
Form field (MSMQMailFormField) object that defines the field.
IndexKey
Specifies the position in the field list or a specific field's key.

Numeric indexes range from 1 to Count.

Keys are added when the recipient is added to the list.

Return Values

MSMQMailFormField object.

Remarks

Item is the default property for the MSMQMailFormFieldList object. Thus, FormFieldList[2] and FormFieldList.Item[2] both return the second field in the field list.

Example

This example defines a form with three fields and displays the name of the second field using the field key specified when the field was added.

To try this example using Microsoft Visual Basic (version 5.0), paste the code into the Code window of a form, run the example, and click the form.

Dim email As New MSMQMailEMail
Dim msg As New MSMQMessage
Dim field As New MSMQMailFormField

Private Sub Form_Click()

   '*********************
   '*  Define e-mail
   '*********************

   'Set e-mail type to form message.
   email.ContentType = MSMQMAIL_EMAIL_FORM

   'Add primary recipient.
   email.Recipients.Add "Exchange_User", "ExchangeUser@ServerInputQueueLabel", MSMQMAIL_RECIPIENT_TO

  'Set who sent the e-mail.
  email.Sender.Name = "Our name"
  email.Sender.Address = "Our queue label"

  'Set subject of mail.
  email.Subject = "Test form."

  'Set form name.
  email.FormData.Name = "Test Form"

  'Set form field list.
  email.FormData.FormFields.Add "Name", "Test Field"
  email.FormData.FormFields.Add "Employed", True, "Employed"
  email.FormData.FormFields.Add "CurrentDate", "DateString"

  '***********************
  '* Compose message Body.
  '***********************
  msg.Body = email.ComposeBody

  '*******************************************
  '* Display the value of the "Employed" field.
  '*******************************************

   Set field = email.FormData.FormFields.Item("Employed")
   MsgBox "The value of the Employment field is: " + CStr(field.Value)

End Sub

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Library: Included as a resource in Mqmailoa.dll.

See Also

Add (MSMQMailRecipientList), Add (MSMQMailFormFieldList), Address, ContentType, FormData, FormFields, Item, MSMQMailEMail, MSMQMailFormField, MSMQMessage, Name, Recipients, Sender, Subject


MSMQMailNonDeliveryReportData

[The Message Queuing Mail Service is available only on Windows NT4 and Windows 2000.]

The MSMQMailNonDeliveryReportData object represents a non-delivery report e-mail. A non-delivery report contains the recipients who did not receive the original e-mail and the original e-mail.

Properties

The following table lists the properties of the MSMQMailNonDeliveryReportData object and gives their access, whether read-only or read/write; their data type; and a description.

Property | Description
NonDeliveredRecipients Access: Read/write Data type: MSMQMailRecipientList | Specifies who did not receive the e-mail.
OriginalEMail Access: Read/write Data type: String | Specifies the original e-mail in a non-delivery report e-mail.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Library: Included as a resource in Mqmailoa.dll.


MSMQMailNonDeliveryReportData.NonDeliveredRecipients

[The Message Queuing Mail Service is available only on Windows NT4 and Windows 2000.]

The NonDeliveredRecipients property of the MSMQMailNonDeliveryReportData object specifies those who did not receive the e-mail.

Type: | MSMQMailRecipientList
Run time: | Read-write

emailObject.nondeliveryreportdataObject.NonDeliveredRecipients

Parameters

emailObject
E-mail (MSMQMailEMail) object that defines the non-delivered report.
nondeliveryreportdataObject
Non-delivery report data (MSMQMailNonDeliveryReportData) object that represents the non-delivery report information.

Settings

MSMQMailRecipientList object.

Remarks

Each recipient in the non-delivered recipient list is represented by an MSMQMailRecipient object. Each recipient object includes the name and address of the recipient, the input queue of the recipient, how the message was sent to recipient, and the reason why the original message was not delivered.

The NonDeliveryReason property of the MSMQMailRecipient object specifies why the original e-mail was not delivered to the recipient.

Example

This example defines a non-delivery report, adding two non-delivered recipients to the non-delivered recipient list of the report. The e-mail object is composed into a mail message and each non-delivered recipient is displayed.

To try this example using Microsoft® Visual Basic® (version 5.0), build an original e-mail object in emailOrig, paste the code into the Code window of a form, enter a valid user address for each recipient, run the example, and click the form.

Dim email As New MSMQMailEMail
Dim msg As New MSMQMessage

Private Sub Form_Click()

   '*********************
   '*  Define e-mail
   '*********************

   'Set e-mail type to non-delivery report.
   email.ContentType = MSMQMAIL_EMAIL_NON_DELIVERY_REPORT

   'Add the Recipient of the report (usually the original e-mail sender).
   email.Recipients.Add "Exchange_User", "UserAlias@ServerInputQueueLabel", MSMQMAIL_RECIPIENT_TO

   'Set original mail.
   Set email.NonDeliveryReportData.OriginalEMail = emailOrig

  'Add two non-delivered recipients.
   email.NonDeliveryReportData.NonDeliveredRecipients.Add "Exchange_User2", "UserAlias2@ServerInputQueueLabel", MSMQMAIL_RECIPIENT_TO, NonDeliveryReason:= "Recipient was not available at this address"
email.NonDeliveryReportData.NonDeliveredRecipients.Add "Exchange_User3", "UserAlias3@ServerInputQueueLabel", MSMQMAIL_RECIPIENT_CC, NonDeliveryReason:= "Communication failure"

   'Compose message Body
   msg.Body = email.ComposeBody

   '***********************************
   '* Display non-delivered recipients.
   '***********************************

   Dim recipient As MSMQMailRecipient

   For Each recipient In email.NonDeliveryReportData.NonDeliveredRecipients
       MsgBox "Not Delivered To Recipient: " + recipient.Name + " at " + recipient.Address + ", Reason is:" + recipient.NonDeliveryReason
   Next recipient

End Sub

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Library: Included as a resource in Mqmailoa.dll.

See Also

Add, Address, ComposeBody, ContentType, FormData, FormFields, MSMQMailEMail, Name, Subject


MSMQMailNonDeliveryReportData.OriginalEmail

[The Message Queuing Mail Service is available only on Windows NT4 and Windows 2000.]

The OriginalEmail property of the MSMQMailNonDeliveryReportData object specifies the original e-mail in a non-delivery report e-mail.

Type: | String
Run time: | Read-write

emailObject.nondeliveryreportdataObject.OriginalEMail

Parameters

emailObject
E-mail (MSMQMailEMail) object that defines the e-mail report.
nondeliveryreportdataObject
Non-delivery report data (MSMQMailNonDeliveryReportData) object that represents the non-delivery report information.

Settings

The original e-mail that was not delivered.

Example

This example defines a non-delivery report, adding two non-delivered recipients to the non-delivered recipient list of the report. The e-mail object is composed into a mail message, and each non-delivered recipient is displayed.

To try this example using Microsoft® Visual Basic® (version 5.0), build an original e-mail object, paste the code into the Code window of a form, enter a valid user address for each recipient, run the example, and click the form.

Dim email As New MSMQMailEMail
Dim msg As New MSMQMessage

Private Sub Form_Click()

   '*********************
   '*  Define e-mail
   '*********************

   'Set e-mail type to non-delivery report.
   email.ContentType = MSMQMAIL_EMAIL_NON_DELIVERY_REPORT

   'Add the Recipient of the report (usually the original e-mail sender).
   email.Recipients.Add "Exchange_User", "UserAlias@ServerInputQueueLabel", MSMQMAIL_RECIPIENT_TO

   'Set original mail.
   Set email.NonDeliveryReportData.OriginalEMail = emailOrig

  'Add two non-delivered recipients.
   email.NonDeliveryReportData.NonDeliveredRecipients.Add "Exchange_User2", "UserAlias2@ServerInputQueueLabel", MSMQMAIL_RECIPIENT_TO, NonDeliveryReason:= "Recipient was not available at this address"
email.NonDeliveryReportData.NonDeliveredRecipients.Add "Exchange_User3", "UserAlias3@ServerInputQueueLabel", MSMQMAIL_RECIPIENT_CC, NonDeliveryReason:= "Communication failure"

   'Compose message Body
   msg.Body = email.ComposeBody

   '********************************
   '* Display non-delivered recipients.
   '********************************

   Dim recipient As MSMQMailRecipient

   For Each recipient In email.NonDeliveryReportData.NonDeliveredRecipients
       MsgBox "Not Delivered To Recipient: " + recipient.Name + " at " + recipient.Address + ", Reason is:" + recipient.NonDeliveryReason
   Next recipient

End Sub

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Library: Included as a resource in Mqmailoa.dll.

See Also

Add, Address, Body, ComposeBody, ContentType, MSMQMailEMail, MSMQMessage, Name, NonDeliveryReportData, NonDeliveredRecipients, NonDeliveryReason, Recipients


MSMQMailRecipient

[The Message Queuing Mail Service is available only on Windows NT4 and Windows 2000.]

The MSMQMailRecipient object represents an e-mail recipient. A recipient is defined by their name, address, and type. Two optional properties (NonDeliveryReason and DeliveryTime) can also be used when making non-delivery and delivery reports respectivly.

A recipient can be included in a list of recipients (MSMQMailRecipientList object) to indicate who is receiving the mail, or it can be used to indicate who sent the mail (Sender).

Properties

The following table lists the properties of the MSMQMailRecipient object and gives their access, whether read-only or read/write; their data type; and a description.

Property | Description
Address Access: Read/write Data type: String | Specifies the e-mail address of the recipient.
DeliveryTime Access: Read/write Data type: Date | Optional. Specifies the time when the original e-mail was delivered to the recipient.
Name Access: Read/write Data type: String | Identifies the name of an e-mail recipient.
NonDeliveryReason Access: Read/write Data type: String | Optional. Specifies why the original e-mail was not delivered.
RecipientType Access: Read/write Data type: Long | Specifies how the e-mail is sent to the recipient.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Library: Included as a resource in Mqmailoa.dll.


MSMQMailRecipient.Address

[The Message Queuing Mail Service is available only on Windows NT4 and Windows 2000.]

The Address property of the MSMQMailRecipient object specifies the e-mail address of the recipient.

Type: | String
Run time: | Read-write

emailObject,recipientObject.Address

Parameters

emailObject
An e-mail (MSMQMailEMail) object that defines an e-mail message.
recipientObject
Recipient (MSMQMailRecipient) object the represents the e-mail recipient.

Settings

String representation of the e-mail recipient's address. Use one of the following formats:

"UserAlias@ServerInputQueueLabel"    Exchange Connector
"MAPIUserInputQueueLabel"            MAPI Transport Provider
"ApplicationInputQueueLabel"         Message Queuing Application

Remarks

Typically, Address is not referenced explicitly. In most cases, it is set when adding a recipient to the recipient list.

When the e-mail is being sent to an Message Queuing application, the recipient's address is the label (MSMQQueueInfo.Label) or the application input queue.

When the e-mail is being sent to an e-mail user, the recipient's address varies depending on which Message Queuing mail service is being used.

  • For applications using the MSMQ Exchange Connector, the address includes the e-mail alias of the Microsoft Exchange user plus the label of the MSMQ Exchange server input queue.
  • For applications using the MSMQ MAPI Transport Provider, the address includes the e-mail alias plus the label of the MAPI Transport Provider's User Input Queue.

Example

This example defines an e-mail form, adding three recipients to the e-mail's recipient list. The e-mail object is composed into a mail message and then each recipient is displayed.

To try this example using Microsoft Visual Basic (version 5.0), paste the code into the Code window of a form, enter a valid user address for each recipient, run the example, and click the form.

Dim email As New MSMQMailEMail
Dim msg As New MSMQMessage

Private Sub Form_Click()

   '*********************
   '*  Define e-mail
   '*********************

   'Set e-mail type to form message.
   email.ContentType = MSMQMAIL_EMAIL_FORM

   'Add Recipients.
   email.Recipients.Add "Exchange_User", "UserAlias@ServerInputQueueLabel", MSMQMAIL_RECIPIENT_TO
   email.Recipients.Add "MAPI_User", "MAPIUserInputQueueLabel", MSMQMAIL_RECIPIENT_CC
   email.Recipients.Add "MSMQApplication", "ApplicationInputQueueLabel", MSMQMAIL_RECIPIENT_BCC

   'Set who sent the e-mail.
   email.Sender.Name = "Our name"
   email.Sender.Address = "Our queue label"

   'Set subject of mail.
   email.Subject = "Test mail"

   'Set name of form
   email.FormData.Name = "Test form"

   'Set form field list.
   email.FormData.FormFields.Add "StringField", "Test Field"

   'Compose message Body
   msg.Body = email.ComposeBody

   '*********************
   '* Display Recipients.
   '*********************

   Dim recipient As MSMQMailRecipient

   For Each recipient In email.Recipients
       MsgBox "Recipient: " + recipient.Name + " at " + recipient.Address
   Next recipient

End Sub

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Library: Included as a resource in Mqmailoa.dll.

See Also

Add (MSMQMailFormFieldList), Add (MSMQMailRecipientList), ComposeBody, ContentType, FormData, FormFields, MSMQMailEMail, MSMQMessage, Name, Recipients, Sender, Subject


MSMQMailRecipient.DeliveryTime

[The Message Queuing Mail Service is available only on Windows NT4 and Windows 2000.]

The DeliveryTime property of the MSMQMailRecipient object specifies the time when the original e-mail was delivered to the recipient (MSMQMailRecipient).

Type: | Date
Run time: | Read-write

mailRecipientObject.DeliveryTime

Parameters

mailRecipientObject
A recipient (MSMQMailRecipient) object that defines an e-mail recipient.

Settings

The time when the original e-mail was delivered to the recipient.

Remarks

DeliveryTime has a valid value only when the recipient is a member of the DeliveredRecipients property of a delivery report e-mail.

Example

This example defines a delivery report, adding two delivered recipients to the delivered recipient list of the report. The e-mail object is composed into a mail message, and each delivered recipient is displayed.

To try this example using Microsoft® Visual Basic® (version 5.0), paste the code into the Code window of a form, enter a valid user address for each recipient, run the example, and click the form.

Dim email As New MSMQMailEMail
Dim msg As New MSMQMessage

Private Sub Form_Click()

   '*********************
   '*  Define e-mail
   '*********************

   'Set e-mail type to delivery report.
   email.ContentType = MSMQMAIL_EMAIL_DELIVERY_REPORT

   'Add the Recipient of the report (usually the original e-mail sender).
   email.Recipients.Add "Exchange_User", "UserAlias@ServerInputQueueLabel", MSMQMAIL_RECIPIENT_TO

   'Set subject of original mail.
   email.DeliveryReportData.OriginalSubject = "Original subject "

   'Set submission time of original mail.
   email.DeliveryReportData.OriginalSubmissionTime = CDate("5/20/94 10:16:07 PM")

  'Add two delivered recipients.
   email.DeliveryReportData.DeliveredRecipients.Add "Exchange_User2", "UserAlias2@ServerInputQueueLabel", MSMQMAIL_RECIPIENT_TO, DeliveryTime:= CDate("5/20/94 10:17:00 PM")
email.DeliveryReportData.DeliveredRecipients.Add "Exchange_User3", "UserAlias3@ServerInputQueueLabel", MSMQMAIL_RECIPIENT_CC, DeliveryTime:= CDate("5/20/94 11:01:00 PM")

   'Compose message Body
   msg.Body = email.ComposeBody

   '*********************
   '* Display Delivered Recipients.
   '*********************

   Dim recipient As MSMQMailRecipient

   For Each recipient In email.DeliveryReportData.DeliveredRecipients
       MsgBox "Delivered To Recipient: " + recipient.Name + " at " + recipient.Address + " on " + recipient.DeliveryTime
   Next recipient

End Sub

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Library: Included as a resource in Mqmailoa.dll.

See Also

Add, Address, Body, ComposeBody, ContentType, DeliveredRecipients, DeliveryReportData, DeliveryTime, MSMQMailEMail, MSMQMessage, Name, OriginalSubject, OriginalSubmissionTime, Recipients


MSMQMailRecipient.Name

[The Message Queuing Mail Service is available only on Windows NT4 and Windows 2000.]

The Name property of the MSMQMailRecipient object identifies the name of an e-mail recipient.

Type: | String
Run time: | Read-write

emailObject.recipientObject.Name

Parameters

emailObject
An e-mail (MSMQMailEMail) object that defines an e-mail message.
recipientObject
Recipient (MSMQMailRecipient) object that defines the e-mail user.
emailObject.recipientlist.Item(IndexKey).Name

Parameters

emailObject
An e-mail (MSMQMailEMail) object that defines an e-mail message.
recipientlistObject
Recipients (MSMQMailRecipientList) object that defines the list of e-mail users.
IndexKey
Specifies the position in the recipient list or a specific field key.

Numeric indexes range from 1 to Count.

Keys are added when the recipient is added to the list.

Settings

String that specifies the name of the form, form field, or e-mail recipient.

Remarks

When used to specify an e-mail user, Name is only used for display purposes. It should contain the full name of the user.

Name is explicitly referenced to name the sender recipient. However, it is not referenced explicitly when naming a recipient in the recipient list. In these cases, the name is set when adding the recipient to the recipient list.

Example

This example defines an e-mail message as a form, setting the sender's name to "Our name", the recipient's name to "Exchange user", the form name to "Test form", and the field name to "StringField". Then a message body is composed and all names are displayed.

To try this example using Microsoft Visual Basic (version 5.0), paste the code into the Code window of a form, run the example, and click the form.

Dim email As New MSMQMailEMail
Dim msg As New MSMQMessage

Private Sub Form_Click()

   '*********************
   '*  Define e-mail
   '*********************

   'Set e-mail type to form message.
   email.ContentType = MSMQMAIL_EMAIL_FORM

   'Set who sent the e-mail.
   email.Sender.Name = "Our name"
   email.Sender.Address = "Our queue label"

   'Add Recipients.
   email.Recipients.Add "Exchange user", "UserAlias@ServerInputQueueLabel", MSMQMAIL_RECIPIENT_TO, "Test"

   'Set subject of mail.
   email.Subject = "Test mail"

   '***************
   '*  Define form
   '***************

   'Set name of form
   email.FormData.Name = "Test form"

   'Set form field list.
   email.FormData.FormFields.Add "StringField", "Test Field", "Test"

   'Compose message Body
   msg.Body = email.ComposeBody

   '*****************
   '* Display names.
   '*****************

   MsgBox "Form name: " + email.FormData.Name
   MsgBox "Field name is: " + email.FormData.FormFields.Item("test").Name
   MsgBox "Sender recipient is: " + email.Sender.Name
   MsgBox "To recipient is: " + email.Recipients.Item("test").Name

End Sub

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Library: Included as a resource in Mqmailoa.dll.

See Also

Add (MSMQMailRecipient), Add (MSMQMailFormFieldList), Address, Body, ComposeBody, ContentType, FormData, FormFields, Item, MSMQMailEMail, MSMQMessage, Recipients, Sender, Subject


MSMQMailRecipient.NonDeliveryReason

[The Message Queuing Mail Service is available only on Windows NT4 and Windows 2000.]

The NonDeliveryReason property of the MSMQMailRecipient object specifies why the original e-mail was not delivered.

Type: | String
Run time: | Read-write

mailRecipientObject.NonDeliveryReason

Parameters

mailRecipientObject
A recipient (MSMQMailRecipient) object that defines an e-mail recipient.

Settings

Free text that describes the reason for not delivering the original e-mail to this recipient.

Remarks

NonDeliveryReason has a valid value only when the recipient is a member of the NonDeliveredRecipients property of a non-delivery report e-mail.

Example

This example defines a non-delivery report, adding two non-delivered recipients to the non-delivered recipient list of the report. The e-mail object is composed into a mail message, and each non-delivered recipient is displayed.

To try this example using Microsoft® Visual Basic® (version 5.0), build an original e-mail object in emailOrig, paste the code into the Code window of a form, enter a valid user address for each recipient, run the example, and click the form.

Dim email As New MSMQMailEMail
Dim msg As New MSMQMessage

Private Sub Form_Click()

   '*********************
   '*  Define e-mail
   '*********************

   'Set e-mail type to non-delivery report.
   email.ContentType = MSMQMAIL_EMAIL_NON_DELIVERY_REPORT

   'Add the Recipient of the report (usually the original e-mail sender).
   email.Recipients.Add "Exchange_User", "UserAlias@ServerInputQueueLabel", MSMQMAIL_RECIPIENT_TO

   'Set original mail.
   Set email.NonDeliveryReportData.OriginalEMail = emailOrig

  'Add two non-delivered recipients.
   email.NonDeliveryReportData.NonDeliveredRecipients.Add "Exchange_User2", "UserAlias2@ServerInputQueueLabel", MSMQMAIL_RECIPIENT_TO, NonDeliveryReason:= "Recipient was not available at this address"
email.NonDeliveryReportData.NonDeliveredRecipients.Add "Exchange_User3", "UserAlias3@ServerInputQueueLabel", MSMQMAIL_RECIPIENT_CC, NonDeliveryReason:= "Communication failure"

   'Compose message Body
   msg.Body = email.ComposeBody

   '*********************
   '* Display Delivered Recipients.
   '*********************

   Dim recipient As MSMQMailRecipient

   For Each recipient In email.NonDeliveryReportData.NonDeliveredRecipients
       MsgBox "Not Delivered To Recipient: " + recipient.Name + " at " + recipient.Address + ", Reason is:" + recipient.NonDeliveryReason
   Next recipient

End Sub

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Library: Included as a resource in Mqmailoa.dll.

See Also

Add, Body, ComposeBody, ContentType, FormData, FormFields, MSMQMailEMail, MSMQMAILFormField, Name, ParseBody, Recipients, Subject, Text, TextMessageData, Value


MSMQMailRecipient.RecipientType

[The Message Queuing Mail Service is available only on Windows NT4 and Windows 2000.]

The RecipientType property of the MSMQMailRecipient object specifies how the e-mail is sent (MSMQMailRecipient) to the recipient.

Type: | Long
Run time: | Read-write

object.RecipientType

Parameters

object
A recipient (MSMQMailRecipient) object that defines an e-mail recipient.

Settings

RecipientType can have any one of the following values:

MSMQMailRecipient_TO
Default. The recipient is the primary recipient of the e-mail.
MSMQMailRecipient_CC
The e-mail is copied to the recipient.
MSMQMailRecipient_BCC
The e-mail is blind copied to the recipient.

Remarks

This property is automatically set whenever a recipient is added to the recipient list of an e-mail object (see the Type parameter of Add). Consequently, explicitly setting this property is seldom required.

Type is ignored if the recipient (MSMQMailRecipient) object represents the sender of an e-mail.

Example

This example composes a message body from an e-mail object with three recipients, and parses the message body, and displays all the recipients who received a copy of the message.

To try this example using Microsoft Visual Basic (version 5.0), paste the code into the Code window of a form, run the example, and click the form.

Dim email As New MSMQMailEMail
Dim emailReceived As New MSMQMailEMail
Dim recipient As MSMQMailRecipient
Dim msg As New MSMQMessage

Private Sub Form_Click()

   '*********************
   '*  Define e-mail
   '*********************

   'Set e-mail type to form message.
   email.ContentType = MSMQMAIL_EMAIL_FORM

   'Add primary recipient.
   email.Recipients.Add "Exchange_User1", "ExchangeUser@ServerInputQueueLabel", MSMQMAIL_RECIPIENT_TO
   email.Recipients.Add "Exchange_User2", "ExchangeUser@ServerInputQueueLabel", MSMQMAIL_RECIPIENT_CC
   email.Recipients.Add "Exchange_User3", "ExchangeUser@ServerInputQueueLabel", MSMQMAIL_RECIPIENT_CC

   'Set who sent the e-mail.
   email.Sender.Name = "Our name"
   email.Sender.Address = "Our queue label"

   'Set subject of mail.
   email.Subject = "Test form."

   'Set form name.
   email.FormData.Name = "Test form."

   'Set form field list.
   email.FormData.FormFields.Add "StringField", "Test Field"

   '***************************
   '* Compose and Parse message
   '***************************
   msg.Body = email.ComposeBody
   emailReceived.ParseBody (msg.Body)

   For Each recipient In email.Recipients
       If recipient.RecipientType = MSMQMAIL_RECIPIENT_CC Then
          MsgBox "Mail was copied to: " + recipient.Name
       End If
   Next recipient

End Sub

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Library: Included as a resource in Mqmailoa.dll.

See Also

Add, Body, ComposeBody, ContentType, FormData, FormFields, MSMQMailEMail, MSMQMAILFormField, Name, ParseBody, Recipients, Subject, Text, TextMessageData, Value


MSMQMailRecipientList

[The Message Queuing Mail Service is available only on Windows NT4 and Windows 2000.]

The MSMQMailRecipientList object represents a list of e-mail recipients. It contains references to one or more MSMQMailRecipient objects.

Methods

The following table lists the methods of the MSMQMailRecipientList object.

Method | Description
MSMQMailRecipientList.Add | Adds a recipient to the recipient list.
MSMQMailRecipientList.Remove | Removes a specific recipient from the recipient list

Properties

The following table lists the properties of the MSMQMailRecipientList object and gives their access, whether read-only or read/write; their data type; and a description.

Property | Description
Count Access: Read-only Data type: Long | Indicates the number of recipients in the recipient list or the number of fields in the field list.
Item Access: Read-only Data type: MSMQMailRecipient | Provides read access to the recipients of an e-mail's recipient list (MSMQMailRecipientList) or the fields of a form's field list (MSMQMailFormFieldList).

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Library: Included as a resource in Mqmailoa.dll.


MSMQMailRecipientList.Add

[The Message Queuing Mail Service is available only on Windows NT4 and Windows 2000.]

The Add method of the MSMQMailRecipientList object adds a recipient to the recipient list (MSMQMailRecipientList).

emailObject.recipientlistObject.Add Name, Address, Type[, DeliveryTime][, NonDeliveryReason][, Key]

Parameters

emailObject
E-mail message (MSMQMailEMail) object that defines the e-mail message.
recipientlistObject
Recipient list (MSMQMailRecipientList) object that represents the list of recipients.
Name
String representation of recipient.
Address
String representation of the e-mail recipient's address. Use one of the following formats (see Remarks for examples).

When the e-mail is being sent to another Message Queuing application, the recipient's address is the label (MSMQQueueInfo.Label) of the application input queue.

Address:="MSMQQueueLabel"

When the e-mail is being sent to a Microsoft Exchange user via the MSMQ Exchange Connector, the address includes the e-mail alias of the Exchange user plus the label of the Exchange Connector's server input queue.

Address:="UserName@ServerInputQueueLabel"

When e-mail is being sent to the MAPI Transport Provider, the address is the label of the MAPI user input queue.

Address:="UserInputQueueLabel"

Type
The Type parameter can have any one of the following values:

MSMQMAIL_RECIPIENT_TO: Default. The recipient is the primary recipient of the e-mail.

MSMQMAIL_RECIPIENT_CC: The e-mail is copied to the recipient.

MSMQMAIL_RECIPIENT_BCC: The e-mail is blind copied to the recipient.

DeliveryTime
Optional. DeliveryTime is only used when adding a recipient to the DeliveredRecipients property of the MSMQMailDeliveryReportData object. This property specifies when the original e-mail was delivered to the recipient.
NonDeliveryReason
Optional. NonDeliveryReason is only used when adding a recipient to the NonDeliveredRecipients property of the MSMQMailNonDeliveryReportData object. This property specifies the reason why the original e-mail was not delivered to the recipient.
Key
Optional. Key (Variant type) used when removing the recipient from the recipient list (see IndexKey parameter of Remove).

Example

This example defines an e-mail message with two recipients and then displays the name and address of each recipient. The addresses of the recipients indicate that the mail will be sent to the Exchange Connector (first recipient) and the MAPI Transport Provider (second recipient).

Note For examples of setting the NonDeliveryReason and DeliveryTime parameters, see the examples in NonDeliveryReason and DeliveryTime properties respectively.

To try this example using Microsoft® Visual Basic® (version 5.0), paste the code into the Code window of a form, run the example, and click the form.

Private Sub Form_Click()

Dim email As New MSMQMailEMail

'Set e-mail type to text message
 email.ContentType= MSMQMAIL_EMAIL_TEXTMESSAGE

'**********************************
'* Add Exchange Connector recipient
'* as primary recipient.
'**********************************
email.Recipients.Add "Exchange_User", "ExchangeUser@ServerInputQueueLabel", MSMQMAIL_RECIPIENT_TO

'*********************
'* Add MAPI recipient
'* as CC recipient.
'*********************
email.Recipients.Add "MAPI_User", "MAPIUserInputQueueLabel", MSMQMAIL_RECIPIENT_CC

'Set who sent the e-mail.
email.Sender.Name = "Our name"
email.Sender.Address = "Our queue label"

'Set the subject of the e-mail.
email.Subject = "Test mail."

'Set the Body of the e-mail.
email.TextMessageData.Text = "This is the Body of the message."

'*********************
'* Display Recipients.
'*********************

Dim recipient As MSMQMailRecipient

For Each recipient In email.Recipients
    MsgBox "Mail was sent to " + recipient.Name + " at " + recipient.Address
Next recipient

End Sub

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Library: Included as a resource in Mqmailoa.dll.

See Also

Address, ContentType, MSMQMailEMail, MSMQMailRecipient, Name, Recipients, Sender, Subject, Text, TextMessageData


MSMQMailRecipientList.Remove

[The Message Queuing Mail Service is available only on Windows NT4 and Windows 2000.]

The Remove method of the MSMQMailRecipientList object removes a specific recipient from the recipient list (MSMQMailRecipientList).

emailObject.recipientlistObject.Remove IndexKey

Parameters

emailObject
E-mail message (MSMQMailEMail) object that defines the e-mail message.
recipientlistObject
Recipient (MSMQMailRecipientList) list object.
IndexKey
Index of the MSMQMailRecipientList.Item array, or the key specified when the recipient was added to the list (see Key parameter of MSMQMailRecipientList.Add).

Example

This example creates an e-mail object with a primary, copy, and blind copy recipient, setting the index key on the blind-copy recipient. It then displays the names of the recipients, removes the blind-copy recipient using its index key, and displays the names of the recipients remaining in the form.

To try this example using Microsoft Visual Basic (version 5.0), paste the code into the Code window of a form, run the example, and click the form.

Dim email As New MSMQMailEMail

Private Sub Form_Click()

   'Set e-mail type to text message
   email.ContentType = MSMQMAIL_EMAIL_TEXTMESSAGE

   '**********************************
   '* Add primary recipient.
   '**********************************
   email.Recipients.Add "Exchange_User", "ExchangeUser@ServerInputQueueLabel", MSMQMAIL_RECIPIENT_TO

   '*********************
   '* Add CC recipient.
   '*********************
   email.Recipients.Add "MAPI_User1", "MAPIUserInputQueueLabel", MSMQMAIL_RECIPIENT_CC

   '*********************
   '* Add BC recipient.
   '*********************
   email.Recipients.Add "MAPI_User2", "MAPIUserInputQueueLabel", MSMQMAIL_RECIPIENT_BCC, "BC"

   'Set who sent the e-mail.
   email.Sender.Name = "Our name"
   email.Sender.Address = "Our queue label"

   'Set the subject of the e-mail.
   email.Subject = "Test mail."

   'Set the Body of the e-mail.
   email.TextMessageData.Text = "This is the Body of the message."

   '*******************************
   '* Remove blind-copy Recipients.
   '*******************************

   Dim recipient As MSMQMailRecipient

   Debug.Print "**Old Recipient List**"
   For Each recipient In email.Recipients
       Debug.Print recipient.Name
   Next recipient

   email.Recipients.Remove "BC"

   Debug.Print "**New Recipient List**"
   For Each recipient In email.Recipients
          Debug.Print recipient.Name
   Next recipient

End Sub

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Library: Included as a resource in Mqmailoa.dll.

See Also

Add, Address, ContentType, MSMQMailEMail, MSMQMailRecipient, Name, Recipients, Remove, Sender, Subject, Text, TextMessageData


MSMQMailRecipientList.Count

[The Message Queuing Mail Service is available only on Windows NT4 and Windows 2000.]

The Count property of the MSMQMailRecipientList object indicates the number of recipients in the recipient list.

Type: | Long
Run time: | Read-only

emailObject.recipientlistObject.Count

Parameters

emailObject
E-mail message (MSMQMailEMail) object that defines the e-mail message.
recipientlistObject
The recipient list (MSMQMailRecipientList) object that defines the list of recipients.

Return Values

Number of items in list.

Remarks

Count is updated each time the MSMQMailRecipientList.Add or MSMQMailRecipientList.Remove method of the list object (MSMQMailRecipientList) is called.

Example

This example defines an e-mail object, adds three recipients to the recipient list, and displays the number of recipients followed by the name of each recipient.

To try this example using Microsoft® Visual Basic® (version 5.0), paste the code into the Code window of a form, run the example, and click the form.

Dim email As New MSMQMailEMail

Private Sub Form_Click()

   'Set e-mail type to text message
   email.ContentType = MSMQMAIL_EMAIL_TEXTMESSAGE

   '**********************************
   '* Add Recipients.
   '**********************************
   email.Recipients.Add "Exchange_User", "ExchangeUser@ServerInputQueueLabel", MSMQMAIL_RECIPIENT_TO
   email.Recipients.Add "MAPI_User1", "MAPIUserInputQueueLabel", MSMQMAIL_RECIPIENT_CC
   email.Recipients.Add "MAPI_User2", "MAPIUserInputQueueLabel", MSMQMAIL_RECIPIENT_BCC, "BC"

   'Set who sent the e-mail.
   email.Sender.Name = "Our name"
   email.Sender.Address = "Our queue label"

   'Set the subject of the e-mail.
   email.Subject = "Test mail."

   'Set the Body of the e-mail.
   email.TextMessageData.Text = "This is the Body of the message."

   '*******************************
   '* Count recipient.
   '*******************************

   Dim recipient As MSMQMailRecipient

   Debug.Print "**Number of Recipient in List**"
   Debug.Print CStr(email.Recipients.Count)

   Debug.Print "**Recipients**"
   For Each recipient In email.Recipients
       Debug.Print recipient.Name
   Next recipient

End Sub

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Library: Included as a resource in Mqmailoa.dll.

See Also

Add, Address, MSMQMailEMail, MSMQMailRecipient, Name, Recipients, Sender, Subject, Text, TextMessageData


MSMQMailRecipientList.Item

[The Message Queuing Mail Service is available only on Windows NT4 and Windows 2000.]

The Item property of the MSMQMailRecipientList object provides read access to an e-mail's recipient list (MSMQMailRecipientList).

Type: | MSMQMailRecipient object
Run time: | Read-only

set recipientObject=emailObject.recipientlistObject.Item (IndexKey)

Parameters

emailObject
E-mail message (MSMQMailEMail) object that defines the e-mail message.
recipientlistObject
Recipient list (MSMQMailRecipientList) object.
recipientObject
Recipient (MSMQMailRecipient) object.
IndexKey
Specifies the position in the recipient list or a specific recipient's key.

Numeric indexes range from 1 to Count.

Keys are added when the recipient is added to the list.

Return Values

MSMQMailRecipient object.

Remarks

Item is the default property for the MSMQMailRecipientList object. Thus, RecipientList[2] and RecipientList.Item[2] both return the second recipient in the recipient list.

Example

This example adds three recipients and displays the address of the MAPI recipient using a recipient key.

To try this example using Microsoft Visual Basic (version 5.0), paste the code into the Code window of a form, run the example, and click the form.

Dim email As New MSMQMailEMail
Dim recipient As New MSMQMailRecipient

Private Sub Form_Click()

   '****************
   '* Define eimail
   '****************

   'Set e-mail type to text message
   email.ContentType = MSMQMAIL_EMAIL_TEXTMESSAGE

   'Add Recipients.
   email.Recipients.Add "Exchange_User", "ExchangeUser@ServerInputQueueLabel", MSMQMAIL_RECIPIENT_TO
   email.Recipients.Add "MAPI_User", "MAPIUserInputQueueLabel", MSMQMAIL_RECIPIENT_CC, "MAPI"
   email.Recipients.Add "Exchange_User", "ExchangeUser@ServerInputQueueLabel", MSMQMAIL_RECIPIENT_BCC

   'Set who is sending the e-mail.
   email.Sender.Name = "Our name"
   email.Sender.Address = "Our queue label"

   'Set the subject of the e-mail.
   email.Subject = "Test mail."

   'Set the Body of the e-mail.
   email.TextMessageData.Text = "This is the Body of the message."

   '*********************************
   '* Display Name of MAPI recipient.
   '*********************************

   Set recipient = email.Recipients.Item("MAPI")
   MsgBox "The MAPI recipient's address is: " + recipient.Address

End Sub

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Library: Included as a resource in Mqmailoa.dll.

See Also

Add, Address, MSMQMailEMail, MSMQMailRecipient, Name, Recipients, Sender, Subject, Text, TextMessageData


MSMQMailTextMessageData

[The Message Queuing Mail Service is available only on Windows NT4 and Windows 2000.]

The MSMQMailTextMessageData object represents an e-mail text message.

Properties

The following table lists the properties of the MSMQMailTextMessageData object and gives their access, whether read-only or read/write; their data type; and a description.

Property | Description
Text Access: Read/write Data type: String | Specifies the text of a text-message e-mail.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Library: Included as a resource in Mqmailoa.dll.


MSMQMailTextMessageData.Text

[The Message Queuing Mail Service is available only on Windows NT4 and Windows 2000.]

The Text property of the MSMQMailTextMessageData object specifies the text of a text-message e-mail.

Type: | String
Run time: | Read-write

emailObject.textmessagedataObject.Text

Parameters

emailObject
E-mail (MSMQMailEMail) object that defines the e-mail message.
textmessagedataObject
Text message data (MSMQMailTextMessageData) object that represents the text message.

Settings

String representation of message body.

Example

This example defines an e-mail object as a text message, setting the text message body to "This is a text message". The e-mail object is then used to compose the body of a mail message, and a message box displays the text of the mail.

To try this example using Microsoft Visual Basic (version 5.0), paste the code into the Code window of a form, run the example, and click the form.

Dim email As New MSMQMailEMail
Dim msg As New MSMQMessage

Private Sub Form_Click()

   '***********************
   '*  Define e-mail object
   '***********************

   'Set e-mail type to text message
   email.ContentType = MSMQMAIL_EMAIL_TEXTMESSAGE

   'Add Recipients
   email.Recipients.Add "Connector Recipient Name", "ExchangeUser@ServerInputQueueLabel", MSMQMAIL_RECIPIENT_TO
   email.Recipients.Add "MAPI Recipient Name", "MAPIUserInputQueueLabel", MSMQMAIL_RECIPIENT_CC

   'Set who sent the e-mail.
   email.Sender.Name = "Our name"
   email.Sender.Address = "Our queue label"

   'Set the subject of the e-mail.
   email.Subject = "Test mail."

   'Set the Body of the e-mail.
   email.TextMessageData.Text = "This is the Body of the message."

   '**********************
   '* Compose message Body
   '**********************
   msg.Body = email.ComposeBody

   '******************
   '* Display subject.
   '******************
   MsgBox "The text of the message is:" + email.TextMessageData.Text

End Sub

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Library: Included as a resource in Mqmailoa.dll.

See Also

Add, Address, Body, ComposeBody, ContentType, MSMQMailEMail, MSMQMessage, Name, Recipients, Sender, Subject, TextMessageData


MSMQMailTnefData

[The Message Queuing Mail Service is available only on Windows NT4 and Windows 2000.]

The MSMQMailTnefData object represents an e-mail in TNEF format.

TNEF is a MAPI internal format that encapsulates the MAPI properties and is used by the Message Queuing mail services (the MSMQ Exchange Connector and the MSMQ MAPI Transport) to send mail to recipients who are defined as rich-text recipients.

Properties

The following table lists the properties of the MSMQMailTnefData object and gives their access, whether read-only or read/write; their data type; and a description.

Property | Description
Data Access: Read/write Data type: Variant | Specifies the data of a TNEF e-mail.

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Library: Included as a resource in Mqmailoa.dll.


MSMQMailTnefData.Data

[The Message Queuing Mail Service is available only on Windows NT4 and Windows 2000.]

The Data property of the MSMQMailTnefData object specifies the data of a TNEF e-mail.

Type: | Variant (variant type is an array of bytes)
Run time: | Read-write

emailObject.tnefdataObject.Data

Parameters

emailObject
E-mail (MSMQMailEMail) object that defines the e-mail message.
tnefdataObject
TNEF data (MSMQMailTnefData) object that represents the text message.

Settings

A variant that contains the TNEF data of the e-mail. The data in the variant should be an array of bytes representing the TNEF data.

TNEF is a MAPI internal format that encapsulates the MAPI properties and is used by the Message Queuing mail services (the MSMQ Exchange Connector and the MSMQ MAPI Transport) to send mail to recipients who are defined as rich-text recipients. These recipients have selected the check box labeled "Send to this recipient in Microsoft Exchange rich text format" in their Exchange/MAPI address.

Example

This example defines an e-mail object as a TNEF message, setting the TNEF message body to a predefined variant value that should be filled by MAPI or taken from another TNEF message. The e-mail object is then used to compose the body of a mail message, and a message box displays the size of the TNEF data (the data itself is binary and is not supposed to be readable).

To try this example using Microsoft Visual Basic (version 5.0), paste the code into the Code window of a form, run the example, and click the form.

Dim email As New MSMQMailEMail
Dim msg As New MSMQMessage

Private Sub Form_Click()

   '***********************
   '*  Define e-mail object
   '***********************

   'Set e-mail type to TNEF message
   email.ContentType = MSMQMAIL_EMAIL_TNEF

   'Add Recipients
   email.Recipients.Add "Connector Recipient Name", "ExchangeUser@ServerInputQueueLabel", MSMQMAIL_RECIPIENT_TO
   email.Recipients.Add "MAPI Recipient Name", "MAPIUserInputQueueLabel", MSMQMAIL_RECIPIENT_CC

'Set the TNEF information of the e-mail.
   email.TnefData.Data = tnefdata

   '**********************
   '* Compose message Body
   '**********************
   msg.Body = email.ComposeBody

   '****************************
   '* Display size of TNEF data.
   '****************************
   MsgBox "The size of the TNEF data is:" + (UBound(email.TnefData.Data) - LBound(email.TnefData.Data) + 1)

End Sub

Requirements

Windows NT/2000 or later: Requires Windows NT 4.0 SP3 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Library: Included as a resource in Mqmailoa.dll.

See Also

Add, Address, Body, ComposeBody, ContentType, MSMQMailEMail, MSMQMessage, Name, Recipients, Sender, Subject, TextMessageData


Message Queuing Glossary

A

access mode
A setting that specifies how a queue is opened. A queue can be opened with send access, peek access, or receive access.

Send access is used when sending messages to the queue, peek access is used when looking at the messages in the queue, and receive access is used when looking at or retrieving the messages from the queue.

access rights
A setting that restricts who can create, delete, or open a queue; who can send messages to or retrieve messages from the queue; and who can get or set the properties or security descriptor of the queue.

Access rights are specified in the security descriptor for a queue.

acknowledgment level
A setting that indicates the type of acknowledgment messages returned to the sending application. These include negative acknowledgment messages, or a combination of both positive and negative acknowledgment messages.

To set the acknowledgment level of a message, specify the PROPID_M_ACKNOWLEDGE property (when using function calls) or the MSMQMessage.Ack property (when using COM components).

See also acknowledgment message.

acknowledgment message
A system-generated message that indicates whether a sent message reached its queue, was retrieved from the queue, or both.

Acknowledgment messages are generated by Message Queuing, or by connector applications and computers outside the Message Queuing system.

Active Directory
The Microsoft directory service feature included with Microsoft® Windows NT® Server 5.0. MSMQ 2.0 uses Active Directory™ as its directory service.

MSMQ 1.0, on the other hand, uses MSMQ information store (MQIS) as its directory service.

See also directory service and MSMQ information store.

Active Directory Manager
A directory service designed to perform day-to-day directory administration tasks. These common tasks include creating, deleting, modifying, moving, and setting permissions on directory objects such as organizational units, users, contacts, groups, computers, printers, and shared file folders.
address specification
The address specification of a computer. It can be specified using two forms: either as the network protocol followed by the network address of the target machine or as the operating system protocol (OS) followed by any string (supported by the underlying operating system) that identifies the target machine.

For example:

SPX:00000012;00A0234F7500 //supported only on Windows NT4 and Windows 2000
TCP:157.18.3.1
OS:MachineName
administration queue
A queue created and maintained by the sending application that receives system-generated acknowledgment messages. Acknowledgment messages cant indicate if a message reached its destination queue, was retrieved from the destination queue, or both.

When sending message, the sending application can specify one administration queue (MSMQ 2.0 and earlier) or any number of administration queues (introduced in MSMQ 3.0).

application input queue
A queue created by the Message Queuing application that is reading Message Queuing mail formatted messages. When the application creates the queue, the label and type properties of the queue must be set to specific values.

The queue label must match the address field of the sending applications MAPI address.

The queue type must be set to the following MAPI type identifier:

{5EADC0D0-7182-11CF-A8FF-0020AFB8FB50}

When a MAPI e-mail is sent to an Message Queuing application, the sending Message Queuing mail service (MAPI Transport Provider or MSMQ Exchange Connector) locates the application input queue by the queue's label and type. If the mail service cannot find the queue with the correct label and type, the form is rejected and a non-delivery report is generated.

application object
An object whose methods provide global syntactic functionality. Unlike most application objects, the Message Queuing application object does not start a new instance of Message Queuing.
application queue
A public or private queue created by an application or the MSMQ Explorer. Application queues include message queues, administration queues, and response queues.

Application queues are user-defined. In contrast to system queues that are generated by Message Queuing.

application-encrypted
Messages that are encrypted by the sending application, not by Message Queuing. Applications must encrypt their own messages when sending messages where there is no access to the directory service (for example, when sending message using a direct format name, when operating in foreign enterprises, or when operating in a Windows 2000 workgroup environment).
application-specific information
Information generated by the application for which it is the responsibility of the sending and receiving application to understand what actions should be performed for a specific value. It can be single integer values or application-defined message classes.
audit
A process that allows applications to monitor queue operations. Queue operations can be audited by modifying the system access control list (SACL) of the queue's security descriptor. For a complete description of auditing, see Microsoft® Windows NT® Help


B

base priority level
A property of a public queue that Message Queuing uses for routing the queue's messages over the network. The base priority level can be used to give the messages sent to a queue higher (or lower) priority than messages sent to other queues. When a queue's base priority is set, all the messages sent to it are given a higher priority than messages sent to queues with a lower base priority. The queue's base priority has no effect on the order of the messages in the queue or how messages are read from the queue.


C

CA
See certification authority.
callback function
A function used to asynchronously read the messages in a queue. It is an application-defined function that Message Queuing calls when a message is available or an error (for example a time out) occurs.
certification authority (CA)
An entity that issues external certificates. The certification authority accepts requests for certificates, confirms that the information provided in the request is accurate, and returns a certificate to the person requesting it.

The requester must provide their public key and whatever additional information is required by the certification authority.

computer
Computers are created and maintained by the Message Queuing administrator. All existing computers are defined in the directory service.

A computer's properties can be retrieved using MQGetMachineProperties.

See also directory service.

computer journal
A system queue used to store copies of application-generated messages. This is also called machine journal and source journal.

See also queue journal.

computersystemqueue
One of the three system queues associated with the computer: JOURNAL, DEADLETTER, OR DEADXACT.

See also, direct format name.

connector application
An application that works with the MSMQ Connector Service to translate between Message Queuing messages and foreign messages.

Connector applications may also perform security services such as authenticating messages and encrypting/decrypting messages.

connector queue
A queue used by an MSMQ Connector server. Messages sent to foreign queues are temporarily stored in a connector queue before they are retrieved by the connector application.

MSMQ Connector servers can have several pairs of connector queues. There is a transactional and non-transactional queue for each foreign site connected to the server.

correlation identifier
A 20-byte identifier used to identify a message. The correlation identifier message property can be set by Message Queuing (when generating acknowledgement and report messages) or by the sending application.

The correlation identifier must be exactly 20-bytes in length.

critical section object
A Win32 object that provides mutually exclusive synchronization within a process. A critical section object can only be used by one thread at a time.

For more information on critical section objects, see the Platform SDK and winbase.h.

cursor
A mechanism that receiving applications can use to maintain a specific location when navigating through a queue. Each cursor is associated with a specific instance of an open queue.


D

dead-letter queue
A system queue used to store application-generated messages that cannot be delivered. There are two types of dead-letter queues on each computer, one for transactional messages and the other for non-transactional messages.
DEADXACT
A keyword added to the format name of the source computer that indicates the transactional dead-letter queue on the source computer is requested.

See also transactional_dead-letter queue.

DEADLETTER
A keyword added to the format name of the source computer that indicates the non-transactional dead-letter queue on the source computer is requested.

See also dead-letter queue.

delivery report
An e-mail report that is sent to the originator of a previously sent e-mail (referenced as the original e-mail). It contains a list of the recipients who received the original e-mail and when, plus the original e-mail's subject and submission time.
dependent client
An Message Queuing computer that require synchronous access to the supporting Message Queuing server to perform all standard Message Queuing functions. This includes creating queues, sending messages, and receiving messages.
digital signature
An encrypted hash value based on several message properties. MSMQ 1.0 provides a single type of signature, the MSMQ 1.0 signature. However, MSMQ 2.0 provides both MSMQ 1.0 signatures and MSMQ 2.0 signatures.

The digital signature is used to ensure message integrity through message authentication. It is created by the Message Queuing run time and attached to messages when they are sent, then used by the receiving queue manager to verify that the message was not modified.

direct connection
A connection where there is direct network connectivity between two computers. When opening a queue to read messages, both computers must support the same protocol.
direct format name
A format used to open a queue that is not necessarily in your enterprise or when you want to make sure Message Queuing sends messages to the queue in one step.

Direct format names include the address of the computer where the queue is located followed by the local name of the queue (the name specified in the queue's pathname when the queue was created).

See also address specification.

directory service
Different versions of Message Queuing use two different directory services. MSMQ 1.0 uses MSMQ information store (MQIS), and MSMQ 2.0 uses Active Directory™. In both cases, Message Queuing uses the directory service to store, organize, and make available information about public queues, certificates, computers, and so on.

See also Active Directory and MSMQ information store.

DistributionListGUID
A GUID identifier that identifies the distribution list in Active Directory. This identifier can be found in the objectGUID property of the distribution list group in Active Directory.
distribution list
An Active Directory group object that is referenced by a distribution list format name. A distribution list format name can be used to send messages to multiple destinations and to specify sets of administration or response queues.

Distribution lists can contain references to public queues, queue aliases, and other distribution lists.


E

E-mail message
An electronic mail message. There are several types of e-mail messages used by the Message Queuing mail services: forms, text messages, TNEF messages, delivery reports, and non-delivery reports.

E-mail forms contain information in pre-defined fields, text messages use a single text body to pass information, TNEF messages contain a rich-text body in TNEF format, and delivery and non-delivery report messages specify whether or not a previously sent e-mail reached its intended recipients.

See also Transport-Neutral Encapsulation Format.

e-mail form
An e-mail message that contains one or more fields.
express
A delivery mode that provides the fastest delivery. The message stays in memory (RAM) until it can be delivered and is not recovered if the computer is rebooted.
external certificate
A certificate obtained from a certification authority. It is used when the receiving application needs information provided in the certificate to verify who sent a message.

External certificates contain information about the certification authority, the certificate user, the validity period of the certificate, the public key of the certificate user, and the certification authority's signature.

See internal certificate.

external transaction
A transaction called when the transaction includes units of work that incorporate more than one resource manager (for example, a transaction that includes more than simply sending or retrieving Message Queuing messages).

In this case, the application must ask MS DTC for a transaction object and reference that object each time it sends a message, retrieves a message, or executes an action of another resource manager.


F

foreign application
An application that is running on a messaging service other than Message Queuing.
foreign CN
A connected network (CN) that contains computers that do not run Message Queuing (foreign computers) and at least one MSMQ Connector server.

For information on creating, renaming, or removing a foreign CN, see Microsoft® Windows NT® Help.

foreign CN GUID
A GUID identifier that identifies the foreign site (or connected network for MSMQ 1.0 applications) where a specific MSMQ Connector is located.

The identifier is generated by Message Queuing when the site (or connected network) is created.

For information on CNs, see Microsoft® Windows NT® Help.

foreign computer
A computer that does not run Message Queuing, but can exchange messages with Message Queuing through a connector application.

For information on creating, renaming, or removing a foreign computer, see Microsoft® Windows NT® Help.

foreign queue
A queue that resides on a computer that does not run Message Queuing (a foreign computer).
format name
A name used to specify a queue when making calls to several functions.

The queue's format name is not an Message Queuing queue property. It is a unique name for the queue that is generated by Message Queuing when the queue is created or generated later by the application. Message Queuing never stores the format name of a queue for later reference.

For example:

DIRECT=SPX:NetworkNumber;HostNumber\QueueName //supported only on Windows NT4 and Windows 2000
DIRECT=TCP:IPAddress\QueueName
DIRECT=OS:MachineName\QueueName


H

hive
A discrete body of registry keys, subkeys, and values that is rooted at the top of the registry.
HTTP message


I

independent client
An Message Queuing computer that runs the Message Queuing service, hosts queues, sends and receives messages, and can operate while disconnected from the network by default. These clients do not require synchronous access to a Message Queueing server to send and receive messages.

The primary difference between independent clients and Message Queueing servers is that independent clients do not provide directory services access or the message routing capabilities of Message Queuing servers that have routing enabled.

In addition to the basic Message Queuing files, you can install Message Queuing on Message Queuing independent clients.

internal certificate
A certificate provided by Message Queuing that is used to verify message integrity when operating in a Windows® 2000 domain environment.

An internal certificate contains a public key and the sender identifier (SID) of the user that registered the certificate. It is written in the form of an X.509 certificate. It does not contain additional sender information that can be used for authentication.

See also external certificate.

internal transaction
A transaction called where Message Queuing is the only resource manager. Message Queuing internal transactions cannot be passed to another resource manager, unlike MS DTC external transactions. Significant overhead is needed to coordinate between several resource managers, thus, whenever possible, Message Queuing internal transactions are a better choice than MS DTC external transactions.


J

journal queue
See machine journal and queue journal.
JOURNAL
A key word appended to the format name of a queue or computer to indicate that the associated queue journal or computer journal is requested.

To create a format name for a queue journal, obtain a format name for the destination queue and append ";JOURNAL" to the end of the returned format name.

To create a format name for a computer journal, obtain a format name for the computer and append ";JOURNAL" to the end of the returned format name.

journaling level
A queue setting that specifies if the queue's queue journal should be used, or a message setting the indicates if the source computer's computer journal or dead-letter queue should be used.


L

local machine
For Message Queuing servers and independent clients, the local machine is the local computer. However, for Message Queuing–dependent clients, the local machine is the client's Message Queuing server.
lookup identifier
A 64-bit identifier that is assigned to the message when the message is placed in the queue. Each identifier in the queue is unique, and is greater than the identifier of the previous message and less than the identifier of the next message in the queue.

The local queue manager generates the lookup identifier and sets the lookup identifier property of the message (PROPID_M_LOOKUPID or MSMQMessage.LookupId) whenever it places a message in a queue

LQS file

A text file that describes a queue. This file is created when the queue is created, and it is stored on the same computer as the queue. LQS files are located in the MSMQ\Storage\Lqs folder.


M

machine
See computer.
machine GUID
A computer identifier generated by Message Queuing when the computer is added to your enterprise. (Same as "machine identifier.").

The identifier of a machine can be retrieved by a call to MQGetMachineProperties.

machine identifier
A GUID identifier created by Message Queuing when a computer is added to your enterprise. (Same as "machine GUID.")

The identifier of a machine can be retrieved by a call to MQGetMachineProperties.

machine journal
See computer journal.
machine journal queue
See computer journal.
machine name
The name of the computer where the queue's messages will be stored. Message Queuing supports both the NetBIOS and full DNS name of the machine. Machine names are not case sensitive, so "mymachine" and "MyMachine" are treated the same way.

To indicate the local computer, you can substitute the string "." for the name of the local machine. (For dependent clients, the local machine is the dependent client's server.)

For private queues, the machine name must be the name of the local machine.

mail message
An Message Queuing message whose body is formatted in Message Queuing mail format. The body of a mail message can be composed or parsed by any Message Queuing application.

The MSMQ Exchange Connector and MAPI Transport Provider translate between e-mail and Message Queuing mail messages.

message
An Message Queuing message that is defined by its properties. Included in these properties is the message body, which contains the bulk of the information passed between applications.
message identifier
A 20-byte Message Queuing–generated identifier composed of the machine GUID of the computer that sent the message plus an identifier that is unique to the computer. By combining these two components, the message identifier is unique within your enterprise.

Message Queuing sets the message identifier property of a message when it is sent. In addition, Message Queuing uses the message identifier to indicate the original application message associated with an acknowledgment or report message.

message priority level
An indicator used to place messages in the queue. Messages with higher priority are placed towards the front of the queue.
message queue
An application-generated queue that contains application-generated messages. Applications can send messages to these queues or read their messages. They can be public queues that are registered in the directory service or private queues that are registered on individual computers.

See also directory service.

MIME
See Multipurpose Internet Mail Extensions.
MS DTC external transaction
An external transaction where the transaction object is provided by Microsoft® Distributed Transaction Coordinator (MS DTC). Used when more then one resource manager is required.
MSMQ 1.0 signatures
A digital signature based on a hash of the following message properties. This signature type is supported by all versions of Message Queuing.

correlation identifier
application specific identifier
message body
message label
response queue
administration queue
extension

For more information, see the "Digital Signatures" topic.

MSMQ 2.0 signatures
A digital signature based on a hash of the following message properties. This type provides tighter security due to the number of message properties used when creating the signature, but is not supported by MSMQ 1.0.

correlation identifier
application specific identifier
message body
message label
response queue
administration queue
extension
destination queue
source machine identifier
delivery mode
priority level
journal level
acknowledgment level
message class
body type
connector type

For more information, see the "Digital Signatures" topic.

MSMQ Connector server
An MSMQ Connector server allows Message Queuing–based applications to communicate with computers that use other messaging systems (foreign computers). MSMQ Connector servers use internal connector queues and a connector application to pass messages between the Message Queuing and foreign enterprises.

The Level 8 Systems Message Queuing message queuing product is an example of an MSMQ Connector server.

MSMQ information store (MQIS)
A Microsoft® SQL Server version 6.5 replicated database that MSMQ 1.0 uses as its directory service. MSMQ 1.0 uses MQIS to store information about your Message Queuing enterprise.

MSMQ 2.0, on the other hand, uses Active Directory™ as its directory service.

See also Active Directory and directory service.

Message Queuing internal transaction
A transaction provided by Message Queuing. Internal transactions cannot be passed to other resource managers.
Message Queuing mail format
The Message Queuing mail format used by applications to send messages to e-mail based applications. The Message Queuing mail format is a subset of the standard Multipurpose Internet Mail Extensions (MIME) format.
MTS transaction
A transaction that uses the Microsoft® Transaction Server (MTS) environment. When using Message Queuing COM objects, Message Queuing can implicitly use the current MTS transaction if one is available.
multicast address
A group address that can be used to send message to multiple destinations and to specify sets of administration or response queues.
multi-threaded apartment
A programming model in which apartments consist of one or more threads. As a result, all COM objects in a multi-threaded apartment receive method calls directly from any caller thread that belongs to the multi-threaded apartment. Threads in a multi-threaded apartment use a model called "free-threading".
multiple-element format name
A local format name that be used to send messages to multiple destinations and to specify sets of administration or response queues.

A multiple-element format name can consist of one or more public, private, distribution list, or multicast address format names.

Multipurpose Internet Mail Extensions (MIME)
A standard that is used to encode Internet mail messages and is described by several RFCs; the most relevant RFCs are RFC-822, 1521 (MIME), and RFC-1867 (form data).


N

negative source journaling
The process used by Message Queuing to respond when a message could not be delivered. Negative source journaling uses a transactional and non-transaction dead-letter queues to store message that fail.

For information on setting negative source journaling, see PROPID_M_JOURNAL or MSMQMessage.Journal.

non-delivery report
E-mail that is sent to the originator of a previously sent e-mail (referenced as the original e-mail). It contains the recipients who did not receive the original e-mail, the reason e-mail was not delivered, and the original e-mail content.
non-transactional message
Any message that is sent to a non-transactional queue. Typically, any message that is not part of a transaction.

See also non-transactional queue.

non-transactional queue
A queue that only contains non-transactional messages.

See also non-transactional message.


P

pathname
A name used when creating the queue. It indicates the machine where the queue's messages are stored, where the queue is registered, and provides a name for the queue.
peek
To look at a message in a queue without removing it from the queue.

See also read or retrieve.

peek access
An access mode that allows messages to be read from the queue without removing them. Used when the receiving application opens a queue to read message.

The access mode of a queue is set when the queue is opened, and it cannot be changed while the queue is open.

positive source journaling
The process used by Message Queuing to respond when a message is successfully delivered to the next computer. Positive source journaling uses computer journals to store copies of message that are successfully sent.

For information on setting positive source journaling, see PROPID_M_JOURNAL or MSMQMessage.Journal.

privacy level
A queue setting that indicates if the queue accepts only private (encrypted) messages, or a message setting that indicates if the body of the message is encrypted.
private format name
A format name used to specify queues not registered in the directory service. The private format name of the queue includes the string "Private=" followed by the MachineGUID (machine identifier) of the computer where the queue is located, and a hexadecimal number that identifies the queue.

The following is the general format of a private format name:

"PRIVATE=MachineGUID\QueueNumber"

See also directory service.

private message
A message whose body is encrypted by Message Queuing. Applications can indicate that a message is private by setting the privacy-level of the message and indicate the encryption algorithm used to encrypt the message.
private queue
A queue registered on the local computer (not in the directory service) that typically cannot be located by other applications. Private queues have the advantage of no directory service overhead (faster to create, no latency, and no replication), and they can be created and deleted when the directory service is not working.

See also public queue and directory service.

private signing key
A signature key used by Message Queuing run-time to digitally sign a message. The private signing key is part of the signature key pair and should always be kept private.

See also public signing key.

PRIVATE$
A keyword that indicates the queue is private and is registered on the local computer. Its absence indicates a public queue that is registered in the directory service.
public format name
A format name used to specify a queue registered in the directory service. A queue's public format name contains the string "Public=" followed by the queue identifier generated by Message Queuing when the queue was created.

The following is the general format for public format names:

"PUBLIC=QueueGUID"

See also directory service.

public queue
A queue registered in the directory service that can be located by any Message Queuing application. Public queues are persistent and their registration information can be backed up on the enterprise, making them good for long-term use.

See also private queue and directory service.

public signing key
A signature key used by the receiving queue manager to validate the digital signature of a message. The public signing key is extracted from the certificate attached to the message.

See also private signing key.


Q

queue
Objects that hold messages passed between applications, or messages passed between Message Queuing and applications. In general, applications can send messages to queues and read messages from queues.

Message Queuing uses application queues (queues created by applications) and system queues (queues created by Message Queuing).

queue alias
An Active Directory object used to reference queues that might not be listed in Active Directory. For example, a queue alias can be used to reference a private queue in a distribution list.

Queue aliases are referenced by their ADs path. The following is an example of the ADs path to a queue alias.

"LDAP://CN=QueueAlias,OU=Domain Controllers,DC=DOM,DC=shush,DC=lab"
queue GUID
A GUID queue identifier returned by Message Queuing when the queue is created.
queue handle
The handle returned when the queue is opened. The queue handle is primarily used when making API function calls to send messages, read messages, create cursors, and to close the queue.

Applications using COM components can access the queue handle through the MSMQQueue.Handle property.

queue identifier
A GUID identifier that uniquely identifies each queue created by Message Queuing. This includes applications and system queues.
queue journal
A system queue used to store messages retrieved from their destination queue. This is also called a target journal.
queue name
An application-defined name, used to identify the queue, that is specified when the queue is created (maximum length 124 Unicode characters).

Queue names may consist of any character except "\" and ";". In addition, the last character in the name may not be the "$" character (Message Queuing reserves names ending with "$", for example, the token "PRIVATE$" is used to specify a private queue).

Queue names are case-insensitive. For example, "MyQueue" and "myQueue" are treated as the same name.

queue number
An eight-digit, hexadecimal number that identifies the private queue. It is generated by Message Queuing when the queue is created on the local computer.

To find the queue number of a private queue, use Windows Explorer to locate the queue in the …\MSMQ\Storage\Lqs folder. Typically, Message Queuing is installed in c:\program files\msmq.

queue manager
An Message Queuing service responsible for delivering, receiving, authenticating, and routing messages, as well as maintaining information in the directory service.

See also directory service.


R

read
The process of peeking at or retrieving a message in the queue.

See also peek or retrieve.

receive
The process of retrieving a message from a queue.
receive access
An access mode that allows messages to be retrieved from the queue when they are read. Used when the receiving application opens a queue to remove messages.

The access mode of a queue is set when the queue is opened, and it cannot be changed while the queue is open.

recoverable
A delivery mode that guarantees message delivery even in the case of a computer crash. In this mode the message is forwarded to the next hop or stored in a local backup file at every hop along its route until it is delivered
report message
A system-message that is generated each time an application message passes through an Message Queuing routing server.

See also report queue.

report queue
A queue used to track the progress of your messages as they move through your enterprise. Report queues receive Message Queuing–generated report messages. Applications can only read the messages in a report queue.

See also report message.

response message
An application-generated message that is returned to a response queue specified by the sending application.

See also response queue.

response queue
A queue used by the receiving application to return application-generated response messages to the sending application.

See also response message.

retrieve
The process of reading and removing a message from a queue.

See also peek or read.

rich-text recipient
A recipient whose Send to this recipient in Microsoft Exchange rich text format check box is selected in their Exchange/MAPI address. The Message Queuing mail format of an e-mail sent to this type of recipient contains TNEF (a proprietary MAPI format) information.


S

security certificate
An internal or external certificate that contains information used to authenticate messages. The certificate contains information about the sender and the public signature key of the sender.

See also internal certificate and external certificate.

security context information
Information used by Message Queuing to attach a certificate to a message or to impersonate a user. When sending authenticated messages, the security context information is extracted from the certificate once, then used by Message Queuing run-time to attach the same certificate to any number of messages. Security context information is used primarily when a large number of authenticated messages are sent using the same certificate.

Security context information is stored locally, and is not sent with the message.

security descriptor
An opaque structure that consists of a SECURITY_DESCRIPTOR structure and its associated security information.

Security information can include security identifiers (SID), a discretionary access-control list (DACL), and a system access-control list (SACL).

For a complete description of security descriptors, see the Platform SDK.

security identifier (SID)
A unique value of variable length used to identify a user or group. The SID is assigned when the user logs on and becomes part of the access token for any process started by the user.
send access
An access mode that allows messages to be sent to the queue. Used when the sending application opens a queue to send messages.

The access mode of a queue is set when the queue is opened and cannot be changed while the queue is open.

server input queue
The Exchange server input queue is created by the MSMQ Exchange Connector when the connector starts the first time. When an Message Queuing message reaches this queue, it is picked up by the MSMQ Exchange Connector, translated into an e-mail message, and sent to the Exchange Server where it is distributed to the appropriate Exchange user.

The queue's label is set by the Exchange Connector's Setup program. In addition, the Exchange Connector sets the queue's type to the MAPI type identifier shown in the following example.

MAPI type identifier:

{5EADC0D0-7182-11CF-A8FF-0020AFB8FB50}
share mode
A queue setting that specifies who can use the queue when it is opened with peek or receive access (share mode does not apply to queues opened with send access). The queue can be restricted to exclusive access or completely unrestricted access.

The share mode of a queue is set when the queue is opened.

SID
See security identifier.

The SID contains a 48-bit identifier authority value, a revision level, and any number of subauthority values. For a complete description of SIDs, see the Platform SDK.

single-message transaction
A single-message transaction is a special case of an Message Queuing internal transaction that can be used to guarantee exactly once delivery of a single message. This transaction implicitly uses the Message Queuing internal transaction to send a single message to a transactional queue.
single-threaded apartment
A programming model in which apartments consist of exactly one thread. As a result, all COM objects in a single-threaded apartment receive method calls only through the one thread that belongs to that apartment. All method calls to a COM object in a single-threaded apartment are processed synchronously.
source journaling
The ability to track messages that were sent. Applications can request positive source journaling (the message was successfully sent from the computer), negative source journaling (the message could not be delivered), or both.

When source journaling is requested, returned messages are sent to the computer journal queue (for positive source journaling) or one of two dead-letter queues (negative source journaling.

SYSTEM$
A keyword that indicates the queue is a computer system queue. These queues include the computer's computer journal queue, non-transactional dead-letter queue, and transactional dead-letter queue.

See also, computersystemqueue.

SOAP attachments
XML or non-XML documents attached to an SRMP message. The SOAP envelope may contain information on what is in the message, who should process the message, and whether the message is optional or required.

An SRMP message is a special form of a SOAP message.

SOAP envelope
The top element of the XML document that represents an SRMP message. The SOAP envelope may contain information on what is in the message, who should process the message, and whether the message is optional or required.

An SRMP message is a special form of a SOAP message.

system queue
A queues created by Message Queuing or indirectly by the Message Queuing administrator. System queues include queue journals, dead-letter queues, and report queues.


T

target journal
See queue journal.
target journaling
The process Message Queuing uses to respond when messages are removed from a queue. Target journaling uses the journal of a queue to store copies of messages removed from the queue.

For information on setting target journaling, see PROPID_Q_JOURNAL or MSMQQueueInfo.Journal.

text message
An e-mail message that uses a single text body to pass information.
TNEF
See Transport-Neutral Encapsulation Format.
TNEF message
A message formatted in Transport-Neutral Encapsulation format (TNEF).

See also Transport-Neutral Encapsulation Format (TNEF).

transaction boundaries
The boundaries that define a group of messages sent within a single transaction. When transactional messages are sent to a single destination queue, the receiving application can use the transaction boundaries to verify that first and last messages sent in a transaction have not been lost by the application while the messages were waiting in the queue.
transactional dead-letter queue
A system-generated transactional queue located on each source computer. It is used to store a copy of each non-confirmed message sent within a transaction. Looking into this queue after the proper interval gives the sending application a guaranteed way to verify that the message was delivered and processed by the receiving application.
transaction level
A queue setting that indicates if the queue accepts transactional or non-transactional messages. This setting is set when the queue is created and cannot be changed later.
transactional message
A message sent as part of a transaction. Transaction messages must be sent to transactional queues.

See also transactional queue.

transactional queue
A queue that contains transactional messages. Transaction queues can only contain transactional messages, which are messages sent within a transaction.

See also transactional message.

transaction status queue
A system-queue that contains the read receipt acknowledgments returned by connector applications. It is specified by setting the message's PROPID_M_XACT_STATUS_QUEUE property. The transaction status queue must be a transactional queue.
Transport-Neutral Encapsulation Format (TNEF)
A MAPI-defined format that encapsulates MAPI message properties inside a single binary stream. To preserve MAPI properties, a sending application can encode a MAPI message into a TNEF stream and send the stream to a receiving application. The receiving application can use MAPI to decode the stream and reconstruct the original MAPI message.


U

user input queue
A queue created when the MSMQ MAPI Transport Provider is started the first time. The transport provider creates a user input queue for each MAPI user. The queue is created with an enterprise scope, its type property set to the MAPI type identifier shown in the following example, and its label set to a MAPI user's logon name.

MAPI type identifier:

{5EADC0D0-7182-11CF-A8FF-0020AFB8FB50}

An Message Queuing mail message that reaches this queue is picked up by the MSMQ MAPI Transport Provider, translated into an e-mail message, and sent to the Inbox of the MAPI user.


W

workgroup environment
A Microsoft® Windows® 2000 environment where there is no the directory service. In this environment, Message Queuing is limited to those functions and methods that do not require access to the directory service.

See also directory service.


X

XA transaction
A transaction that uses an XA-compliant transaction manager. Message Queuing implicitly calls the current XA transaction.
XACTONLY
A keyword that indicates that the transactional connector queue is requested.


Message Queuing Appendix

The Message Queuing Appendix contains the following information.

For information on | See
Error and information codes returned by Message Queuing. | Message Queuing Error and Information Codes
Files found in the Message Queuing Storage and Lqs folders. | Storage Folder Files
Creating location independent queues | Programming for Location Independence


Message Queuing Error and Information Codes

Error and information codes are returned in two ways: directly by Message Queuing functions and COM object methods, or via the optional aStatus array specified in an MQQUEUEPROPS, MQMSGPROPS, or MQQMPROPS structure.

The following error and information codes are defined in mq.h.

Error Codes

MQ_ERROR_ACCESS_DENIED
Returned when access to the specified queue or computer is denied.

When returned, verify that you have the access rights for the operation (for example, creating, setting properties, or deleting a queue). To change access rights for a queue, call MQSetQueueSecurity.

MQ_ERROR_BAD_DSSERVER_REGISTRY
Returned when the registry parameter for the directory service server has a bad value.
MQ_ERROR_BAD_SECURITY_CONTEXT
Returned when the Security context specified by PROPID_M_SECURITY_CONTEXT is corrupted.
MQ_ERROR_BUFFER_OVERFLOW
When reading messages, a supplied buffer for a property is too small. In the case of the message body buffer, the portion of the message body that fits is copied to the buffer, but the message is not removed from the queue.
MQ_ERROR_CANNOT_CREATE_CERT_STORE
Message Queuing cannot create a certificate store for its internal certificate. This error is returned only when you do not have permission to manipulate your own profile.
MQ_ERROR_CANNOT_IMPERSONATE_CLIENT
Returned when the directory service server cannot impersonate the client application. Security credentials could not be verified.
MQ_ERROR_CANNOT_OPEN_CERT_STORE
Message Queuing cannot open the certificate store for its internal certificate. This error is returned only when you do not have permission to manipulate your own profile.
MQ_ERROR_CERTIFICATE_NOT_PROVIDED
Returned when the sending application attempts to use security context information to authenticate a message, and the security context does not include a certificate.
MQ_ERROR_COMPUTER_DOES_NOT_SUPPORT_ENCRYPTION
Returned when encryption is requested and the computer (source or destination) does not support encryption operations.

When this error is returned the encryption operation fails.

MQ_ERROR_CORRUPTED_INTERNAL_CERTIFICATE
(MSMQ 1.0 only) Returned when the Message Queuing–supplied internal certificate is corrupted.
MQ_ERROR_CORRUPTED_PERSONAL_CERT_STORE
Returned when the Microsoft® Internet Explorer personal certificate store is corrupted.
MQ_ERROR_CORRUPTED_SECURITY_DATA
Returned when a cryptographic function (CryptoAPI) has failed.
MQ_ERROR_COULD_NOT_GET_ACCOUNT_INFO
Returned when Message Queuing cannot get account information for the user.
MQ_ERROR_COULD_NOT_GET_USER_SID
Returned when Message Queuing cannot get the specified sender identifier.
MQ_ERROR_DELETE_CN_IN_USE
Returned when the specified connected network (CN) cannot be deleted because it is defined in at least one other computer. Remove the CN from all CN lists and try again.
MQ_ERROR_DS_ERROR
Returned when an internal error with the directory service is issued.
MQ_ERROR_DS_IS_FULL
(MSMQ 1.0 only). Returned when the MSMQ information store is full.
MQ_ERROR_DTC_CONNECT
Returned when Message Queuing cannot connect to the Microsoft® Distributed Transaction Coordinator (MS DTC).
MQ_ERROR_FORMATNAME_BUFFER_TOO_SMALL
Returned when the specified format name buffer is too small to contain the returned format name of the queue.
MQ_ERROR_FUNCTION_NOT_SUPPORTED
Returned when a call is made to a function is not supported in Windows 95.
MQ_ERROR_ILLEGAL_CONTEXT
Returned when the lpwcsContext parameter of MQLocateBegin is not NULL.
MQ_ERROR_ILLEGAL_CURSOR_OPERATION
Returned when an attempt is made to move the cursor after it has already been moved by Message Queuing.

For example, you try to perform a peek-next operation after removing a message from the queue. In this case, Message Queuing has already moved the cursor when it removed the message from the queue.

MQ_ERROR_ILLEGAL_FORMATNAME
Returned when the specified format name is not valid.
MQ_ERROR_ILLEGAL_MQCOLUMNS
Returned when pColumns is set to NULL.
MQ_ERROR_ILLEGAL_MQQMPROPS
Returned when no properties are specified by the MQQMPROPS structure, or the pQMprops parameter is set to NULL.
MQ_ERROR_ILLEGAL_MQQUEUEPROPS
Returned when no properties are specified by the MQQUEUEPROPS structure, or the pQueueProps parameter is set to NULL.
MQ_ERROR_ILLEGAL_OPERATION
Returned when the requested operation is not supported on this specific platform.
MQ_ERROR_ILLEGAL_PROPERTY_SIZE
Returned when the specified buffer for the message identifier or correlation identifier is not the correct size.
MQ_ERROR_ILLEGAL_PROPERTY_VALUE
Returned when an illegal property value is specified in the MQPROPVARIANT array.
MQ_ERROR_ILLEGAL_PROPERTY_VT
Returned when an illegal VARTYPE is specified in the VT field of the MQPROPVARIANT array.
MQ_ERROR_ILLEGAL_PROPID
Returned when an invalid property identifier is specified in the property identifier array.
MQ_ERROR_ILLEGAL_QUEUE_PATHNAME
Returned when an invalid Message Queuing pathname is specified for the queue.
MQ_ERROR_ILLEGAL_RELATION
Returned when an invalid relationship parameter is specified.
MQ_ERROR_ILLEGAL_RESTRICTION_PROPID
Returned when an invalid property identifier is specified in MQRESTRICTION.
MQ_ERROR_ILLEGAL_SECURITY_DESCRIPTOR
Returned when an invalid security descriptor is specified.
MQ_ERROR_ILLEGAL_SORT
Returned when an illegal sort is specified.
MQ_ERROR_ILLEGAL_SORT_PROPID
Returned when an invalid property identifier is specified in MQSORTSET.
MQ_ERROR_ILLEGAL_USER
Returned when an illegal User is specified.
MQ_ERROR_INCONSISTENT_QM_ID
Returned when an inconsistency exists between the queue manager identifier found in the directory service and the one found in the registry.
MQ_ERROR_INSUFFICIENT_PROPERTIES
Returned when not all properties required for the operation were specified.
MQ_ERROR_INSUFFICIENT_RESOURCES
Returned when there are insufficient resources to complete the operation (for example, not enough memory).

When this error is returned the operation fails.

MQ_ERROR_INVALID_CERTIFICATE
Returned when the security certificate specified by PROPID_M_SENDER_CERT is invalid, or the certificate is not correctly placed in the Microsoft® Internet Explorer personal certificate store.
MQ_ERROR_INVALID_HANDLE
Returned when the specified queue handle is not valid.
MQ_ERROR_INVALID_OWNER
Returned when an invalid object owner is specified. For example, this code is returned when trying to create a queue on a machine where Message Queuing is not installed.
MQ_ERROR_INVALID_PARAMETER
Returned when one of the IN parameters supplied by the operation is not valid.
MQ_ERROR_IO_TIMEOUT
Returned when the MQReceiveMessage I/O time-out has expired.
MQ_ERROR_LABEL_TOO_LONG
Returned when the specified message label is too long. The message label should be equal to or less than MQ_MAX_MSG_LABEL_LEN.
MQ_ERROR_LABEL_BUFFER_TOO_SMALL
Returned when the supplied message label buffer is too small for received label.
MQ_ERROR_LOG_XACT_STATE
Returned when Message Queuing cannot log transaction state.
MQ_ERROR_LOGMGR_LOAD
Returned when Message Queuing cannot get log manager library or interface.
MQ_ERROR_MACHINE_EXISTS
Returned when the specified machine name already exists.
MQ_ERROR_MACHINE_NOT_FOUND
returned when the specified machine could not be found in the directory service.
MQ_ERROR_MESSAGE_ALREADY_RECEIVED
Returned when some other cursor, application, or system administrator (using the directory service) has already removed the message from the queue.
MQ_ERROR_MESSAGE_STORAGE_FAILED
Returned when a recoverable message cannot be stored on the local computer.
MQ_ERROR_MISSING_CONNECTOR_TYPE
Returned when PROPID_M_CONNECTOR_TYPE is not specified.

This error is returned when a property (typically generated by Message Queuing) is specified without specifying the connector to use.

MQ_ERROR_MQIS_SERVER_EMPTY
(MSMQ 1.0 only). Returned when the list of MSMQ information store servers (in registry) is empty.
MQ_ERROR_NO_DS
Returned when the application cannot access the directory service.

When this error is returned, verify permissions for accessing the directory service.

MQ_ERROR_NO_INTERNAL_USER_CERT
Returned when no internal certificate is registered or the registered certificate is corrupted.
MQ_ERROR_NO_RESPONSE_FROM_OBJECT_SERVER
Returned when there is no response from the directory service server.

When this error is returned the status of the operation is unknown.

MQ_ERROR_NO_TRANSPORT
Returned when there is no network transport to the remote computer.
MQ_ERROR_OBJECT_SERVER_NOT_AVAILABLE
Returned when the directory service server for the object is not available.

When this error is returned the operation fails.

MQ_ERROR_OPERATION_CANCELLED
Returned when an operation is canceled before it could be started.
MQ_ERROR_PRIVILEGE_NOT_HELD
Returned when the application does not have the required privileges to perform the operation.
MQ_ERROR_PROPERTY
Returned when one or more of the specified properties causes an error.
MQ_ERROR_PROPERTY_NOTALLOWED
Returned when a specified property is not valid for the operation (for example, specifying PROPID_Q_INSTANCE when setting queue properties).
MQ_ERROR_PROV_NAME_BUFFER_TOO_SMALL
Returned when the provider name buffer is too small for the returned name of the cryptographic service provider.
MQ_ERROR_PUBLIC_KEY_DOES_NOT_EXIST
(MSMQ 2.0 only) This error is returned when you attempt to retrieve PROPID_QM_ENCRYPTION_PK_ENHANCED and the enhanced key is not registered. Message Queuing was able to successfully query the directory service, but the enhanced key was not found.
MQ_ERROR_PUBLIC_KEY_NOT_FOUND.
(MSMQ 2.0 only) This error is returned when you attempt to retrieve PROPID_QM_ENCRYPTION_PK_ENHANCED and Message Queuing failed to query the directory service. For example, this can happen if the computer calling MQGetMachineProperties is operating offline or if you are trying to retrieve the machine properties of a computer running MSMQ 1.0.
MQ_ERROR_Q_DNS_PROPERTY_NOT _SUPPORTED
Indicates that PROPID_Q_PATHNAME_DNS was specified in pColumns parameter of MQLocateBegin. You cannot retrieve the DNS pathname of a queue.
MQ_ERROR_QUEUE_DELETED
Returned when the queue is deleted before the message could be read.

The specified queue handle is no longer valid and the queue must be closed.

MQ_ERROR_QUEUE_EXCEEDS_QUOTA
Returned when a message is sent and the specified destination queue is full.
MQ_ERROR_QUEUE_EXISTS
Returned when a queue with the identical Message Queuing pathname is already registered.

Public queues are registered in the directory service. Private queues are registered in the local computer.

MQ_ERROR_QUEUE_NOT_AVAILABLE
Returned when trying to read a message from a queue residing on a remote computer.
MQ_ERROR_QUEUE_NOT_FOUND
Returned when Message Queuing cannot find the queue. This includes public queues not registered in the directory service and Internet queues that do not exist in the MSMQ namespace.
MQ_ERROR_RECOVER_TRANSACTIONS
Returned when Message Queuing could not recover the transactions.
MQ_ERROR_REGISTRATION_ERROR
Returned when an error occurs in registration access.
MQ_ERROR_RESULT_BUFFER_TOO_SMALL
Returned when the supplied result buffer is too small.

MQLocateNext could not return at least one complete query result.

MQ_ERROR_SECURITY_DESCRIPTOR_TOO_SMALL
Returned when the supplied security buffer is too small for the security descriptor.
MQ_ERROR_SENDER_CERT_BUFFER_TOO_SMALL
Returned when the supplied sender certificate buffer is too small for the certificate.
MQ_ERROR_SENDERID_BUFFER_TOO_SMALL
Returned when the supplied sender identification buffer is too small for the sender identification.
MQ_ERROR_SERVICE_NOT_AVAILABLE
Returned when the application is unable to connect to the queue manager.
MQ_ERROR_SIGNATURE_BUFFER_TOO_SMALL
Returned when the retrieved digital signature is to small for the buffer.
MQ_ERROR_SHARING_VIOLATION
Returned when an application is trying to open an already opened queue that has exclusive read rights.
MQ_ERROR_STALE_HANDLE
Returned when the specified handle was obtained in a previous session of the queue manager service.
MQ_ERROR_SYMM_KEY_BUFFER_TOO_SMALL
Returned when the symmetric key buffer is too small for the returned symmetric key.
MQ_ERROR_TOO_MANY_TRANSACTIONS
Returned when the application has too many active transactions.
MQ_ERROR_TRANSACTION_ENLIST
Returned when Message Queuing cannot enlist a transaction.
MQ_ERROR_TRANSACTION_FILE
Returned when Message Queuing cannot open or create a transaction file.
MQ_ERROR_TRANSACTION_IMPORT
Returned when Message Queuing cannot import the specified transaction.
MQ_ERROR_TRANSACTION_PREPAREINFO
Returned when Message Queuing cannot get the Prepare Info from the Microsoft Distributed Transaction Coordinator (MS DTC).
MQ_ERROR_TRANSACTION_QUEUE
Returned when the application could not create or use the transaction queue.
MQ_ERROR_TRANSACTION_SEQUENCE
Returned when the transaction operation sequence is incorrect.
MQ_ERROR_TRANSACTION_USAGE
While reading messages, one of the following actions were attempted within the context of a transaction.
  • An attempt was made to open a remote queue for read access.
  • An attempt was made to read a message from a non-transactional queue.
  • An attempt was made to read a message using a callback or overlap function.
MQ_ERROR_WRITE_NOT_ALLOWED
Returned when a write operation is attempted to the directory service and write operations are not allowed.
MQ_ERROR_UNSUPPORTED_ACCESS_MODE
Returned when the access mode specified when opening the queue is set to an invalid value, or the access mode and the share mode specified are not compatible.
MQ_ERROR_UNSUPPORTED_DBMS
Returned when the current version of the Database Management System is not supported.
MQ_ERROR_UNSUPPORTED_FORMATNAME_OPERATION
Returned when the requested operation is not supported for the specified format name (for example, trying to open a queue to receive messages using a direct format name).
MQ_ERROR_UNSUPPORTED_PROTOCOL
Returned when the specified remote machine network protocol is not supported.
MQ_ERROR_USER_BUFFER_TOO_SMALL
Returned when the supplied buffer is too small to hold the returned user information.

Information Codes

MQ_INFORMATION_DUPLICATE_PROPERTY
Returned when the supplied property with the same value has already been specified.

When duplicate settings are found, the first entry is used and subsequent settings are ignored.

MQ_INFORMATION_FORMATNAME_BUFFER_TOO_SMALL
Returned when the supplied format name buffer is too small. Queue was still created.
MQ_INFORMATION_ILLEGAL_PROPERTY
Returned when an invalid property identifier is specified in aPropID.
MQ_INFORMATION_INTERNAL_USER_CERT_EXISTS
An internal certificate already exists. This information code does not indicate an error condition. It is returned when dwFlags is set to MQ_REGISTER_IF_NOT_EXIST.
MQ_INFORMATION_OPERATION_PENDING
Returned when an asynchronous operation is pending.
MQ_INFORMATION_OWNER_IGNORED
Returned when MQSetQueueSecurity does not set the owner of a queue but does set the other elements identified in the SECURITY_INFORMATION structure referenced as a parameter.
MQ_INFORMATION_PROPERTY
Returned when one or more of the specified properties resulted in a warning. Operation completed anyway.
MQ_INFORMATION_PROPERTY_IGNORED
Returned when a specified property is not valid for this operation (for example, PROPID_M_SENDERID is not valid; it is set by Message Queuing when sending messages).
MQ_INFORMATION_UNSUPPORTED_PROPERTY
Returned when the specified property is not supported by this operation. This property is ignored.


Storage Folder Files

This topic describes the message files found in the MSMQ\Storage folder and the queue registration files found in MSMQ\Storage\Lqs. This information is useful when you need to manually retrieve the queue number of a private queue, inspect the properties of a private queue, or determine the disk space being used to store the messages on a computer.

Files in the MSMQ\Storage Folder

The files in the MSMQ\Storage folder include message files (xxxxxxxxx.mq files), a history file (QMLog file), and state files for received message (MQInSeqs.lgx files) and transaction operations (MQTrans.lgx files).

Message files with an .mq extension represent memory-mapped files where messages are stored. Each file can be up to 4 MB in size. A single file does not represent the messages of a single queue. Each file may contain messages from multiple queues, and conversely, a single queue's messages may be stored in several files. The only restriction to how messages are stored in these files is that a single message cannot span multiple files.

Each .mq file is prefixed with a letter representing the type of messages it is tracking. These prefixes include:

r000000x.mq
Represents express messages that could not be stored in RAM. (Typically express messages are held in RAM, not on disk.)
p000000x.mq
Represents persistent (recoverable) messages.
j000000x.mq
Represents queue journal and computer journal messages.
l000000x.mq
Represents an indexing bitmap for interpreting the journal (j000000x.mq) and recoverable (r000000x.mq) message files.

The QMLog file is a history file of all message queue processing. When the log is full, the oldest data is overwritten as new entries are made.

State files are used to temporarily store the information that goes into the QMLog file. The state of receiving ordered messages and all active transactions are periodically saved to the following files.

MQInSeqs.lg1
MQInSeqs.lg2
MQTrans.lg1
MQTrans.lg2

Information is sent to each set of files (xx.lg1 and xx.lg2) in an alternating pattern to ensure that one file will persist if the other is damage when writing to the QMLog file.

Files in the MSMQ\Storage\Lqs Folder

The files in this folder are text files that describe the properties of the local public and private queues. They are formatted as .ini files.

The names of private queue registration files are formatted:

nnnnnnnn.hhhhhhhh

Where nnnnnnnn is the 8-byte queue number of the private queue, and the hhhhhhhh extension is a hash of the pathname of the queue. The queue number is used when manually generating the format name of the private queue.

The names of the local public queue registration files are formatted as follows:

aaaaaaaabbbbccccddddeeeeeeeeeeee.hhhhhhhh

Here, aaaaaaaabbbbccccddddeeeeeeeeeeee is the queue identifier (queue GUID) of the queue, and the hhhhhhhh extension is a hash of the pathname of the queue.


Programming for Location Independence

This topic describes how applications can locate and use location-independent mobile queues.

The term "mobile queue" is used to indicate a destination, not a specific queue. A specific mobile queue can be any public queue that is using a specific location independent queue property, or set of properties, to identify itself.

For example, say you need to send messages to an account that can be in several different locations. By using a mobile queue for the account, the sending application can send messages to the account, regardless of which queue is currently being used as the destination.

Note Message Queuing does not allow the queue itself to be moved. A queue cannot be moved from one computer to another because the identifier (GUID) of the queue cannot be altered. Message Queuing generates the queue identifier when the queue is created and adds information about the computer where the queue resides. This information cannot be changed.

To use mobile queues, the application must be able to identify the correct queue to used by one or more location independent queue properties. For example, a combination of queue type and queue label can be used to uniquely identify a queue without reference to the location of the current queue being used.

Single Mobile Queues

If only one mobile queue is required, a queue's type GUID property can be used, instead of its instance property, to uniquely identify the queue. To give the appearance of moving the queue, delete the old queue and create a new destination queue using the same queue type GUID. The sending application will then always search for the queue type, finding the correct queue regardless of where it is located.

In this case, it is the application's responsibility to make sure that only one queue with the specific queue type exists at any time. For example, the sending application can monitor for the error MQ_ERROR_QUEUE_DELETED or negative acknowledgment messages to trigger a new lookup when sending messages.

Multiple Mobile Queues

If several mobile queues are required, a queue's type GUID property can be used to identify a group of mobile queues, and its label property can then be used to identify a specific queue in the group. In this case, a query (based on the queue type) can be run to locate all the mobile queues of a specific type. The application can then use the label to select a specific queue from among the query results.

To give the appearance of moving the queue, each time a new destination queue is created it is given the same queue type and label. Because the sending application always searches for this queue type and label, it finds the correct queue regardless of where it is located.

In this case, it is the application's responsibility to make sure that only one queue with the specific queue type and label exists at any time.


Topic Not Found

No matching topic was found. Some possible reasons and remedies are as follows:

  • The file (.chm) that contains the destination topic is not in the expected location.

    Remedy: Rerun the MSDN Library Setup.

  • The file (.chm) that contains the current topic or destination topic is out-of-date and the link is no longer valid.

    Remedy: Install the latest version of the MSDN Library.

  • The MSDN Library CD is not in the CD-ROM drive.

    Remedy: Insert the MSDN Library CD into the CD-ROM drive.