Locating a Public Queue

Public queues can be located by running a query on the queue information registered in Active Directory. 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 MSMQ 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.

    To run a query
  1. Determine the search criteria for the query and what properties you want to retrieve.
  2. Specify the search criteria using MQPROPERTYRESTRICTION and MQRESTRICTION.
    // 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;
        
  3. Specify the properties to retrieve using MQCOLUMNSET.
    MQCOLUMNSET    Column;
    QUEUEPROPID    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;
        
  4. Call MQLocateBegin to start the 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
        );
     
  5. Call MQLocateNext to look at the query results.
    hr = MQLocateNext( 
         hEnum,      // Handle returned by MQLocateBegin.
         &cProps,    // Size of aPropVar array.
         aPropVar    // An array of PROPVARIANT for results.
         );
     
  6. Call MQLocateEnd to close the query.
    hr = MQLocateEnd(hEnum);   // Handle returned by MQLocateBegin.
     

Example

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}};
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;
QUEUEPROPID    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.
/////////////////////////////////////

PROPVARIANT 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 PROPVARIANT 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
    //
}