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

346 lines
10 KiB
C++

//////////////////////////////////////////////////////////////////////////////
// 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.
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//////////////////////////////////////////////////////////////////////////////
#include <windows.h>
#include <stdlib.h>
#include <strsafe.h>
#include <string.h>
#include <stdio.h>
#include <conio.h>
#include <wsdapi.h>
#include "Common.h"
#include "TargetService.h"
#include "Service.h"
//Usages: WSDiscoveryService.exe [/a EndpointReference] [/s scope [...]]
//You may use one of /a or /s, or both (in that order).
//
//By default, both the default scope matching rule (RFC2396) and the custom
//scope matching rule (see CTargetService::MatchScopes) are attached. But unless
//there are scopes specified for use with the target service using the /s flag,
//the attached scope matching rules will have no effect.
//
// If an EndpointReference is provided, it must begin with one of http://, https://,
// uri:, urn:uuid: or uuid:.
//
//To start a default target service with a randomly generated
//EndpointReference in the form of a urn:uuid (as defined in Section 2.6 of the
//WS-Discovery spec):
//WSDiscoveryService.exe
//
//To have 2 scopes attached to the target service:
//WSDiscoveryService.exe /s http://www.contoso.com/wsd/scope1/Printer3
//http://www.contoso.com/wsd/scope1/NoticeBoard
//
//To have an Endpoint Reference attached to the target service:
//WSDiscoveryService.exe /a urn:uuid:91022ed0-7d3d-11de-8a39-0800200c9a66
//
//To do both:
//WSDiscoveryService.exe /a urn:uuid:91022ed0-7d3d-11de-8a39-0800200c9a66 /s
//http://www.contoso.com/wsd/scope1/Printer3
//http://www.contoso.com/wsd/scope1/NoticeBoard
int _cdecl wmain
( int argc
, _In_reads_( argc ) LPWSTR *argv
)
{
LPWSTR epr = NULL;
LPCWSTR eprAfterInit = NULL; // do not deallocate
WSD_URI_LIST *scopesList = NULL;
CTargetService *service = NULL;
HRESULT hr = S_OK;
char command = '\0';
wprintf( L"----------------------------------------\r\n" );
wprintf( L"WS-Discovery SDK Sample Target Service\r\n" );
wprintf( L"Copyright (c) Microsoft Corporation. All rights reserved.\r\n" );
wprintf( L"----------------------------------------\r\n" );
hr = ParseArguments( argc, argv, &epr, &scopesList );
if ( S_OK != hr )
{
PrintErrorMessage( L"Failed to parse arguments", hr );
}
if ( S_OK == hr )
{
wprintf( L"Creating and initializing the target service...\r\n" );
hr = CreateTargetService( epr, scopesList, &service );
if ( S_OK != hr )
{
PrintErrorMessage( L"Failed to create or initialize the target service", hr );
}
}
if ( S_OK == hr )
{
wprintf( L"Obtaining EndpointReference: " );
hr = service->GetEndpointReference( &eprAfterInit );
if ( S_OK == hr )
{
wprintf( L"%s\r\n", eprAfterInit );
}
else
{
PrintErrorMessage( L"Failed to obtain EPR", hr );
}
}
if ( S_OK == hr )
{
wprintf( L"Sending a Hello Message...\r\n" );
hr = service->SendHelloMessage();
if ( S_OK != hr )
{
wprintf( L"Failed to Send a Hello message...\r\n" );
}
}
// listen for commands
while ( 'q' != command && 'Q' != command && S_OK == hr )
{
wprintf( L"\r\n" );
wprintf( L"Press 'h' to send a Hello, 'b' to send a Bye, 'q' to terminate: " );
command = (char)_getch();
wprintf( L"\r\n" );
if ( 'h' == command || 'H' == command )
{
wprintf( L"Sending a Hello Message...\r\n" );
hr = service->SendHelloMessage();
if ( S_OK != hr )
{
wprintf( L"Failed to Send a Hello message...\r\n" );
}
}
else if ( 'b' == command || 'B' == command )
{
wprintf( L"Sending a Bye Message...\r\n" );
hr = service->SendByeMessage();
if ( S_OK != hr )
{
wprintf( L"Failed to Send a Bye message...\r\n" );
}
}
else if ( 'q' != command && 'Q' != command )
{
wprintf( L"Command not recognized..." );
}
}
if ( S_OK == hr )
{
wprintf( L"Terminating the target service...\r\n" );
hr = service->Terminate();
if ( S_OK != hr )
{
PrintErrorMessage( L"Failed to terminate the target service", hr );
}
}
eprAfterInit = NULL; // do not deallocate
if ( NULL != epr )
{
delete[] epr;
epr = NULL;
}
if ( NULL != scopesList )
{
WSDFreeLinkedMemory( scopesList );
scopesList = NULL;
}
if ( NULL != service )
{
service->Release();
service = NULL;
}
if ( S_OK != hr )
{
// display usage if it fails for any reason
wprintf( L"\r\n" );
DisplayUsages();
wprintf( L"\r\n" );
}
wprintf( L"Target service application has ended. Press any key to exit..." );
(void)_getch();
return 0;
}
// Parses the command line arguments according to rules
// specified in the DisplayUsages() function.
// The caller should pass in argc and argv as they were
// being passed into the wmain() function.
// The caller should call WSDFreeLinkedMemory on the
// returned scopesList, and delete[] on epr
// when they are no longer needed.
_Success_( return == S_OK )
HRESULT ParseArguments
( _In_ int argc
, _In_reads_( argc ) LPWSTR *argv
, _Outptr_result_maybenull_ LPWSTR *epr
, _Outptr_result_maybenull_ WSD_URI_LIST **scopesList
)
{
HRESULT hr = S_OK;
LPWSTR tempEpr = NULL;
WSD_URI_LIST *tempScopesList = NULL;
if ( 1 > argc || NULL == argv )
{
// argc must be at least 1
// the minimum it contains is the executable name
hr = E_INVALIDARG;
}
else if ( NULL == epr || NULL == scopesList )
{
hr = E_POINTER;
}
else
{
*epr = NULL;
*scopesList = NULL;
}
if ( S_OK == hr )
{
// expecting arguments to be of the following format:
// argv[0] = executable name - ignored
//
// argv[1] = if specified, one of /a or /s
// if /a, then argv[2] = endpoint reference address
// if /s, then argv[2] and above are scopes
//
// if argv[1] was /a, then
// argv[3] = if specified, must be /s
// argv[4] and above are scopes
//
// argc must be at least 3
if ( 1 == argc )
{
// Do nothing.
// A logical address will be generated and
// no scopes attached.
}
else if ( 2 == argc )
{
// Not enough parameters.
hr = E_INVALIDARG;
}
else if ( 0 == wcscmp( argv[1], L"/a" ) )
{
// argv[0] [1] [2] [3] [4]...
// WSDiscoveryService.exe /a some_epr /s some_scope ...
// argc must be either 3 or at least 5 - it cannot be 4
if ( 4 == argc )
{
hr = E_INVALIDARG;
}
else if ( 5 <= argc && 0 != wcscmp( argv[3], L"/s" ) )
{
// if argv[3] is specified, it has to be /s
hr = E_INVALIDARG;
}
if ( S_OK == hr )
{
// copy the EndpointReference
hr = DeepCopyString( argv[2], &tempEpr );
}
if ( S_OK == hr && 5 <= argc )
{
// extract scopes from argv[4] and above
#pragma prefast( suppress: 6385, "Number of strings are previously checked." )
hr = ParseScopes( argc, argv, 4, &tempScopesList );
}
}
else if ( 0 == wcscmp( argv[1], L"/s" ) )
{
// extract scopes from argv[2]
hr = ParseScopes( argc, argv, 2, &tempScopesList );
}
else
{
// unknown arguments specified
hr = E_INVALIDARG;
}
}
if ( S_OK == hr )
{
// outside pointer now owns temp var
*epr = tempEpr;
tempEpr = NULL;
*scopesList = tempScopesList;
tempScopesList = NULL;
}
if ( NULL != tempEpr )
{
delete[] tempEpr;
tempEpr = NULL;
}
if ( NULL != tempScopesList )
{
WSDFreeLinkedMemory( tempScopesList );
tempScopesList = NULL;
}
return hr;
};
void DisplayUsages()
{
wprintf( L"Usages: WSDiscoveryService.exe [/a EndpointReference] [/s scope [...]]\r\n" );
wprintf( L"You may use one of /a or /s, or both (in that order).\r\n" );
wprintf( L"\r\n" );
wprintf( L"By default, both the default scope matching rule (RFC2396) and the custom\r\n" );
wprintf( L"scope matching rule (see CTargetService::MatchScopes) are attached. But unless\r\n" );
wprintf( L"there are scopes specified for use with the target service using the /s flag,\r\n" );
wprintf( L"the attached scope matching rules will have no effect.\r\n" );
wprintf( L"\r\n" );
wprintf( L"If an EndpointReference is provided, it must begin with one of http://, https://,\r\n" );
wprintf( L"uri:, urn:uuid: or uuid:.\r\n" );
wprintf( L"\r\n" );
wprintf( L"To start a default target service with a randomly generated\r\n" );
wprintf( L"EndpointReference in the form of a urn:uuid (as defined in Section 2.6 of the\r\n" );
wprintf( L"WS-Discovery spec):\r\n" );
wprintf( L"WSDiscoveryService.exe\r\n" );
wprintf( L"\r\n" );
wprintf( L"To have 2 scopes attached to the target service:\r\n" );
wprintf( L"WSDiscoveryService.exe /s http://www.contoso.com/wsd/scope1/Printer3\r\n" );
wprintf( L"http://www.contoso.com/wsd/scope1/NoticeBoard\r\n" );
wprintf( L"\r\n" );
wprintf( L"To have an Endpoint Reference attached to the target service:\r\n" );
wprintf( L"WSDiscoveryService.exe /a urn:uuid:91022ed0-7d3d-11de-8a39-0800200c9a66\r\n" );
wprintf( L"\r\n" );
wprintf( L"To do both:\r\n" );
wprintf( L"WSDiscoveryService.exe /a urn:uuid:91022ed0-7d3d-11de-8a39-0800200c9a66 /s\r\n" );
wprintf( L"http://www.contoso.com/wsd/scope1/Printer3\r\n" );
wprintf( L"http://www.contoso.com/wsd/scope1/NoticeBoard\r\n" );
}