C-C++ Code Example: Reading Messages in the Computer Journal

 

Applies To: Windows 10, Windows 7, Windows 8, Windows 8.1, Windows Server 2008, Windows Server 2008 R2, Windows Server 2012, Windows Server 2012 R2, Windows Server Technical Preview, Windows Vista

This example provides an application-defined function that synchronously reads all the messages in the computer journal of the computer specified, retrieving the PROPID_M_LABEL property and displaying the label of each message in the computer journal.

This example receives the computer name and generates the machine format name needed to open the computer journal for reading messages from the computer GUID obtained by retrieving the PROPID_QM_MACHINE_ID property. This property cannot be retrieved if there is no connection to the directory service. This restriction applies to dependent clients, independent clients that are working offline, and Message Queuing routing servers.

For more information on machine format names, see Machine and Connector Format Names.

In MSMQ 2.0 and later, this function can be modified to generate the direct format name of the computer journal instead of retrieving its machine format name.

To read messages in the computer journal

  1. Define an MQQMPROPS structure.

  2. Specify PROPID_QM_MACHINE_ID as the property that you want to retrieve.

  3. Initialize the MQQMPROPS structure.

  4. Call MQGetMachineProperties to retrieve the computer GUID.

  5. Generate the format name of the computer journal.

    In MSMQ 2.0 and later, the direct format name of the computer journal can be generated instead of retrieving the machine format name. Then, add code to perform the following replace the preceding steps:

    You must concatenate "DIRECT=OS:", wszComputerName, "\" , and "SYSTEM$;JOURNAL" into the wszFormatName variable.

    wszFormatName = "DIRECT=OS:" + wszComputerName + "\" + "SYSTEM$;JOURNAL"

    You should return FALSE if the format name is too long for the buffer.

  6. Define an MQMSGPROPS structure.

  7. Specify the message label and its length as the message properties that you want to retrieve.

  8. Initialize the MQMSGPROPS structure.

  9. Call MQOpenQueue to open the computer journal with receive access.

  10. Call MQReceiveMessage and synchronously read all the messages in the computer journal.

  11. Call MQCloseQueue to close the computer journal and free resources.

Code Example

The following code example can be run on all versions of Message Queuing.

HRESULT ReadCompJournal(  
                        LPCWSTR wszComputerName  
                        )  
{  
  
  // Validate the input string.  
  if (wszComputerName == NULL)  
  {  
    return MQ_ERROR_INVALID_PARAMETER;  
  }  
  
  // Define the required constants, variables, and structures.  
  const int NUMBEROFPROPERTIES = 2;              // Number of properties  
  DWORD cPropId = 0;                             // Property counter  
  HANDLE hQueue = NULL;                          // Queue handle  
  HRESULT hr = MQ_OK;  
  
  //Define an MQQMPROPS structure.  
  MQQMPROPS qmprops;  
  QMPROPID aQMPropId[NUMBEROFPROPERTIES];  
  PROPVARIANT aQMPropVar[NUMBEROFPROPERTIES];  
  HRESULT aQMStatus[NUMBEROFPROPERTIES];  
  
  // Create a buffer for the computer GUID and    
  // specify PROPID_QM_MACHINE_ID as a property to be retrieved.  
  CLSID guidMachineID;                            // Computer GUID buffer  
  aQMPropId[cPropId] = PROPID_QM_MACHINE_ID;      // Property ID  
  aQMPropVar[cPropId].vt = VT_CLSID;              // Type indicator  
  aQMPropVar[cPropId].puuid = &guidMachineID;  
  cPropId++;  
  
  // Initialize the MQQMPROPS 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 MQGetMachineProperties to retrieve the  
  // computer identifier (GUID).  
  hr = MQGetMachineProperties(  
                              wszComputerName,   // Machine name  
                              NULL,              // Pointer to GUID (not used here)  
                              &qmprops           // Pointer to properties structure  
                              );  
  
  if (FAILED(hr))  
  {  
    wprintf(L"An error occurred during the call to MQGetMachineProperties. Error: 0x%x\n", hr);  
    return hr;  
  }  
  
  // Construct the format name of the computer journal. The returned   
  // computer GUID is translated into a string and then combined   
  // with the MACHINE and JOURNAL keywords.  
  UCHAR *pszUuid = NULL;                        // Computer GUID string  
  CHAR szFormatName[54] = {0};                  // Format name buffer  
  WCHAR wszFormatName[54] = {0};                // Wide-character format name buffer  
  
  if (UuidToString(&guidMachineID, &pszUuid) != RPC_S_OK)  
  {  
    wprintf(L"An error occurred during the call to UuidToString.\n");  
    return E_FAIL;  
  }  
  else  
  {  
    // Combine the computer ID with the MACHINE and JOURNAL keywords.  
    // ************************************  
    // You must concatenate "MACHINE=", pszUuid, and ";JOURNAL" into    
    // the szFormatName buffer.  
    // szFormatName = "MACHINE=" + pszUuid + ";JOURNAL"  
 // If the format name is too long for the buffer, return FALSE.  
    // ************************************  
  
    // Convert the format name string to a wide-character string.  
    mbstowcs(  
             wszFormatName,  
             szFormatName,  
             sizeof(szFormatName)  
             );  
    RpcStringFree(&pszUuid);  
  }  
  
  //Define an MQMSGPROPS structure.  
  MQMSGPROPS msgprops;  
  MSGPROPID aMsgPropId[NUMBEROFPROPERTIES];  
  PROPVARIANT aMsgPropVar[NUMBEROFPROPERTIES];  
  HRESULT aMsgStatus[NUMBEROFPROPERTIES];  
  cPropId = 0;  
  
  // Specify the message label and its length as message properties to be retrieved.  
  WCHAR wszLabelBuffer[MQ_MAX_MSG_LABEL_LEN];         // Message label buffer  
  aMsgPropId[cPropId] = PROPID_M_LABEL_LEN;           // Property ID  
  aMsgPropVar[cPropId].vt = VT_UI4;                   // Type indicator  
  aMsgPropVar[cPropId].ulVal = MQ_MAX_MSG_LABEL_LEN;  // 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  
  
  // Open the computer journal to read messages.  
  hr = MQOpenQueue(  
                   wszFormatName,                    // Format name of the computer journal  
                   MQ_RECEIVE_ACCESS,                // Access mode  
                   MQ_DENY_RECEIVE_SHARE,            // Share mode  
                   &hQueue                           // OUT: Queue handle  
                   );  
  
  if (FAILED(hr))  
  {  
    return hr;  
  }  
  
  // Read all the messages in the computer journal.  
  for ( ; ; )  
  {  
    hr = MQReceiveMessage(  
                          hQueue,                   // Queue handle  
                          0,                        // Maximum time (msec)  
                          MQ_ACTION_RECEIVE,        // Receive action  
                          &msgprops,                // Message property structure  
                          NULL,                     // No OVERLAPPED structure  
                          NULL,                     // No callback function  
                          NULL,                     // Cursor handle  
                          MQ_NO_TRANSACTION         // Not in a transaction  
                          );  
    if (FAILED(hr))  
    {  
      break;  
    }  
  
    if (msgProps.aPropVar[0].ulVal)                // Label returned  
    {  
      wprintf(L"A message was read from the computer journal. Label: %s\n", aMsgPropVar[1].pwszVal);  
    }  
    else  
    {  
      wprintf(L"A message was read from the computer journal.\n");  
    }  
  }  
  
  // Call MQCloseQueue to close the queue.  
  hr = MQCloseQueue(hQueue);  
  
  return hr;  
}