2025-11-28 00:35:46 +09:00

944 lines
24 KiB
C++

// --------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// --------------------------------------------------------------------
//
// Includes
//
#include <stdio.h>
#include <windows.h>
//
// Unique include file for ActiveX MSMQ applications
//
#include <mqoai.h>
//
// Various defines
//
#define MAX_VAR 20
#define MAX_BUFFER 500
//
// GUID created with the tool "GUIDGEN"
//
static WCHAR strGuidMQTestType[] =
L"{c30e0960-a2c0-11cf-9785-00608cb3e80c}";
//
// Prototypes
//
void PrintError(char *s, HRESULT hr);
HRESULT Syntax();
char mbsMachineName[MAX_COMPUTERNAME_LENGTH + 1];
// Some useful macros
#define RELEASE(punk) if (punk) { (punk)->Release(); (punk) = NULL; }
#define ADDREF(punk) ((punk) ? (punk)->AddRef() : 0)
#define PRINTERROR(s, hr) { PrintError(s, hr); goto Cleanup; }
//-----------------------------------------------------
//
// Check whether the local computer is enabled to
// access the directory service (DS-enabled).
//
//-----------------------------------------------------
short DetectDsConnection(void)
{
IMSMQApplication2 *pqapp = NULL;
short fDsConnection;
HRESULT hresult;
hresult = CoCreateInstance(
CLSID_MSMQApplication,
NULL, // punkOuter
CLSCTX_SERVER,
IID_IMSMQApplication2,
(LPVOID *)&pqapp);
if (FAILED(hresult))
{
printf("The attempt to create an MSMQApplication object failed (0x%X). Exiting...\n", hresult);
RELEASE(pqapp);
exit(1);
}
pqapp->get_IsDsEnabled(&fDsConnection);
RELEASE(pqapp);
return fDsConnection;
}
//-----------------------------------------------------
//
// Allow a DS-enabled client to connect to a
// DS-disabled one.
//
//-----------------------------------------------------
bool SetConnectionMode(void)
{
char cDirectMode;
//
// If the local computer is in a domain and not in workgroup mode,
// we have two cases:
// 1. Other side is a computer in a domain.
// 2. Other side is a computer working in workgroup mode.
//
if(DetectDsConnection() != 0)
{
printf("Do you want to connect to a DS-disabled computer (Y or N) ? ");
int iRes = scanf_s("%c", &cDirectMode);
if (iRes == 0 || iRes == EOF)
{
printf("\nInvalid input was entered.\n");
exit(1);
}
switch(tolower(cDirectMode))
{
case 'y':
return true;
case 'n':
return false;
default:
printf("Bye.\n");
exit(1);
}
}
return true; // Local computer is DS-disabled.
}
//--------------------------------------------------------
//
// Receiver Mode
// -------------
// The receiver side does the following:
// 1. Creates a local queue of type "guidMQTestType".
// The queue is either public or private, depending
// on the connection that we want to establish.
// 2. Opens the queue.
// 3. In a loop,
// receives messages and
// prints the message body and message label.
// 4. Closes the handle to the queue.
// 5. Deletes the queue from the directory service.
//
//--------------------------------------------------------
HRESULT Receiver(bool fDirectMode)
{
IMSMQMessage *pmessageReceive = NULL;
IMSMQQueue *pqReceive = NULL;
IMSMQQueueInfo *pqinfo = NULL;
BSTR bstrPathName = NULL;
BSTR bstrServiceType = NULL;
BSTR bstrLabel = NULL;
BSTR bstrMsgLabel = NULL;
VARIANT varIsTransactional, varIsWorldReadable, varBody, varBody2, varWantDestQueue, varWantBody, varReceiveTimeout;
WCHAR wcsPathName[MAX_COMPUTERNAME_LENGTH +100];
BOOL fQuit = FALSE;
HRESULT hresult = NOERROR;
printf("\nReceiver Mode on Machine: %s\n\n", mbsMachineName);
//
// Create an MSMQQueueInfo object.
//
hresult = CoCreateInstance(
CLSID_MSMQQueueInfo,
NULL, // punkOuter
CLSCTX_SERVER,
IID_IMSMQQueueInfo,
(LPVOID *)&pqinfo);
if (FAILED(hresult)) {
PRINTERROR("The queue cannot be created", hresult);
}
//
// Prepare properties for creating a queue on the local computer.
//
// Set the path name.
if(fDirectMode) // Private queue path name
{
if(_snwprintf_s(wcsPathName, sizeof(wcsPathName)/sizeof(wcsPathName[0]), (sizeof(wcsPathName)/sizeof(wcsPathName[0]))-1,
L"%S\\private$\\MSMQTest", mbsMachineName) < 0)
{
// overflow
PRINTERROR("Path name creation failed", hresult);
}
else
{
wcsPathName[(sizeof(wcsPathName)/sizeof(wcsPathName[0]))-1] = L'\0';
}
}
else // Public queue path name
{
if(_snwprintf_s(wcsPathName, sizeof(wcsPathName)/sizeof(wcsPathName[0]), (sizeof(wcsPathName)/sizeof(wcsPathName[0]))-1,
L"%S\\MSMQTest", mbsMachineName) < 0)
{
// Overflow occurred.
PRINTERROR("Path name creation failed", hresult);
}
else
{
wcsPathName[(sizeof(wcsPathName)/sizeof(wcsPathName[0]))-1] = L'\0';
}
}
bstrPathName = SysAllocString(wcsPathName);
if (bstrPathName == NULL) {
PRINTERROR("OOM: pathname", E_OUTOFMEMORY);
}
pqinfo->put_PathName(bstrPathName);
//
// Set the type of the queue.
// (This property will be used to locate all the queues of this type.)
//
bstrServiceType = SysAllocString(strGuidMQTestType);
if (bstrServiceType == NULL) {
PRINTERROR("OOM: ServiceType", E_OUTOFMEMORY);
}
pqinfo->put_ServiceTypeGuid(bstrServiceType);
//
// Add a descriptive label to the queue.
// (This property is useful for administration through the MSMQ admin tools.)
//
bstrLabel =
SysAllocString(L"Sample ActiveX application of MSMQ SDK");
if (bstrLabel == NULL) {
PRINTERROR("OOM: label ", E_OUTOFMEMORY);
}
pqinfo->put_Label(bstrLabel);
//
// Specify whether the queue is 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);
if (FAILED(hresult)) {
//
// The API failed, but not because the queue exists.
//
if (hresult != MQ_ERROR_QUEUE_EXISTS)
PRINTERROR("The queue cannot be created", hresult);
}
//
// Open the queue with receive access.
//
hresult = pqinfo->Open(MQ_RECEIVE_ACCESS,
MQ_DENY_NONE,
&pqReceive);
//
// Things are a little bit tricky. MQCreateQueue succeeded, but in the
// case of a public queue, this does not mean that MQOpenQueue
// will succeed, because replication delays are possible. The queue is
// registered in the DS, but it might take a replication interval
// until the replica reaches the server that I am connected to.
// To overcome this, open the queue in a loop.
//
// In this specific case, this can happen only if this program
// is run on an MSMQ 1.0 backup server controller (BSC) or on
// a client connected to a BSC.
// To be totally on the safe side, we should have put some code
// to exit the loop after a few retries, but this is just a sample.
//
while (hresult == MQ_ERROR_QUEUE_NOT_FOUND) {
printf(".");
// Wait a bit.
Sleep(500);
// Retry.
hresult = pqinfo->Open(MQ_RECEIVE_ACCESS,
MQ_DENY_NONE,
&pqReceive);
}
if (FAILED(hresult)) {
PRINTERROR("The queue cannot be opened", hresult);
}
//
// Main receiver loop
//
printf("\nWaiting for messages...\n");
while (!fQuit) {
//
// Receive the message.
//
VariantInit(&varWantDestQueue);
VariantInit(&varWantBody);
VariantInit(&varReceiveTimeout);
varWantDestQueue.vt = VT_BOOL;
varWantDestQueue.boolVal = TRUE; // Yes, we want the destination queue.
varWantBody.vt = VT_BOOL;
varWantBody.boolVal = TRUE; // Yes, we want the message body.
varReceiveTimeout.vt = VT_I4;
varReceiveTimeout.lVal = INFINITE; // Infinite time-out
hresult = pqReceive->Receive(
NULL,
&varWantDestQueue,
&varWantBody,
&varReceiveTimeout,
&pmessageReceive);
if (FAILED(hresult)) {
PRINTERROR("Receive failed", hresult);
}
//
// Display the received message.
//
pmessageReceive->get_Label(&bstrMsgLabel);
VariantInit(&varBody);
VariantInit(&varBody2);
hresult = pmessageReceive->get_Body(&varBody);
if (FAILED(hresult)) {
PRINTERROR("The message body cannot be retrieved", hresult);
}
hresult = VariantChangeType(&varBody2,
&varBody,
0,
VT_BSTR);
if (FAILED(hresult)) {
PRINTERROR("The message body cannot be converted to a string", hresult);
}
printf("%S : %s\n", bstrMsgLabel, (char *)V_BSTR(&varBody2));
//
// Check for a request to end the application.
//
if (_stricmp((char *)V_BSTR(&varBody2), "quit") == 0) {
fQuit = TRUE;
}
VariantClear(&varBody);
VariantClear(&varBody2);
//
// Release the current message.
//
RELEASE(pmessageReceive);
} /* while (!fQuit) */
//
// Cleanup: Close the handle to the queue.
//
pqReceive->Close();
if (FAILED(hresult)) {
PRINTERROR("The queue cannot be closed", hresult);
}
//
// In the concluding stage, we delete the queue from the directory
// service. (We don't need to do this. In case of a public queue,
// leaving it in the DS enables sender applications to send messages
// even if the receiver is not available.)
//
hresult = pqinfo->Delete();
if (FAILED(hresult)) {
PRINTERROR("The queue cannot be deleted", hresult);
}
// Fall through...
Cleanup:
SysFreeString(bstrPathName);
SysFreeString(bstrMsgLabel);
SysFreeString(bstrServiceType);
SysFreeString(bstrLabel);
RELEASE(pmessageReceive);
RELEASE(pqReceive);
RELEASE(pqinfo);
return hresult;
}
//-----------------------------------------------------
//
// Sender Mode
// -----------
// The sender side does the following:
//
// In domain (standard) mode:
// 1. Locates all queues of type "guidMQTestType."
// 2. Opens handles to all the queues.
// 3. In a loop,
// sends messages to all those queues.
// 4. Cleans up handles.
//
// If we work in workgroup (direct) mode:
// 1. Opens a handle to a private queue labeled
// "MSMQTest" on the computer specified.
// 2. Sends messages to that queue.
// 3. Cleans up handles.
//-----------------------------------------------------
//-----------------------------------------------------
//
// Sender in domain (standard) mode
//
//-----------------------------------------------------
HRESULT StandardSender()
{
IMSMQQuery *pquery = NULL;
IMSMQQueueInfo *rgpqinfo[MAX_VAR];
IMSMQQueue *rgpqSend[MAX_VAR];
IMSMQQueueInfo *pqinfo = NULL;
IMSMQQueueInfos *pqinfos = NULL;
IMSMQMessage *pmessage = NULL;
char szBuffer[MAX_BUFFER] = {0};
WCHAR wcsMsgLabel[MQ_MAX_MSG_LABEL_LEN] = {0};
BSTR bstrServiceType = NULL;
BSTR bstrLabel = NULL;
BSTR bstrBody = NULL;
VARIANT varBody;
DWORD i;
DWORD cQueue = 0;
HRESULT hresult = NOERROR;
printf("\nSender mode on the computer %s\n\n", mbsMachineName);
//
// Create query object for lookup.
//
hresult = CoCreateInstance(
CLSID_MSMQQuery,
NULL, // punkOuter
CLSCTX_SERVER,
IID_IMSMQQuery,
(LPVOID *)&pquery);
if (FAILED(hresult)) {
PRINTERROR("A query object cannot be created", hresult);
}
//
// Prepare parameters to locate all queues that
// have the test service type GUID.
//
VARIANT varGuidQueue;
VARIANT varStrLabel;
VARIANT varGuidServiceType;
VARIANT varRelServiceType;
VARIANT varRelLabel;
VARIANT varCreateTime;
VARIANT varModifyTime;
VARIANT varRelCreateTime;
VARIANT varRelModifyTime;
VariantInit(&varGuidQueue);
VariantInit(&varStrLabel);
VariantInit(&varGuidServiceType);
VariantInit(&varRelServiceType);
VariantInit(&varRelLabel);
VariantInit(&varCreateTime);
VariantInit(&varModifyTime);
VariantInit(&varRelCreateTime);
VariantInit(&varRelModifyTime);
//
// We only want to specify the service type GUID, so we
// set the other variant parameters to VT_ERROR to simulate
// "missing," i.e. optional, parameters.
//
V_VT(&varGuidQueue) = VT_ERROR;
V_VT(&varStrLabel) = VT_ERROR;
V_VT(&varRelServiceType) = VT_ERROR;
V_VT(&varRelLabel) = VT_ERROR;
V_VT(&varCreateTime) = VT_ERROR;
V_VT(&varModifyTime) = VT_ERROR;
V_VT(&varRelCreateTime) = VT_ERROR;
V_VT(&varRelModifyTime) = VT_ERROR;
bstrServiceType = SysAllocString(strGuidMQTestType);
if (bstrServiceType == NULL) {
PRINTERROR("OOM: Service Type GUID", E_OUTOFMEMORY);
}
V_VT(&varGuidServiceType) = VT_BSTR;
V_BSTR(&varGuidServiceType) = bstrServiceType;
hresult = pquery->LookupQueue(&varGuidQueue,
&varGuidServiceType,
&varStrLabel,
&varCreateTime,
&varModifyTime,
&varRelServiceType,
&varRelLabel,
&varRelCreateTime,
&varRelModifyTime,
&pqinfos);
if (FAILED(hresult)) {
PRINTERROR("LookupQueue failed", hresult);
}
//
// Reset the queue collection object.
//
hresult = pqinfos->Reset();
if (FAILED(hresult)) {
PRINTERROR("Reset failed", hresult);
}
//
// Open each of the queues found.
//
cQueue = 0;
hresult = pqinfos->Next(&rgpqinfo[cQueue]);
if (FAILED(hresult)) {
PRINTERROR("Next failed", hresult);
}
pqinfo = rgpqinfo[cQueue];
while (pqinfo) {
//
// Open the queue with send access.
//
hresult = pqinfo->Open(
MQ_SEND_ACCESS,
MQ_DENY_NONE,
&rgpqSend[cQueue]);
if (FAILED(hresult)) {
PRINTERROR("Open failed", hresult);
}
cQueue++;
hresult = pqinfos->Next(&rgpqinfo[cQueue]);
if (FAILED(hresult)) {
PRINTERROR("Next failed", hresult);
}
pqinfo = rgpqinfo[cQueue];
}
if (cQueue == 0) {
//
// No queue could be found, so exit.
//
PRINTERROR("No queue is registered", hresult = E_INVALIDARG);
}
printf("\tQueue(s) found: %d\n", cQueue);
printf("\nEnter \"quit\" to exit.\n");
//
// Build the message label property.
//
if(_snwprintf_s(wcsMsgLabel, sizeof(wcsMsgLabel)/sizeof(wcsMsgLabel[0]), (sizeof(wcsMsgLabel)/sizeof(wcsMsgLabel[0]))-1,
L"Message from %S", mbsMachineName) < 0)
{
// overflow
PRINTERROR("Label creation failed", hresult);
}
else
{
wcsMsgLabel[(sizeof(wcsMsgLabel)/sizeof(wcsMsgLabel[0]))-1] = L'\0';
}
bstrLabel = SysAllocString(wcsMsgLabel);
if (bstrLabel == NULL)
PRINTERROR("OOM: label", E_OUTOFMEMORY);
fflush(stdin);
//
// Main sender loop
//
while (1) {
//
// Get a string from the console.
//
printf("Enter a string: ");
if (fgets(szBuffer, MAX_BUFFER - 1, stdin) == NULL)
break;
szBuffer[MAX_BUFFER - 1] = '\0';
//
// Delete the new-line character from the string.
//
if(szBuffer[strlen(szBuffer) - 1] == '\n')
{
szBuffer[strlen(szBuffer) - 1] = '\0';
}
//
// Create a message object.
//
hresult = CoCreateInstance(
CLSID_MSMQMessage,
NULL, // punkOuter
CLSCTX_SERVER,
IID_IMSMQMessage,
(LPVOID *)&pmessage);
//
// Send the message to all the queues.
//
for (i = 0; i < cQueue; i++)
{
hresult = pmessage->put_Label(bstrLabel);
//
// This isn't a "true" Unicode string, of course.
//
bstrBody = SysAllocStringByteLen(szBuffer, strlen(szBuffer) + 1);
if (bstrBody == NULL) {
PRINTERROR("OOM: message body", E_OUTOFMEMORY);
}
VariantInit(&varBody);
V_VT(&varBody) = VT_BSTR;
V_BSTR(&varBody) = bstrBody;
hresult = pmessage->put_Body(varBody);
if (FAILED(hresult)) {
PRINTERROR("put_body failed", hresult);
}
hresult = pmessage->Send(rgpqSend[i], NULL);
if (FAILED(hresult)) {
PRINTERROR("Send failed", hresult);
}
VariantClear(&varBody);
bstrBody = NULL;
}
RELEASE(pmessage);
//
// Check for a request to end the application.
//
if (_stricmp(szBuffer, "quit") == 0)
break;
} /* while (1) */
Cleanup:
//
// Close and release all the queues.
//
for (i = 0; i < cQueue; i++) {
rgpqSend[i]->Close();
rgpqSend[i]->Release();
rgpqinfo[i]->Release();
}
RELEASE(pqinfos);
RELEASE(pquery);
RELEASE(pmessage);
SysFreeString(bstrLabel);
SysFreeString(bstrBody);
SysFreeString(bstrServiceType);
return hresult;
}
//-----------------------------------------------------
//
// Sender in direct (workgroup) mode
//
//-----------------------------------------------------
HRESULT DirectSender(void)
{
IMSMQQueue *rgpqSend = NULL;
IMSMQQueueInfo *pqinfo = NULL;
IMSMQMessage *pmessage = NULL;
char szBuffer[MAX_BUFFER];
WCHAR wcsMsgLabel[MQ_MAX_MSG_LABEL_LEN] = {0};
WCHAR wcsFormat[MAX_BUFFER + 100] = {0};
WCHAR wcsReceiverComputer[MAX_BUFFER] = {0};
BSTR bstrFormat = NULL;
BSTR bstrServiceType = NULL;
BSTR bstrLabel = NULL;
BSTR bstrBody = NULL;
VARIANT varBody;
DWORD cQueue = 0;
HRESULT hresult = NOERROR;
//
// Get the receiver computer name.
//
//
// Flushing stdin to get rid of the new-line character entered earlier.
//
fflush(stdin);
printf("\nEnter receiver computer name: ");
if (fgetws(wcsReceiverComputer, MAX_BUFFER - 1, stdin) == NULL)
return E_INVALIDARG;
if(wcsReceiverComputer[wcslen(wcsReceiverComputer) - 1] == L'\n')
wcsReceiverComputer[wcslen(wcsReceiverComputer) - 1] = L'\0';
if(wcsReceiverComputer[0] == 0)
{
printf("You have entered an incorrect parameter. Exiting...\n");
return E_INVALIDARG;
}
hresult = CoCreateInstance(
CLSID_MSMQQueueInfo,
NULL, // punkOuter
CLSCTX_SERVER,
IID_IMSMQQueueInfo,
(LPVOID *)&pqinfo);
if (FAILED(hresult))
PRINTERROR("The queue cannot be opened", hresult);
if(_snwprintf_s(wcsFormat, sizeof(wcsFormat)/sizeof(wcsFormat[0]), (sizeof(wcsFormat)/sizeof(wcsFormat[0])) - 1,
L"DIRECT=OS:%s\\private$\\MSMQTest", wcsReceiverComputer) < 0)
{
// Overflow occurred.
PRINTERROR("The receiver format name is too long for the buffer specified", hresult);
}
else
{
wcsFormat[(sizeof(wcsFormat)/sizeof(wcsFormat[0])) - 1] = L'\0';
}
bstrFormat = SysAllocString(wcsFormat);
hresult = pqinfo->put_FormatName(bstrFormat);
if (FAILED(hresult))
PRINTERROR("Open failed", hresult);
//
// Open the queue with send access.
//
hresult = pqinfo->Open(
MQ_SEND_ACCESS,
MQ_DENY_NONE,
&rgpqSend);
if (FAILED(hresult))
PRINTERROR("Open failed", hresult);
printf("\nSender mode on the computer %s.\n\n", mbsMachineName);
printf("\nEnter \"quit\" to exit.\n");
//
// Build the message label property.
//
if(_snwprintf_s(wcsMsgLabel, sizeof(wcsMsgLabel)/sizeof(wcsMsgLabel[0]), (sizeof(wcsMsgLabel)/sizeof(wcsMsgLabel[0])) - 1,
L"Message from %S", mbsMachineName) < 0)
{
// Overflow occurred.
PRINTERROR("Label creation failed", hresult);
}
else
{
wcsMsgLabel[(sizeof(wcsMsgLabel)/sizeof(wcsMsgLabel[0])) - 1] = L'\0';
}
bstrLabel = SysAllocString(wcsMsgLabel);
if (bstrLabel == NULL)
PRINTERROR("OOM: label", E_OUTOFMEMORY);
fflush(stdin);
//
// Main sender loop.
//
while (1)
{
//
// Get a string from the console.
//
printf("Enter a string: ");
if (fgets(szBuffer,sizeof(szBuffer) - 1, stdin) == NULL)
break;
if(szBuffer[strlen(szBuffer) - 1] == '\n')
{
szBuffer[strlen(szBuffer) - 1] = '\0';
}
//
// Create a message object.
//
hresult = CoCreateInstance(
CLSID_MSMQMessage,
NULL, // punkOuter
CLSCTX_SERVER,
IID_IMSMQMessage,
(LPVOID *)&pmessage);
//
// Send the message.
//
hresult = pmessage->put_Label(bstrLabel);
bstrBody = SysAllocStringByteLen(szBuffer, strlen(szBuffer) + 1);
if (bstrBody == NULL)
PRINTERROR("OOM: body", E_OUTOFMEMORY);
VariantInit(&varBody);
V_VT(&varBody) = VT_BSTR;
V_BSTR(&varBody) = bstrBody;
hresult = pmessage->put_Body(varBody);
if (FAILED(hresult))
PRINTERROR("put_body failed", hresult);
hresult = pmessage->Send(rgpqSend, NULL);
if (FAILED(hresult))
PRINTERROR("Send failed", hresult);
VariantClear(&varBody);
bstrBody = NULL;
RELEASE(pmessage);
//
// Check for a request to end teh application.
//
if (_stricmp(szBuffer, "quit") == 0)
break;
} /* while (1) */
Cleanup:
if(rgpqSend != NULL)
{
rgpqSend->Close();
rgpqSend->Release();
}
RELEASE(pqinfo);
RELEASE(pmessage);
SysFreeString(bstrFormat);
SysFreeString(bstrLabel);
SysFreeString(bstrBody);
SysFreeString(bstrServiceType);
return hresult;
}
//------------------------------------------------------
//
// Sender function
//
//------------------------------------------------------
HRESULT Sender(int fDirectMode)
{
if(fDirectMode != 0)
return DirectSender();
else
return StandardSender();
}
//-----------------------------------------------------
//
// MAIN
//
//-----------------------------------------------------
int main(int argc, char * * argv)
{
DWORD dwNumChars;
HRESULT hresult = NOERROR;
bool fDirectMode;
if (argc != 2)
return Syntax();
hresult = OleInitialize(NULL);
if (FAILED(hresult))
PRINTERROR("OLE cannot be initialized", hresult);
//
// Retrieve the computer name.
//
dwNumChars = MAX_COMPUTERNAME_LENGTH;
if(!GetComputerNameA(mbsMachineName, &dwNumChars))
{
printf("The computer name cannot be obtained. Exiting...\n");
exit(1);
}
//
// Detect DS connection and working mode.
//
fDirectMode = SetConnectionMode();
if (strcmp(argv[1], "-s") == 0)
hresult = Sender(fDirectMode);
else if (strcmp(argv[1], "-r") == 0)
hresult = Receiver(fDirectMode);
else
hresult = Syntax();
printf("\nOK\n");
// Fall through...
Cleanup:
return (int)hresult;
}
void PrintError(char *s, HRESULT hr)
{
printf("%s (0x%X). Exiting...\n", s, hr);
}
HRESULT Syntax()
{
printf("\n");
printf("Syntax: mqtestoa -s | -r\n");
printf("\t-s: Sender\n");
printf("\t-r: Receiver\n");
return E_INVALIDARG;
}