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
Define an MQQMPROPS structure.
Specify PROPID_QM_MACHINE_ID as the property that you want to retrieve.
Initialize the MQQMPROPS structure.
Call MQGetMachineProperties to retrieve the computer GUID.
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.
Define an MQMSGPROPS structure.
Specify the message label and its length as the message properties that you want to retrieve.
Initialize the MQMSGPROPS structure.
Call MQOpenQueue to open the computer journal with receive access.
Call MQReceiveMessage and synchronously read all the messages in the computer journal.
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;
}